diff --git a/CHANGELOG.md b/CHANGELOG.md index 598bd70..55b7c59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v0.13.1 - 2023-07-29 + +- fixed crash regression with Doxygen 1.9.7 +- fixed issues with \[tag\] substitution +- minor style fixes + ## v0.13.0 - 2023-07-28 - migrated to `pyproject.toml` diff --git a/src/poxy/css/poxy-overrides.css b/src/poxy/css/poxy-overrides.css index abbcb80..08853ae 100644 --- a/src/poxy/css/poxy-overrides.css +++ b/src/poxy/css/poxy-overrides.css @@ -50,10 +50,16 @@ a:hover { } article div > section { - margin-top: 2rem; + margin-top: 2.5rem; +} +article div > section:first-of-type { + margin-top: initial; } article div > section > section { - margin-bottom: 2.25rem; + margin-top: 2.25rem; +} +article div > section > section:first-of-type { + margin-top: initial; } a.poxy-external { @@ -397,6 +403,9 @@ section.m-doc-details div .m-table.m-fullwidth.m-flat tbody td:first-of-type wbr } /* support for those pretty "about the author" blocks as seen in other m.css pages */ +.poxy-about-the-author { + margin-top: 4rem; +} .poxy-about-the-author .socials { display: block; padding-top: 0.5rem; diff --git a/src/poxy/doxygen.py b/src/poxy/doxygen.py index 83f7abe..a875f3a 100644 --- a/src/poxy/doxygen.py +++ b/src/poxy/doxygen.py @@ -111,16 +111,22 @@ def test_path(p): return path.val -def version() -> str: +def version() -> tuple[int, int, int]: if not hasattr(version, "val"): proc = subprocess.run([str(path()), r'--version'], capture_output=True, encoding=r'utf-8', check=True) ret = proc.stdout.strip() if proc.stdout is not None else '' if not ret and proc.stderr.strip(): raise Error(rf'doxygen exited with error: {proc.stderr.strip()}') - version.val = ret + ret = re.fullmatch(r'\s*[v]?\s*([0-9]+)\s*\.\s*([0-9]+)\s*\.\s*([0-9])(\s.+?)?', ret, flags=re.I) + assert ret + version.val = (int(ret[1]), int(ret[2]), int(ret[3])) return version.val +def version_string() -> str: + return rf'{version()[0]}.{version()[1]}.{version()[2]}' + + # ======================================================================================================================= # Doxyfile # ======================================================================================================================= @@ -411,7 +417,9 @@ def parse_type(node: graph.Node, elem, resolve_auto_as=None): # extract constexpr, constinit, static, mutable etc out of the type if doxygen has leaked it while type_elem.text: text = rf' {type_elem.text} ' - match = re.search(r'\s(?:(?:const(?:expr|init|eval)|static|mutable|explicit|virtual|inline|friend)\s)+', text) + match = re.search( + r'\s(?:(?:const(?:expr|init|eval)|static|mutable|explicit|virtual|inline|friend)\s)+', text + ) if match is None: break type_elem.text = (text[: match.start()] + r' ' + text[match.end() :]).strip() @@ -463,7 +471,9 @@ def parse_location(node: graph.Node, elem): node = g.get_or_create_node(id=compound.get(r'refid'), type=KINDS_TO_NODE_TYPES[compound.get(r'kind')]) if node.type is graph.File: # files use their local name?? doxygen is so fucking weird - node.local_name = tail(extract_subelement_text(compound, r'name').strip().replace('\\', r'/').rstrip(r'/'), r'/') # + node.local_name = tail( + extract_subelement_text(compound, r'name').strip().replace('\\', r'/').rstrip(r'/'), r'/' + ) # else: node.qualified_name = extract_subelement_text(compound, r'name') @@ -472,7 +482,9 @@ def parse_location(node: graph.Node, elem): member_kind = member_elem.get(r'kind') if member_kind == r'enumvalue': continue - member = g.get_or_create_node(id=member_elem.get(r'refid'), type=KINDS_TO_NODE_TYPES[member_kind], parent=node) + member = g.get_or_create_node( + id=member_elem.get(r'refid'), type=KINDS_TO_NODE_TYPES[member_kind], parent=node + ) name = extract_subelement_text(member_elem, r'name') if name: if member.type is graph.Define: @@ -1088,7 +1100,9 @@ def make_location(elem, node: graph.Node): ) for node_type in _ordered(*COMPOUND_NODE_TYPES): for node in g(node_type): - compound = xml_utils.make_child(root, r'compound', refid=node.id, kind=NODE_TYPES_TO_KINDS[node.type]) # + compound = xml_utils.make_child( + root, r'compound', refid=node.id, kind=NODE_TYPES_TO_KINDS[node.type] + ) # xml_utils.make_child(compound, r'name').text = node.qualified_name if node.type is graph.Directory: continue diff --git a/src/poxy/fixers.py b/src/poxy/fixers.py index c0fcf82..76a3ef8 100644 --- a/src/poxy/fixers.py +++ b/src/poxy/fixers.py @@ -34,149 +34,265 @@ class PlainTextFixer(object): # HTML post-processes # ======================================================================================================================= +# yapf: disable + +PAIRED_TAGS = TrieRegEx( + r'aside', + r'code', + r'div', + r'p', + r'pre', + r'span', + r'aside', + r'b', + r'center', + r'em', + r'h1', + r'h2', + r'h3', + r'h4', + r'h5', + r'h6', + r'i', + r'li', + r'ol', + r'strong', + r'u', + r'ul', +) +PAIRED_TAGS = PAIRED_TAGS.regex() +PAIRED_TAGS = re.compile( + r'\[\s*' + + rf'({PAIRED_TAGS})\s*' # group 1: tag name + + r'([^\]]*?)\s*' # group 2: tag attributes + + r'\]' + + r'(.*?)' # group 3: tag content + + r'\[\s*/\s*\1\s*\]', # closer + re.I | re.S, +) + +SINGLE_TAGS = TrieRegEx( + r'add_class', + r'add_parent_class', + r'add_parent_parent_class', + r'htmlentity', + r'entity', + r'emoji', + r'img', + r'li', + r'ol', + r'parent_add_class', + r'parent_parent_add_class', + r'parent_parent_remove_class', + r'parent_parent_set_class', + r'parent_parent_set_id', + r'parent_parent_set_name', + r'parent_remove_class', + r'parent_set_class', + r'parent_set_id', + r'parent_set_name', + r'remove_class', + r'remove_parent_class', + r'remove_parent_parent_class', + r'set_class', + r'set_id', + r'set_name', + r'set_parent_class', + r'set_parent_class', + r'set_parent_id', + r'set_parent_id', + r'set_parent_name', + r'set_parent_name', + r'ul', +) +SINGLE_TAGS = SINGLE_TAGS.regex() +SINGLE_TAGS = re.compile( + r'\[\s*' + + rf'({SINGLE_TAGS})\s*' # group 1: tag name + + r'([^\]]*?)\s*' # group 2: tag attributes + + r'\]', + re.I | re.S, +) + +# yapf: enable + +TAG_PARENTS = TrieRegEx( + r'dd', + r'p', + r'h1', + r'h2', + r'h3', + r'h4', + r'h5', + r'h6', + r'li', + r'aside', + r'td', + r'div', + r'span', + r'a', + r'i', + r'u', + r'b', +) +TAG_PARENTS = TAG_PARENTS.regex() +TAG_PARENTS = re.compile(rf'^{TAG_PARENTS}$', re.I) + +TAG_DISALLOWED_PARENTS = (r'code', r'pre') + class CustomTags(HTMLFixer): ''' Modifies HTML using custom square-bracket [tags]. ''' - __double_tags = re.compile( - r'\[\s*(' - + r'p|center|span|div|aside|code|pre|h1|h2|h3|h4|h5|h6|em|strong|b|i|u|li|ul|ol' - + r')(.*?)\s*\](.*?)\[\s*/\1\s*\]', - re.I | re.S, - ) - __single_tags = re.compile( - r'\[\s*(/?(?:' - + r'p|img|span|div|aside|code|pre|emoji' - + r'|(?:parent_)?set_(?:parent_)?(?:name|class)' - + r'|(?:parent_)?(?:add|remove)_(?:parent_)?class' - + r'|br|li|ul|ol|(?:html)?entity)' - + r')(\s+[^\]]+?)?\s*\]', - re.I | re.S, - ) __hex_entity = re.compile(r'(?:[0#]?[xX])?([a-fA-F0-9]+)') - __allowed_parents = ('dd', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'aside', 'td', 'div', 'span') - @classmethod - def __double_tags_substitute(cls, m, out, context): - return f'<{m[1]}{html.unescape(m[2])}>{m[3]}' + def __paired_tags_substitute(cls, m, out, context): + tag_name = m[1].lower() + tag_attrs = m[2].strip() if m[2] else '' + tag_attrs = rf' {tag_attrs}' if tag_attrs else '' + tag_content = m[3].strip() if m[3] else '' + if tag_content: + return rf'<{tag_name}{tag_attrs}>{tag_content}' + return rf'<{tag_name}{tag_attrs} />' @classmethod def __single_tags_substitute(cls, m, out, context): tag_name = m[1].lower() - tag_content = m[2].strip() if m[2] else '' - if tag_name == 'htmlentity' or tag_name == 'entity': - if not tag_content: + tag_attrs = m[2].strip() if m[2] else '' + if tag_name in (r'htmlentity', r'entity'): + if not tag_attrs: return '' - hex_match = cls.__hex_entity.fullmatch(tag_content) + hex_match = cls.__hex_entity.fullmatch(tag_attrs) if hex_match: try: cp = int(hex_match[1], 16) if cp <= 0x10FFFF: - return f'&#x{hex_match[1]};' + return rf'&#x{hex_match[1]};' except: pass - return f'&{tag_content};' - elif tag_name == 'emoji': - tag_content = tag_content.lower() - if not tag_content: + return f'&{tag_attrs};' + elif tag_name == r'emoji': + if not tag_attrs: return '' + tag_attrs = tag_attrs.lower() emoji = None for base in (16, 10): try: - emoji = context.emoji[int(tag_content, base)] + emoji = context.emoji[int(tag_attrs, base)] if emoji is not None: break except: pass if emoji is None: - emoji = context.emoji[tag_content] - if emoji is not None: - return str(emoji) + emoji = context.emoji[tag_attrs] + return str(emoji) if emoji is not None else '' + elif tag_name.find(r'_class') != -1: + if tag_attrs: + tag_attrs = [s.strip() for s in tag_attrs.split()] + tag_attrs = [s for s in tag_attrs if s] + if tag_attrs: + out.append((tag_name, tag_attrs)) return '' - elif tag_name in ( - r'add_class', - r'remove_class', - r'set_class', - r'parent_add_class', - r'parent_remove_class', - r'parent_set_class', - r'add_parent_class', - r'remove_parent_class', - r'set_parent_class', - ): - classes = [] - if tag_content: - for s in tag_content.split(): - if s: - classes.append(s) - if classes: - out.append((tag_name, classes)) - return '' - elif tag_name in (r'set_name', r'parent_set_name', r'set_parent_name'): - if tag_content: - out.append((tag_name, tag_content)) + elif tag_name.find(r'_name') != -1 or tag_name.find(r'_id') != -1: + if tag_attrs: + out.append((tag_name, tag_attrs)) return '' else: - return f'<{m[1]}{(" " + tag_content) if tag_content else ""}>' + return rf'<{tag_name}{rf" {tag_attrs}" if tag_attrs else ""}>' def __call__(self, context: Context, doc: soup.HTMLDocument, path: Path): if doc.article_content is None: return False + changed = False + + def get_candidate_tags(): + tags = doc.article_content.find_all(TAG_PARENTS) + tags = [tag for tag in tags if not tag.decomposed and len(tag.contents)] + tags = [tag for tag in tags if soup.find_parent(tag, TAG_DISALLOWED_PARENTS, doc.article_content) is None] + return tags + + # paired tags changed_this_pass = True while changed_this_pass: changed_this_pass = False - for name in self.__allowed_parents: - tags = doc.article_content.find_all(name) - for tag in tags: - if ( - tag.decomposed - or len(tag.contents) == 0 - or soup.find_parent(tag, 'a', doc.article_content) is not None - ): - continue - replacer = RegexReplacer( - self.__double_tags, lambda m, out: self.__double_tags_substitute(m, out, context), str(tag) - ) - if replacer: - changed_this_pass = True - soup.replace_tag(tag, str(replacer)) - continue - replacer = RegexReplacer( - self.__single_tags, lambda m, out: self.__single_tags_substitute(m, out, context), str(tag) - ) - if replacer: - changed_this_pass = True - parent = tag.parent - new_tags = soup.replace_tag(tag, str(replacer)) - for i in range(len(replacer)): - if replacer[i][0].find(r'parent_') != -1: - if parent is None: - continue - if replacer[i][0] in (r'parent_add_class', r'add_parent_class'): - soup.add_class(parent, replacer[i][1]) - elif replacer[i][0] in (r'parent_remove_class', r'remove_parent_class'): - soup.remove_class(parent, replacer[i][1]) - elif replacer[i][0] in (r'parent_set_class', r'set_parent_class'): - soup.set_class(parent, replacer[i][1]) - elif replacer[i][0] in (r'parent_set_name', r'set_parent_name'): - parent.name = replacer[i][1] - elif len(new_tags) == 1 and not isinstance(new_tags[0], NavigableString): - if replacer[i][0] == r'add_class': - soup.add_class(new_tags[0], replacer[i][1]) - elif replacer[i][0] == r'remove_class': - soup.remove_class(new_tags[0], replacer[i][1]) - elif replacer[i][0] == r'set_class': - soup.set_class(new_tags[0], replacer[i][1]) - elif replacer[i][0] == r'set_name': - new_tags[0].name = replacer[i][1] + for tag in get_candidate_tags(): + replacer = RegexReplacer( + PAIRED_TAGS, lambda m, out: self.__paired_tags_substitute(m, out, context), str(tag) + ) + if replacer: + changed_this_pass = True + soup.replace_tag(tag, str(replacer)) + break + if changed_this_pass: + doc.smooth() + changed = True - continue + # single tags + changed_this_pass = True + while changed_this_pass: + changed_this_pass = False + tags = get_candidate_tags() + strings = [] + for tag in tags: + strings += [string for string in tag.children if isinstance(string, NavigableString) and len(string)] + for string in strings: + before = str(string) + replacer = RegexReplacer( + SINGLE_TAGS, lambda m, out: self.__single_tags_substitute(m, out, context), str(string) + ) + if replacer: + changed_this_pass = True + parent = string.parent + new_tags = soup.replace_tag(string, str(replacer)) + if parent is not None and parent.name == 'p' and not len(parent.contents): + parent = parent.parent + for i in range(len(replacer)): # custom tag handling + key = replacer[i][0] + if key.find(r'parent_') != -1: + if key.find(r'parent_parent') != -1: + key = key.replace(r'parent_parent', r'parent') + if parent is not None: + parent = parent.parent + if parent is None: + continue + if key in (r'parent_add_class', r'add_parent_class'): + soup.add_class(parent, replacer[i][1]) + elif key in (r'parent_remove_class', r'remove_parent_class'): + soup.remove_class(parent, replacer[i][1]) + elif key in (r'parent_set_class', r'set_parent_class'): + soup.set_class(parent, replacer[i][1]) + elif key in (r'parent_set_name', r'set_parent_name'): + parent.name = replacer[i][1] + elif key in (r'parent_set_id', r'set_parent_id'): + parent['id'] = replacer[i][1] + elif key.find(r'_class') or key.find(r'_name') != -1 or key.find(r'_id') != -1: + target = None + if len(new_tags) == 1: + target = new_tags[0] + elif not new_tags: + target = parent + if target is not None and isinstance(target, NavigableString): + target = target.parent + if not target: + continue + if key == r'add_class': + soup.add_class(target, replacer[i][1]) + elif key == r'remove_class': + soup.remove_class(target, replacer[i][1]) + elif key == r'set_class': + soup.set_class(target, replacer[i][1]) + elif key == r'set_name': + target.name = replacer[i][1] + elif key == r'set_id': + target.id = replacer[i][1] + continue if changed_this_pass: doc.smooth() changed = True + return changed diff --git a/src/poxy/generated/poxy.css b/src/poxy/generated/poxy.css index 9cac33c..a777076 100644 --- a/src/poxy/generated/poxy.css +++ b/src/poxy/generated/poxy.css @@ -2645,8 +2645,10 @@ body > header, body > header * { white-space: nowrap; } a { text-decoration: none !important; } a:hover { text-decoration: underline !important; } -article div > section { margin-top: 2rem; } -article div > section > section { margin-bottom: 2.25rem; } +article div > section { margin-top: 2.5rem; } +article div > section:first-of-type { margin-top: initial; } +article div > section > section { margin-top: 2.25rem; } +article div > section > section:first-of-type { margin-top: initial; } a.poxy-external { font-weight: normal; } pre.m-code a, pre.m-console a { font-weight: inherit !important; color: inherit !important; } @@ -2810,6 +2812,7 @@ margin-top: initial; .m-doc-template-params.m-doc-template-long { display: block; padding-left: 1rem; } .m-doc-template-params.m-doc-template-long .m-doc-template-param::before { content: ""; display: block; } section.m-doc-details div .m-table.m-fullwidth.m-flat tbody td:first-of-type wbr { display: none; } +.poxy-about-the-author { margin-top: 4rem; } .poxy-about-the-author .socials { display: block; padding-top: 0.5rem; } .poxy-about-the-author img.poxy-icon, .poxy-about-the-author svg.poxy-icon { max-width: 1.5rem; max-height: 1.5rem; margin-right: 0.5rem; } diff --git a/src/poxy/main.py b/src/poxy/main.py index d046b32..0e264fb 100644 --- a/src/poxy/main.py +++ b/src/poxy/main.py @@ -116,12 +116,19 @@ def main(invoker=True): help=r'override the default visual theme (default: read from config)', ) args.add_argument( - r'--threads', type=int, default=0, metavar=r'N', help=r"set the number of threads to use (default: automatic)" # + r'--threads', + type=int, + default=0, + metavar=r'N', + help=r"set the number of threads to use (default: automatic)", # ) args.add_argument(r'--version', action=r'store_true', help=r"print the version and exit", dest=r'print_version') # make_boolean_optional_arg(args, r'xml', default=False, help=r'specify whether XML output is required') # make_boolean_optional_arg( - args, r'werror', default=None, help=r'override the treating of warnings as errors (default: read from config)' # + args, + r'werror', + default=None, + help=r'override the treating of warnings as errors (default: read from config)', # ) args.add_argument( r'--bug-report', action=r'store_true', help=r"captures all output in a zip file for easier bug reporting." # @@ -136,7 +143,9 @@ def main(invoker=True): args.add_argument(r'--update-fonts', action=r'store_true', help=argparse.SUPPRESS) # args.add_argument(r'--update-emoji', action=r'store_true', help=argparse.SUPPRESS) # args.add_argument(r'--update-tests', action=r'store_true', help=argparse.SUPPRESS) # - args.add_argument(r'--update-mcss', type=Path, default=None, metavar=r'', help=argparse.SUPPRESS, dest=r'mcss') # + args.add_argument( + r'--update-mcss', type=Path, default=None, metavar=r'', help=argparse.SUPPRESS, dest=r'mcss' + ) # args.add_argument( # --xml and --html are the replacements for --xmlonly r'--xmlonly', action=r'store_true', help=argparse.SUPPRESS # ) @@ -200,7 +209,19 @@ def main(invoker=True): bug_report_zip = (Path.cwd() / r'poxy_bug_report.zip').resolve() if args.bug_report: - bug_report_args = [arg for arg in sys.argv[1:] if arg not in (r'--bug-report', r'--bug-report-internal')] + BUG_REPORT_STRIP_ARGS = ( + r'--bug-report', + r'--bug-report-internal', + r'-v', + r'--verbose', + r'--color', + r'--no-color', + r'--colour', + r'--no-colour', + ) + + bug_report_args = [arg for arg in sys.argv[1:]] + bug_report_args_stripped = [arg for arg in bug_report_args if arg not in BUG_REPORT_STRIP_ARGS] print(r'Preparing output paths') delete_directory(bug_report_directory) @@ -209,7 +230,7 @@ def main(invoker=True): print(r'Invoking poxy') result = subprocess.run( - args=[r'poxy', *bug_report_args, r'--bug-report-internal'], + args=[r'poxy', *bug_report_args, r'--bug-report-internal', r'--verbose'], cwd=str(Path.cwd()), check=False, stdout=subprocess.PIPE, @@ -229,9 +250,9 @@ def main(invoker=True): print(r'Writing metadata') with open(bug_report_directory / r'metadata.txt', r'w', newline='\n', encoding=r'utf-8') as f: - print(rf'version: {VERSION_STRING}', file=f) - print(rf'args: {bug_report_args}', file=f) - print(rf'returncode: {result.returncode}', file=f) + f.write(f'version: {VERSION_STRING}\n') + f.write(f'args: {bug_report_args_stripped}\n') + f.write(f'returncode: {result.returncode}\n') # zip file print(r'Zipping files') diff --git a/src/poxy/project.py b/src/poxy/project.py index a7e7d85..c96af26 100644 --- a/src/poxy/project.py +++ b/src/poxy/project.py @@ -512,23 +512,23 @@ class Defaults(object): r'ebash': r'@endcode', r'endbash': r'@endcode', r'detail': r'@details', - r'inline_subheading{1}': r'[h4]\1[/h4]', r'conditional_return{1}': r'\1: ', - r'inline_success': r'[set_class m-note m-success]', - r'inline_note': r'[set_class m-note m-info]', - r'inline_warning': r'[set_class m-note m-danger]', r'inline_attention': r'[set_class m-note m-warning]', + r'inline_note': r'[set_class m-note m-info]', r'inline_remark': r'[set_class m-note m-default]', + r'inline_subheading{1}': r'[h4]\1[/h4]', + r'inline_success': r'[set_class m-note m-success]', + r'inline_warning': r'[set_class m-note m-danger]', r'github{1}': r'\1', r'github{2}': r'\2', r'gitlab{1}': r'\1', r'gitlab{2}': r'\2', r'godbolt{1}': r'Try this code on Compiler Explorer', r'flags_enum': r'@note This enum is a flags type; it is equipped with a full complement of bitwise operators. ^^', - r'implementers': r'@par [parent_set_class m-block m-dim][emoji hammer][entity nbsp]Implementers: ', - r'optional': r'@par [parent_set_class m-block m-info]Optional field ^^', - r'required': r'@par [parent_set_class m-block m-warning][emoji warning][entity nbsp]Required field ^^', - r'availability': r'@par [parent_set_class m-block m-special]Conditional availability ^^', + r'implementers': r'@par [parent_parent_set_class m-block m-dim][emoji hammer][entity nbsp]Implementers: ', + r'optional': r'@par [parent_parent_set_class m-block m-info]Optional field ^^', + r'required': r'@par [parent_parent_set_class m-block m-warning][emoji warning][entity nbsp]Required field ^^', + r'availability': r'@par [parent_parent_set_class m-block m-special]Conditional availability ^^', r'figure{1}': r'@image html \1', r'figure{2}': r'@image html \1 "\2"', # m.css diff --git a/src/poxy/run.py b/src/poxy/run.py index aa85ddf..0e0991e 100644 --- a/src/poxy/run.py +++ b/src/poxy/run.py @@ -460,6 +460,15 @@ def postprocess_xml(context: Context): compound_title = compounddef.find(r'title') compound_title = compound_title.text if compound_title is not None else compound_name + # fix weird regression in doxygen 1.9.7 + if compound_kind == r'file' and doxygen.version() == (1, 9, 7): + sectiondefs = [s for s in compounddef.findall(r'sectiondef') if s.get(r'kind') == r'define'] + for sectiondef in sectiondefs: + members = [m for m in sectiondef.findall(r'member') if m.get(r'kind') == r'define'] + for member in members: + sectiondef.remove(member) + changed = True + # add entry to compounds etc if compound_id not in context.compounds: context.compounds[compound_id] = { @@ -1641,7 +1650,7 @@ def run( # generate + postprocess XML in temp_xml_dir # (we always do this even when output_xml is false because it is required by the html) - with timer(rf'Generating XML files with Doxygen {doxygen.version()}') as t: + with timer(rf'Generating XML files with Doxygen {doxygen.version_string()}') as t: run_doxygen(context) with timer(r'Post-processing XML files') as t: if context.xml_v2: diff --git a/src/poxy/version.txt b/src/poxy/version.txt index 54d1a4f..c317a91 100644 --- a/src/poxy/version.txt +++ b/src/poxy/version.txt @@ -1 +1 @@ -0.13.0 +0.13.1 diff --git a/tests/regenerate_tests.py b/tests/regenerate_tests.py index 6a56b01..b851073 100644 --- a/tests/regenerate_tests.py +++ b/tests/regenerate_tests.py @@ -104,7 +104,7 @@ def regenerate_expected_outputs(): text = text.replace(r'src="search-v2.js"', r'src="../../../src/poxy/mcss/documentation/search.js"') text = re.sub(r'Poxy v[0-9]+[.][0-9]+[.][0-9]+', r'Poxy v0.0.0', text) text = re.sub(r'version="\s*[0-9]+[.][0-9]+[.][0-9]+\s*"', r'version="0.0.0"', text) - text = re.sub(r'gitid="\s*[0-9a-fA-F]+\s*"', r'gitid="000000000000000000000000000000000000000"', text) + text = re.sub(r'\s*doxygen_gitid="\s*[0-9a-fA-F]+\s*"', r'', text) print(rf"Writing {path}") with open(path, r'w', encoding=r'utf-8', newline='\n') as f: f.write(text) diff --git a/tests/test_empty_project/expected_html/tagfile.xml b/tests/test_empty_project/expected_html/tagfile.xml index d2bb145..4d971ff 100644 --- a/tests/test_empty_project/expected_html/tagfile.xml +++ b/tests/test_empty_project/expected_html/tagfile.xml @@ -1,3 +1,3 @@ - + diff --git a/tests/test_project/expected_html/Test!.tagfile.xml b/tests/test_project/expected_html/Test!.tagfile.xml index 6078b2c..d2b7a0e 100644 --- a/tests/test_project/expected_html/Test!.tagfile.xml +++ b/tests/test_project/expected_html/Test!.tagfile.xml @@ -1,5 +1,5 @@ - + code.h code_8h.html diff --git a/tests/test_project/expected_xml/Test!.tagfile.xml b/tests/test_project/expected_xml/Test!.tagfile.xml index 6078b2c..d2b7a0e 100644 --- a/tests/test_project/expected_xml/Test!.tagfile.xml +++ b/tests/test_project/expected_xml/Test!.tagfile.xml @@ -1,5 +1,5 @@ - + code.h code_8h.html