Skip to content

Commit

Permalink
Refactor plugin, fix minor bugs, add more tests...
Browse files Browse the repository at this point in the history
  • Loading branch information
mondeja committed Jul 2, 2021
1 parent 2589a01 commit 805bb3c
Show file tree
Hide file tree
Showing 16 changed files with 591 additions and 286 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.0.14
current_version = 0.0.15

[bumpversion:file:mkdocs_mdpo_plugin/__init__.py]

Expand Down
2 changes: 1 addition & 1 deletion mkdocs_mdpo_plugin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""mkdocs-mdpo-plugin package"""

__version__ = '0.0.14'
__version__ = '0.0.15'
30 changes: 11 additions & 19 deletions mkdocs_mdpo_plugin/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ def run(self, root):
if not hasattr(current_page, '_language'):
return

current_build_extensions = (
mdpo_plugin.mkdocs_build_config['markdown_extensions']
)

def process_translation(node, msgid):
if msgid not in current_page._translated_entries_msgstrs:
if msgid in current_page._po_msgids:
Expand All @@ -38,7 +34,7 @@ def process_translation(node, msgid):
entry = polib.POEntry(msgid=msgid, msgstr='')
current_page._po.append(entry)

if 'pymdownx.tasklist' in current_build_extensions:
if 'pymdownx.tasklist' in mdpo_plugin._markdown_extensions:
node_should_be_processed = lambda node: False if (
node.tag == 'li' and node.text[:3] in ['[ ]', '[x]', '[X]']
) else True
Expand Down Expand Up @@ -86,10 +82,6 @@ def run(self, root):
if not hasattr(current_page, '_language'):
return

current_build_extensions = (
mdpo_plugin.mkdocs_build_config['markdown_extensions']
)

def process_translation(node, msgid):
if msgid not in current_page._translated_entries_msgstrs:
if msgid in current_page._po_msgids:
Expand All @@ -111,22 +103,22 @@ def process_translation(node, msgid):
entry = polib.POEntry(msgid=msgid, msgstr='')
current_page._po.append(entry)

if 'abbr' in current_build_extensions:
if 'pymdownx.emoji' in current_build_extensions:
node_should_be_processed = lambda node: False if (
node.tag == 'abbr'
or node.get('class') in ['emojione', 'twemoji', 'gemoji']
) else True
if 'abbr' in mdpo_plugin._markdown_extensions:
if 'pymdownx.emoji' in mdpo_plugin._markdown_extensions:
node_should_be_processed = lambda node: (
node.tag != 'abbr' and
node.get('class') not in ['emojione', 'twemoji', 'gemoji']
)
else:
node_should_be_processed = lambda node: node.tag != 'attr'
elif 'pymdownx.emoji' in current_build_extensions:
node_should_be_processed = lambda node: node.tag != 'abbr'
elif 'pymdownx.emoji' in mdpo_plugin._markdown_extensions:
node_should_be_processed = lambda node: (
node.get('class') not in ['emojione', 'twemoji', 'gemoji']
)

if (
'abbr' in current_build_extensions
or 'pymdownx.emoji' in current_build_extensions
'abbr' in mdpo_plugin._markdown_extensions
or 'pymdownx.emoji' in mdpo_plugin._markdown_extensions
):
def iterate_childs(_root):
for child in _root:
Expand Down
12 changes: 4 additions & 8 deletions mkdocs_mdpo_plugin/mdpo_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,13 @@
}


def build_md2po_events(mkdocs_build_config):
def build_md2po_events(markdown_extensions):
"""Build dinamically those mdpo events executed at certain moments of the
Markdown file parsing extrating messages from pages, different depending on
active extensions and plugins.
"""
_md_extensions = mkdocs_build_config['markdown_extensions']

md_extensions = []
for ext in _md_extensions:
for ext in markdown_extensions:
if not isinstance(ext, str):
if isinstance(ext, MkdocstringsExtension):
md_extensions.append('mkdocstrings')
Expand Down Expand Up @@ -109,9 +107,7 @@ def build_event(event_type):
return events


def build_po2md_events(mkdocs_build_config):
md_extensions = mkdocs_build_config['markdown_extensions']

def build_po2md_events(markdown_extensions):
def link_reference_event(po2md_instance, target, href, title):
# footnotes
if target.startswith('^'):
Expand All @@ -127,7 +123,7 @@ def link_reference_event(po2md_instance, target, href, title):
events = {}
for event_name, extensions in PO2MD_EVENT_EXTENSIONS.items():
for extension in extensions:
if extension in md_extensions:
if extension in markdown_extensions:
events[event_name] = events_functions[event_name]
break

Expand Down
38 changes: 38 additions & 0 deletions mkdocs_mdpo_plugin/mdpo_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""mdpo utilities"""

