diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 8614e264..2cde0dbd 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.3.58 +current_version = 0.3.59 [bumpversion:file:mdpo/__init__.py] diff --git a/mdpo/__init__.py b/mdpo/__init__.py index 04a16236..b4f2c43f 100644 --- a/mdpo/__init__.py +++ b/mdpo/__init__.py @@ -5,7 +5,7 @@ from mdpo.po2md import pofile_to_markdown -__version__ = '0.3.58' +__version__ = '0.3.59' __title__ = 'mdpo' __description__ = ('Markdown file translation utilities using PO files') __all__ = ( diff --git a/mdpo/event.py b/mdpo/event.py index 4c766928..65e3942f 100644 --- a/mdpo/event.py +++ b/mdpo/event.py @@ -36,7 +36,7 @@ def _block_msg(block, details): return block.name -def debug_events(program): +def debug_events(program, command=True): """Debugging events for interfaces. Displays in STDOUT all event targets. Args: @@ -93,9 +93,8 @@ def print_link_reference(self, target, href, title): msg += f' - title=\'{title}\'' debug('link_reference', msg) - return { + response = { 'msgid': print_msgid, - 'command': print_command, 'enter_block': print_enter_block, 'leave_block': print_leave_block, 'enter_span': print_enter_span, @@ -103,3 +102,6 @@ def print_link_reference(self, target, href, title): 'text': print_text, 'link_reference': print_link_reference, } + if command: + response['command'] = print_command + return response diff --git a/mdpo/md2po/__init__.py b/mdpo/md2po/__init__.py index 0676d911..16baa407 100644 --- a/mdpo/md2po/__init__.py +++ b/mdpo/md2po/__init__.py @@ -527,8 +527,6 @@ def _process_command(self, text): self.command(command, comment, original_command) def enter_block(self, block, details): - # print("ENTER BLOCK:", block.name) - # raise 'enter_block' event if raise_skip_event(self.events, 'enter_block', self, block, details): return @@ -612,8 +610,6 @@ def enter_block(self, block, details): self._current_top_level_block_type = md4c.BlockType.TABLE.value def leave_block(self, block, details): - # print("LEAVE BLOCK:", block.name) - # raise 'leave_block' event if raise_skip_event(self.events, 'leave_block', self, block, details): return @@ -643,8 +639,6 @@ def leave_block(self, block, details): self._save_current_msgid() def enter_span(self, span, details): - # print("ENTER SPAN:", span.name, details) - # raise 'enter_span' event if raise_skip_event(self.events, 'enter_span', self, span, details): return @@ -702,8 +696,6 @@ def enter_span(self, span, details): self._save_msgid(details['title'][0][1]) def leave_span(self, span, details): - # print("LEAVE SPAN:", span.name, details) - # raise 'leave_span' event if raise_skip_event(self.events, 'leave_span', self, span, details): return @@ -753,8 +745,6 @@ def leave_span(self, span, details): self._inside_uspan = False def text(self, block, text): - # print(f"TEXT: '{text}'") - # raise 'text' event if raise_skip_event(self.events, 'text', self, block, text): return diff --git a/mdpo/po2md/__init__.py b/mdpo/po2md/__init__.py index af167235..d31ccf6f 100644 --- a/mdpo/po2md/__init__.py +++ b/mdpo/po2md/__init__.py @@ -10,6 +10,7 @@ normalize_mdpo_command_aliases, parse_mdpo_html_command, ) +from mdpo.event import debug_events, raise_skip_event from mdpo.io import to_file_content_if_is_file from mdpo.md import ( escape_links_titles, @@ -116,6 +117,12 @@ def __init__(self, pofiles, ignore=[], po_encoding=None, **kwargs): self.events[event_name] = ( [functions] if callable(functions) else functions ) + if kwargs.get('debug'): + dbg_events = debug_events('po2md', command=False) + for event_name, function in dbg_events.items(): + if event_name not in self.events: + self.events[event_name] = [] + self.events[event_name].append(function) self._current_msgid = '' self._current_msgctxt = None @@ -294,6 +301,19 @@ def _translate_msgid(self, msgid, msgctxt, tcomment): return msgstr or msgid def _save_current_msgid(self): + # raise 'msgid' event + if raise_skip_event( + self.events, + 'msgid', + self, + self._current_msgid, + None, + self._current_msgctxt, + self._current_tcomment, + [], + ): + return + if (not self._disable and not self._disable_next_line) or \ self._enable_next_line: translation = self._translate_msgid( @@ -379,7 +399,9 @@ def _save_current_line(self): self._current_line = '' def enter_block(self, block, details): - # print('ENTER BLOCK', block.name, details) + # raise 'enter_block' event + if raise_skip_event(self.events, 'enter_block', self, block, details): + return if self._inside_quoteblock and ( not self._current_line or self._current_line[0] != '>' @@ -479,7 +501,9 @@ def enter_block(self, block, details): self._inside_htmlblock = True def leave_block(self, block, details): - # print('LEAVE BLOCK', block.name, details) + # raise 'leave_block' event + if raise_skip_event(self.events, 'leave_block', self, block, details): + return if block is md4c.BlockType.P: self._save_current_msgid() @@ -612,7 +636,9 @@ def leave_block(self, block, details): self._inside_htmlblock = False def enter_span(self, span, details): - # print("ENTER SPAN", span.name, details) + # raise 'enter_span' event + if raise_skip_event(self.events, 'enter_span', self, span, details): + return try: self._current_msgid += self._enterspan_replacer[span.value] @@ -656,7 +682,9 @@ def enter_span(self, span, details): self._current_wikilink_target = details['target'][0][1] def leave_span(self, span, details): - # print("LEAVE SPAN", span.name, details) + # raise 'leave_span' event + if raise_skip_event(self.events, 'leave_span', self, span, details): + return if span is md4c.SpanType.WIKILINK: self._current_msgid += polib.escape(self._current_wikilink_target) @@ -700,7 +728,9 @@ def leave_span(self, span, details): self._current_imgspan = {} def text(self, block, text): - # print("TEXT", "'%s'" % text) + # raise 'text' event + if raise_skip_event(self.events, 'text', self, block, text): + return if not self._inside_htmlblock: if not self._inside_codeblock: @@ -835,6 +865,7 @@ def pofile_to_markdown( command_aliases={}, wrapwidth=80, events={}, + debug=False, **kwargs, ): r"""Translate Markdown content or a file using PO files for message replacing. @@ -872,9 +903,23 @@ def pofile_to_markdown( of the translation process is skipped by po2md. The available events are: + * ``enter_block(self, block, details)``: Executed when the parsing + a Markdown block starts. + * ``leave_block(self, block, details)``: Executed when the parsing + a Markdown block ends. + * ``enter_span(self, span, details)``: Executed when the parsing of + a Markdown span starts. + * ``leave_span(self, span, details)``: Executed when the parsing of + a Markdown span ends. + * ``text(self, block, text)``: Executed when the parsing of text + starts. + * ``msgid(self, msgid, msgstr, msgctxt, tcomment, flags)``: + Executed when a msgid is going to be replaced. * ``link_reference(self, target, href, title)``: Executed when each reference link is being written in the output (at the end of the translation process). + debug (bool): Add events displaying all parsed elements in the + translation process. Returns: str: Markdown output file with translated content. @@ -886,6 +931,7 @@ def pofile_to_markdown( command_aliases=command_aliases, wrapwidth=wrapwidth, events=events, + debug=debug, **kwargs, ).translate( filepath_or_content, diff --git a/mdpo/po2md/__main__.py b/mdpo/po2md/__main__.py index 3b890dfd..6ec6bbdf 100644 --- a/mdpo/po2md/__main__.py +++ b/mdpo/po2md/__main__.py @@ -70,6 +70,11 @@ def build_parser(): ' charset=\\n\'.', metavar='', ) + parser.add_argument( + '-D', '--debug', dest='debug', action='store_true', + help='Print useful messages in the parsing process showing the' + ' contents of all Markdown elements.', + ) add_common_cli_latest_arguments(parser) return parser @@ -110,6 +115,7 @@ def run(args=[]): po_encoding=opts.po_encoding, command_aliases=opts.command_aliases, wrapwidth=opts.wrapwidth, + debug=opts.debug, ) if not opts.quiet and not opts.save: diff --git a/setup.cfg b/setup.cfg index bd952942..5412df5a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = mdpo -version = 0.3.58 +version = 0.3.59 description = Markdown files translation using PO files. long_description = file: README.md long_description_content_type = text/markdown diff --git a/test/test_po2md/test_po2md_cli.py b/test/test_po2md/test_po2md_cli.py index e1e35906..072fb97a 100644 --- a/test/test_po2md/test_po2md_cli.py +++ b/test/test_po2md/test_po2md_cli.py @@ -1,5 +1,8 @@ +"""Tests for po2md command line interface.""" + import io import os +import re import tempfile from uuid import uuid4 @@ -51,6 +54,39 @@ def test_quiet(capsys, arg, tmp_file): assert out == '' +@pytest.mark.parametrize('arg', ['-D', '--debug']) +def test_debug(capsys, arg, tmp_file): + with tmp_file(EXAMPLE['pofile'], '.po') as po_filepath, \ + tmp_file(EXAMPLE['markdown-input'], '.md') as input_md_filepath: + + output, exitcode = run([input_md_filepath, '-p', po_filepath, arg]) + out, err = capsys.readouterr() + + assert exitcode == 0 + assert output == EXAMPLE['markdown-output'] + + md_output_checked = False + + outlines = out.splitlines() + for i, line in enumerate(outlines): + assert re.match( + ( + r'^po2md\[DEBUG\]::\d{4,}-\d\d-\d\d\s\d\d:\d\d:\d\d::' + r'(text|link_reference|msgid|enter_block|' + r'leave_block|enter_span|leave_span)::' + ), + line, + ) + if line.endswith('leave_block:: DOC'): + assert ( + '\n'.join(outlines[i + 1:]) == EXAMPLE['markdown-output'] + ) + md_output_checked = True + break + + assert md_output_checked + + @pytest.mark.parametrize('arg', ['-s', '--save']) def test_save(capsys, arg, tmp_file): with tmp_file(EXAMPLE['pofile'], '.po') as po_filepath, \