feat: Allow semiliterate to adjust the theme
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing

The mechanism here is to shadow a specified `custom.theme_dir` in the
  generated docs directory, and then ignore generated files therein (since they
  will be being used by the theme to render the pages, and are not actually
  part of the documentation).
This commit is contained in:
Glen Whitney 2022-08-09 08:17:37 -07:00
parent 86010351b7
commit b1203327ad
33 changed files with 3180 additions and 9 deletions

View file

@ -19,6 +19,7 @@ from mkdocs_simple_plugin.plugin import SimplePlugin
import os
import re
import subprocess
import sys
import tempfile
import yaml
@ -164,9 +165,8 @@ is checked for `{! ... !}`.
utils.log.error(errmsg)
raise EOFError(errmsg)
filename = body_match['fn']
gitextract = False
r""" md
### Double-quoted filenames and Git extraction
### Double-quoted filenames and special extraction
Standard Python escape sequences in double-quoted filenames are interpreted
as usual; for example you can write
@ -179,9 +179,13 @@ as usual; for example you can write
to include a file whose name (`snippet/Say "Don't"`, in this case) has both
double and single quotes.
Further, `semiliterate` supports a special escape to extract a file from the
Git archive of the project (presuming it is under Git version control) and then
include content from that file. For example, you could write
Further, `semiliterate` supports some special escape sequences for
doublequoted file names to include text from other places than current files
in the project tree:
`\git`: extracts a version of a file from the Git archive of the project
(presuming it is under Git version control) and then
includes content from that file. For example, you could write
```
{! ../tests/fixtures/git-inclusion/README.md extract:
start: '(.*!.*)'
@ -206,14 +210,32 @@ form
is that the output of `git show SPECIFIER` is written to a temporary file,
and that file is extracted from.
`\syspath`: searches for the remainder of the doublequoted filename in the
python `sys.path` and includes content from the found file. For example, you
could write
```
{! ../tests/fixtures/theme-modification/doc_theme/.base.generator extract:
start: '(.*!.*)'
!}
```
to create a version of the "base.html" of the "readthedocs" theme with
additional content at the very top of the body. As the example suggests, this
mechanism is primarily useful to tweak an mkdocs theme in ways not
anticipated by the `{%- block ... %}` directives placed by the theme writer.
"""
gitextract = False
syspathextract = False
if doublequoted:
if filename[:5] == r'\git ':
gitextract = True
filename = filename[5:]
elif filename[:9] == r'\syspath ':
syspathextract = True
filename = filename[9:]
filename = (filename.encode('latin-1', 'backslashreplace')
.decode('unicode-escape'))
include_path = self.include_root + '/' + filename
include_path = os.path.join(self.include_root, filename)
if gitextract:
(write_handle, include_path) = tempfile.mkstemp()
utils.log.info(
@ -221,7 +243,13 @@ and that file is extracted from.
contents = subprocess.check_output(['git', 'show', filename])
os.write(write_handle, contents)
os.close(write_handle)
new_root = re.match(r'(.*)/', include_path)[1]
if syspathextract:
for dirname in sys.path:
candidate = os.path.join(dirname, filename)
if os.path.isfile(candidate):
include_path = candidate
break
new_root = os.path.dirname(include_path)
try:
include_parameters = yaml.safe_load(body_match['yml'])
except Exception as err:
@ -300,6 +328,10 @@ default values in parentheses at the beginning of each entry.
- ['config_options.Type.*?default=([^\)]*)', ': (\1)']
- '^\s*#(.*\s*)$'
terminate: '^\s*\)'
!}
{! plugin.py extract:
start: 'r["]{3}Extend'
stop: '["]{3}'
!}
"""
config_scheme = (
@ -359,8 +391,42 @@ terminate: '^\s*\)'
pattern=re.compile(f"^(.*(?:{ext_pat}))$"),
destination=r'\1',
**self.config['extract_standard_markdown']))
r""" md
### Adjusting the mkdocs theme
`semiliterate` also makes it possible to add generated files to the mkdocs
theme. It does this by detecting if a `theme.custom_dir` parameter has been set
in the mkdocs configuration, and if so, it adds the corresponding directory
in the generated docs dir to the theme search path. (Note this means that
files in the corresponding subdirectory of your project will be copied into
the resulting doc site unless their names start with a '.')
"""
cfpath = os.path.dirname(config.config_file_path)
self.custom_dir = None
for themedir in config['theme'].dirs:
common = os.path.commonpath([cfpath, themedir])
if common == cfpath:
self.custom_dir = os.path.relpath(themedir, cfpath)
newthemedir = os.path.join(self.build_docs_dir, self.custom_dir)
utils.log.debug(
'mkdocs-semiliterate: found theme.custom_dir = '
+ self.custom_dir
+ f"; adding theme directory {newthemedir}")
config['theme'].dirs.insert(0, newthemedir)
break
return new_config
def on_files(self, files, config):
# If we designated a subdirectory for the theme, ignore files in it
if self.custom_dir:
sources = files.src_paths
for path in sources:
if path.startswith(self.custom_dir):
utils.log.debug(
f"mkdocs-semiliterate: ignoring {path} "
+ f"from theme directory {self.custom_dir}")
files.remove(sources[path])
def in_extensions(self, file):
if any(ext in file for ext in self.exclude_extensions):
return False
@ -375,7 +441,7 @@ terminate: '^\s*\)'
class Demiliterate(Semiliterate):
r""" md Extends Semiliterate to use StreamInclusion, not StreamExtract
r"""Extends Semiliterate to use StreamInclusion, not StreamExtract
semiliterate.ensurelines
: (true) Guarantees that a newline is trancribed for each line of the input,