Skip to content

Commit

Permalink
Move all sphinx-using code to tdoc.common.ext.
Browse files Browse the repository at this point in the history
  • Loading branch information
rblank committed Nov 28, 2024
1 parent b053925 commit 054e824
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 147 deletions.
134 changes: 1 addition & 133 deletions tdoc/common/__init__.py
Original file line number Diff line number Diff line change
@@ -1,137 +1,5 @@
# Copyright 2024 Remy Blank <[email protected]>
# SPDX-License-Identifier: MIT

import json
import pathlib

from sphinx import config, locale
from sphinx.util import fileutil, logging

__project__ = 't-doc-common'
__version__ = '0.22'

_log = logging.getLogger(__name__)
_messages = 'tdoc'
_ = locale.get_translation(_messages)

_common = pathlib.Path(__file__).absolute().parent

_license_urls = {
'CC0-1.0': 'https://creativecommons.org/publicdomain/zero/1.0/',
'CC-BY-4.0': 'https://creativecommons.org/licenses/by/4.0/',
'CC-BY-SA-4.0': 'https://creativecommons.org/licenses/by-sa/4.0/',
'CC-BY-NC-4.0': 'https://creativecommons.org/licenses/by-nc/4.0/',
'CC-BY-NC-SA-4.0': 'https://creativecommons.org/licenses/by-nc-sa/4.0/',
'CC-BY-ND-4.0': 'https://creativecommons.org/licenses/by-nd/4.0/',
'MIT': 'https://opensource.org/license/mit',
}


def report_exceptions(fn):
def wrapper(self, /, *args, **kwargs):
try:
return fn(self, *args, **kwargs)
except Exception as e:
return [self.state.document.reporter.error(e, line=self.lineno)]
return wrapper


def format_attrs(translator, /, **kwargs):
return ' '.join(f'{k.replace('_', '-')}="{translator.attval(v)}"'
for k, v in sorted(kwargs.items()) if v is not None)


def format_data_attrs(translator, /, **kwargs):
return ' '.join(f'data-tdoc-{k.replace('_', '-')}="{translator.attval(v)}"'
for k, v in sorted(kwargs.items()) if v is not None)


def build_tag(app):
for tag in app.tags:
if tag.startswith('tdoc_build_'):
return tag


def setup(app):
app.add_event('tdoc-html-page-config')

app.add_config_value('license', '', 'html')
app.add_config_value(
'license_url', lambda c: _license_urls.get(c.license, ''), 'html', str)
app.add_config_value('tdoc_enable_sab', 'no', 'html',
config.ENUM('no', 'cross-origin-isolation', 'sabayon'))

app.add_html_theme('t-doc', str(_common))
app.add_message_catalog(_messages, str(_common / 'locale'))

app.connect('config-inited', on_config_inited)
app.connect('builder-inited', on_builder_inited)
app.connect('html-page-context', on_html_page_context)
if build_tag(app):
app.connect('html-page-context', add_reload_js)
app.connect('write-started', write_static_files)

return {
'version': __version__,
'parallel_read_safe': True,
'parallel_write_safe': True,
}


def on_config_inited(app, config):
cv = config.values['html_title']
super(cv.__class__, cv).__setattr__('default', lambda c: c.project)
config.templates_path.append(str(_common / 'templates'))

# Override defaults in html_theme_options.
opts = config.html_theme_options
opts.setdefault('use_sidenotes', True)
opts.setdefault('path_to_docs', 'docs')
if opts.get('repository_url'):
opts.setdefault('use_repository_button', True)
opts.setdefault('use_source_button', True)

# Set the global HTML context.
context = config.html_context
context['tdoc_enable_sab'] = app.config.tdoc_enable_sab
tag = build_tag(app)
context['tdoc_build'] = tag if tag is not None else ''


def on_builder_inited(app):
# Add our own static paths.
app.config.html_static_path.append(str(_common / 'static'))
app.config.html_static_path.append(str(_common / 'static.gen'))

# Add a default static path.
if '_static' not in app.config.html_static_path:
app.config.html_static_path.append('_static')


def on_html_page_context(app, page, template, context, doctree):
license = app.config.license
if license: context['license'] = license
license_url = app.config.license_url
if license_url: context['license_url'] = license_url