import re

from mdpo.command import COMMAND_SEARCH_RE


COMMAND_SEARCH_RE_AT_LINE_START = re.compile(
r'^(\s{2,})?[^\\]' + COMMAND_SEARCH_RE.pattern + r'\n?',
re.M,
)
COMMAND_SEARCH_RE_ESCAPER = re.compile(
(
r'\\(' + COMMAND_SEARCH_RE.pattern[:20] + ')('
+ COMMAND_SEARCH_RE.pattern[20:38] + '?='
+ COMMAND_SEARCH_RE.pattern[38:] + ')'
),
re.M,
)


def remove_mdpo_commands_preserving_escaped(text):
return re.sub(
# restore escaped commands
'<!-- mdpo-0',
'<!-- mdpo',
re.sub(
# remove commands
COMMAND_SEARCH_RE_AT_LINE_START,
'',
# preserve escaped commands
re.sub(
COMMAND_SEARCH_RE_ESCAPER,
r'\g<1>0-\g<2>',
text,
),
),
)
61 changes: 61 additions & 0 deletions mkdocs_mdpo_plugin/mkdocs_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"""Mkdocs utilities"""

from mkdocs import __version__ as __mkdocs_version__

from mkdocs_mdpo_plugin.io import remove_file_and_parent_dir_if_empty


MKDOCS_MINOR_VERSION_INFO = tuple(
int(n) for n in __mkdocs_version__.split('.')[:2]
)


class MkdocsBuild:
"""Represents the Mkdocs build process.
Is a singleton, so only accepts one build. Should be initialized using
the `instance` class method, which accepts an instance of the plugin class.
"""
_instance = None

@classmethod
def instance(cls, mdpo_plugin):
if cls._instance is None:
cls._instance = cls.__new__(cls)
cls.mdpo_plugin = mdpo_plugin
return cls._instance


def __on_build_error(_self):
for filepath in _self._temp_pages_to_remove:
try:
remove_file_and_parent_dir_if_empty(filepath)
except FileNotFoundError:
pass

MkdocsBuild._instance = None


def set_on_build_error_event(MdpoPlugin):
"""mkdocs>=1.2.0 includes a ``build_error`` event executed when the build
triggers a exception.
This function patch provides the same cleanup functionality if the
`build_error` event is not supported.
"""
if MKDOCS_MINOR_VERSION_INFO >= (1, 2):
if not hasattr(MdpoPlugin, 'on_build_error'):
def _on_build_error(self, error):
return __on_build_error(self)

MdpoPlugin.on_build_error = _on_build_error
else:
import atexit

def _on_build_error(): # pragma: no cover
build_instance = MkdocsBuild()
if hasattr(build_instance, 'mdpo_plugin'):
return __on_build_error(build_instance.mdpo_plugin)

atexit.unregister(_on_build_error)
atexit.register(_on_build_error)
124 changes: 124 additions & 0 deletions mkdocs_mdpo_plugin/on_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
"""Configuration event for 'mkdocs-mdpo-plugin'."""

import mkdocs