# Set up early and on-load JavaScript.
config = {'htmlData': {}}
app.emit('tdoc-html-page-config', page, config)
config = json.dumps(config, separators=(',', ':'))
app.add_js_file(None, priority=0, body=f'const tdocConfig = {config};')
app.add_js_file('tdoc/early.js', priority=1,
scope=context['pathto']('', resource=True))
app.add_js_file('tdoc/load.js', type='module')


def add_reload_js(app, page, template, context, doctree):
app.add_js_file('tdoc/reload.js', type='module')


def write_static_files(app, builder):
if builder.format != 'html': return

# The file must be at the root of the website, to avoid limiting the scope
# of the service worker to _static.
fileutil.copy_asset_file(_common / 'scripts' / 'tdoc-worker.js',
builder.outdir, force=True)
__version__ = '0.23.dev1'
13 changes: 6 additions & 7 deletions tdoc/common/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
import time
from urllib import parse

from .. import common
from . import util
from . import __project__, __version__, util

# TODO: Implement incremental builds, by copying previous build output

Expand Down Expand Up @@ -138,7 +137,7 @@ class Handler(HandlerBase):


def cmd_version(cfg):
cfg.stdout.write(f"{common.__project__}-{common.__version__}\n")
cfg.stdout.write(f"{__project__}-{__version__}\n")


def sphinx_build(cfg, target, *, build, tags=(), **kwargs):
Expand Down Expand Up @@ -276,14 +275,14 @@ def print_serving(self):