def on_config_event(plugin, config, **kwargs):
"""Configuration event for 'mkdocs-mdpo-plugin'.
* Define properly `lc_messages`, `languages` and `locale_dir`
configuration settings.
* Loads `mkdocs.mdpo` extension.
* Configures md4c extensions accordingly to Python-Markdown extensions.
* Stores the Markdown extensions used in the build in the
``_markdown_extensions`` property of the plugin instance.
* Creates the persistent files cache for the project.
"""
if plugin.config['lc_messages'] is True:
plugin.config['lc_messages'] = 'LC_MESSAGES'
elif not plugin.config['lc_messages']:
plugin.config['lc_messages'] = ''

try:
_using_material_theme = config['theme'].name == 'material'
except KeyError:
_using_material_theme = None

# load language selection settings from material or mdpo configuration
def _languages_required():
msg = (
'You must define the languages you will translate the'
' content into using'
f"{' either' if _using_material_theme else ' the'}"
" 'plugins.mdpo.languages'"
)
if _using_material_theme:
msg += " or 'extra.alternate'"
msg += (
' configuration setting'
f"{'s' if _using_material_theme else ''}."
)
return mkdocs.config.base.ValidationError(msg)

languages = plugin.config.get('languages')
if not languages:
if _using_material_theme:
if 'extra' not in config:
raise _languages_required()
alternate = config['extra'].get('alternate')
if not alternate:
raise _languages_required()
plugin.config['languages'] = [alt['lang'] for alt in alternate]
else:
raise _languages_required()

default_language = plugin.config.get('default_language')
if not default_language:
# use mkdocs>=v1.2.0 theme localization setting
theme_locale = (
None if 'theme' not in config
else config['theme']._vars.get('locale')
)
if theme_locale and theme_locale in plugin.config['languages']:
plugin.config['default_language'] = theme_locale
else:
if (
not isinstance(plugin.config['languages'], list)
or not plugin.config['languages']
):
raise _languages_required()

plugin.config['default_language'] = plugin.config['languages'][0]

# ----------------------------------------------------------

# extensions configuration
markdown_extensions = config.get('markdown_extensions')

# configure MD4C extensions
if markdown_extensions:
if 'tables' not in markdown_extensions:
if 'tables' in plugin._md4c_extensions:
plugin._md4c_extensions.remove('tables')
else:
if 'tables' not in plugin._md4c_extensions:
plugin._md4c_extensions.append('tables')
if 'wikilinks' not in markdown_extensions:
if 'wikilinks' in plugin._md4c_extensions:
plugin._md4c_extensions.remove('wikilinks')
else:
if 'wikilinks' not in plugin._md4c_extensions:
plugin._md4c_extensions.append('wikilinks')

# spaces after '#' are optional in Python-Markdown for headers,
# but the extension 'pymdownx.saneheaders' makes them mandatory
if 'pymdownx.saneheaders' in markdown_extensions:
if 'permissive_atx_headers' in plugin._md4c_extensions:
plugin._md4c_extensions.remove('permissive_atx_headers')
else:
if 'permissive_atx_headers' not in plugin._md4c_extensions:
plugin._md4c_extensions.append('permissive_atx_headers')

# 'pymdownx.tasklist' enables 'tasklists' MD4C extentsion
if 'pymdownx.tasklist' in markdown_extensions:
if 'tasklists' not in plugin._md4c_extensions:
plugin._md4c_extensions.append('tasklists')
else:
if 'tasklists' in plugin._md4c_extensions:
plugin._md4c_extensions.remove('tasklists')

# 'pymdownx.tilde' enables strikethrough syntax, but only works
# if the MD4C extension is disabled
if 'pymdownx.tilde' in markdown_extensions:
if 'strikethrough' in plugin._md4c_extensions:
plugin._md4c_extensions.remove('strikethrough')

# configure internal 'mkdocs.mdpo' extension
if 'mkdocs.mdpo' in markdown_extensions: # pragma: no cover
config['markdown_extensions'].remove('mkdocs.mdpo')
config['markdown_extensions'].append('mkdocs.mdpo')

# store reference in plugin to markdown_extensions for later usage
plugin._markdown_extensions = markdown_extensions

# ----------------------------------------------------------
Loading

0 comments on commit 805bb3c

Please sign in to comment.