def check_upgrade(self):
try:
project = common.__project__
upgrades, editable = pip_check_upgrades(self.cfg, project)
if project not in upgrades: return
upgrades, editable = pip_check_upgrades(self.cfg, __project__)
if __project__ not in upgrades: return
msg = self.cfg.ansi(
"@{LYELLOW}A t-doc upgrade is available:@{NORM} "
"%s @{CYAN}%s@{NORM} => @{CYAN}%s@{NORM}\n"
"See <@{LBLUE}https://t-doc.org/common/%s#upgrade@{NORM}>\n"
% (project, metadata.version(project), upgrades[project],
% (__project__, metadata.version(__project__),
upgrades[__project__],
'development' if editable else 'install'))
with self.lock:
self.upgrade_msg = msg
Expand Down
2 changes: 1 addition & 1 deletion tdoc/common/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
'sphinx.ext.todo',
'sphinx_copybutton',
'sphinx_design',
'tdoc.common',
'tdoc.common.ext',
'tdoc.common.ext.defaults',
'tdoc.common.ext.exec',
'tdoc.common.ext.iframe',
Expand Down
136 changes: 136 additions & 0 deletions tdoc/common/ext/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Copyright 2024 Remy Blank <[email protected]>
# SPDX-License-Identifier: MIT

import json
import pathlib

from sphinx import config, locale
from sphinx.util import fileutil, logging

from .. import __version__

_log = logging.getLogger(__name__)
_messages = 'tdoc'
_ = locale.get_translation(_messages)

_base = pathlib.Path(__file__).absolute().parent.parent

_license_urls = {
'CC0-1.0': 'https://creativecommons.org/publicdomain/zero/1.0/',
'CC-BY-4.0': 'https://creativecommons.org/licenses/by/4.0/',
'CC-BY-SA-4.0': 'https://creativecommons.org/licenses/by-sa/4.0/',
'CC-BY-NC-4.0': 'https://creativecommons.org/licenses/by-nc/4.0/',
'CC-BY-NC-SA-4.0': 'https://creativecommons.org/licenses/by-nc-sa/4.0/',
'CC-BY-ND-4.0': 'https://creativecommons.org/licenses/by-nd/4.0/',
'MIT': 'https://opensource.org/license/mit',
}


def report_exceptions(fn):
def wrapper(self, /, *args, **kwargs):
try:
return fn(self, *args, **kwargs)
except Exception as e:
return [self.state.document.reporter.error(e, line=self.lineno)]
return wrapper


def format_attrs(translator, /, **kwargs):
return ' '.join(f'{k.replace('_', '-')}="{translator.attval(v)}"'
for k, v in sorted(kwargs.items()) if v is not None)


def format_data_attrs(translator, /, **kwargs):
return ' '.join(f'data-tdoc-{k.replace('_', '-')}="{translator.attval(v)}"'
for k, v in sorted(kwargs.items()) if v is not None)


def build_tag(app):
for tag in app.tags:
if tag.startswith('tdoc_build_'):
return tag


def setup(app):
app.add_event('tdoc-html-page-config')

app.add_config_value('license', '', 'html')
app.add_config_value(
'license_url', lambda c: _license_urls.get(c.license, ''), 'html', str)
app.add_config_value('tdoc_enable_sab', 'no', 'html',
config.ENUM('no', 'cross-origin-isolation', 'sabayon'))

app.add_html_theme('t-doc', str(_base))
app.add_message_catalog(_messages, str(_base / 'locale'))

app.connect('config-inited', on_config_inited)
app.connect('builder-inited', on_builder_inited)
app.connect('html-page-context', on_html_page_context)
if build_tag(app):
app.connect('html-page-context', add_reload_js)
app.connect('write-started', write_static_files)

return {
'version': __version__,
'parallel_read_safe': True,
'parallel_write_safe': True,
}


def on_config_inited(app, config):
cv = config.values['html_title']
super(cv.__class__, cv).__setattr__('default', lambda c: c.project)
config.templates_path.append(str(_base / 'templates'))

# Override defaults in html_theme_options.
opts = config.html_theme_options
opts.setdefault('use_sidenotes', True)
opts.setdefault('path_to_docs', 'docs')
if opts.get('repository_url'):
opts.setdefault('use_repository_button', True)
opts.setdefault('use_source_button', True)

# Set the global HTML context.
context = config.html_context
context['tdoc_enable_sab'] = app.config.tdoc_enable_sab
tag = build_tag(app)
context['tdoc_build'] = tag if tag is not None else ''


def on_builder_inited(app):
# Add our own static paths.
app.config.html_static_path.append(str(_base / 'static'))
app.config.html_static_path.append(str(_base / 'static.gen'))

# Add a default static path.
if '_static' not in app.config.html_static_path:
app.config.html_static_path.append('_static')


def on_html_page_context(app, page, template, context, doctree):
license = app.config.license
if license: context['license'] = license
license_url = app.config.license_url
if license_url: context['license_url'] = license_url

# Set up early and on-load JavaScript.
config = {'htmlData': {}}
app.emit('tdoc-html-page-config', page, config)
config = json.dumps(config, separators=(',', ':'))
app.add_js_file(None, priority=0, body=f'const tdocConfig = {config};')
app.add_js_file('tdoc/early.js', priority=1,
scope=context['pathto']('', resource=True))
app.add_js_file('tdoc/load.js', type='module')


def add_reload_js(app, page, template, context, doctree):
app.add_js_file('tdoc/reload.js', type='module')


def write_static_files(app, builder):
if builder.format != 'html': return

# The file must be at the root of the website, to avoid limiting the scope
# of the service worker to _static.
fileutil.copy_asset_file(_base / 'scripts' / 'tdoc-worker.js',
builder.outdir, force=True)
2 changes: 1 addition & 1 deletion tdoc/common/ext/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from docutils.parsers.rst import directives
from sphinx.util import docutils, logging

from .. import __version__, report_exceptions
from . import __version__, report_exceptions

_log = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion tdoc/common/ext/exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from sphinx.directives import code
from sphinx.util import logging, osutil

from .. import __version__, format_attrs, format_data_attrs, report_exceptions
from . import __version__, format_attrs, format_data_attrs, report_exceptions

_log = logging.getLogger(__name__)
_base = pathlib.Path(__file__).absolute().parent.parent
Expand Down
2 changes: 1 addition & 1 deletion tdoc/common/ext/iframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from docutils.parsers.rst import directives
from sphinx.util import docutils, logging

from .. import __version__, report_exceptions
from . import __version__, report_exceptions

_log = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion tdoc/common/ext/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from docutils import nodes
from sphinx.util import docutils, logging

from .. import __version__, report_exceptions
from . import __version__, report_exceptions

_log = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion tdoc/common/ext/num.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from sphinx.environment import collectors
from sphinx.util import docutils, logging, nodes as sphinx_nodes

from .. import __version__
from . import __version__

_log = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion tdoc/common/ext/solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from docutils.parsers.rst.directives import admonitions
from sphinx.util import logging

from .. import _, __version__
from . import _, __version__

_log = logging.getLogger(__name__)

Expand Down

0 comments on commit 054e824

Please sign in to comment.