From 75aa007fe4c7adc4ed4829067dac32b480ecd47e Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Wed, 14 Aug 2024 23:39:56 +0200 Subject: [PATCH 1/3] Move script and templates from mysql --- docca_asciidoc.py | 174 ++++++++++++++++++++ include/docca/asciidoc/class.jinja2 | 148 +++++++++++++++++ include/docca/asciidoc/common.jinja2 | 182 +++++++++++++++++++++ include/docca/asciidoc/enum.jinja2 | 34 ++++ include/docca/asciidoc/overload-set.jinja2 | 80 +++++++++ include/docca/asciidoc/quickref.jinja2 | 47 ++++++ include/docca/asciidoc/type-alias.jinja2 | 17 ++ include/docca/asciidoc/variable.jinja2 | 34 ++++ 8 files changed, 716 insertions(+) create mode 100644 docca_asciidoc.py create mode 100644 include/docca/asciidoc/class.jinja2 create mode 100644 include/docca/asciidoc/common.jinja2 create mode 100644 include/docca/asciidoc/enum.jinja2 create mode 100644 include/docca/asciidoc/overload-set.jinja2 create mode 100644 include/docca/asciidoc/quickref.jinja2 create mode 100644 include/docca/asciidoc/type-alias.jinja2 create mode 100644 include/docca/asciidoc/variable.jinja2 diff --git a/docca_asciidoc.py b/docca_asciidoc.py new file mode 100644 index 0000000..2ab564f --- /dev/null +++ b/docca_asciidoc.py @@ -0,0 +1,174 @@ +import sys +import os + +sys.path.append(os.path.abspath(os.path.dirname(__file__))) + +import argparse +import jinja2 +from typing import List +from docca import ( + AcceptOneorNone, + open_input, + collect_compound_refs, + collect_data, + load_configs, + construct_environment, + Class, + Namespace, + Access, + Compound, + OverloadSet, + TypeAlias, + Enum, + Variable, + Entity, + Type, + FunctionKind +) + +DEFAULT_TPLT_DIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'include/docca/asciidoc')) + +def parse_args(args): + parser = argparse.ArgumentParser( + prog=args[0], + description='Produces API reference in QuickBook markup') + parser.add_argument( + '-i', + '--input', + action=AcceptOneorNone, + help='Doxygen XML index file; STDIN by default') + parser.add_argument( + '-o', + '--output', + action=AcceptOneorNone, + help='Output file; STDOUT by default') + parser.add_argument( + '-c', '--config', + action='append', + default=[], + help='Configuration files') + parser.add_argument( + '-T', '--template', + action=AcceptOneorNone, + help='Jinja2 template to use for output') + parser.add_argument( + '-I', '--include', + action='append', + default=[], + help='Directory with template partials') + parser.add_argument( + '-D', '--directory', + action=AcceptOneorNone, + help=( + 'Directory with additional data files; ' + 'by default INPUT parent directory if that is provided, ' + 'otherwise PWD')) + return parser.parse_args(args[1:]) + +def render(env: jinja2.Environment, template_file: str, output_dir: str, output_file: str, **kwargs): + output_path = os.path.join(output_dir, output_file) + template = env.get_template(template_file) + os.makedirs(os.path.dirname(output_path), exist_ok=True) + with open(output_path, 'wt', encoding='utf-8') as f: + template.stream(**kwargs).dump(f) + + +def render_entities(env: jinja2.Environment, template_file: str, output_dir: str, entities): + for e in entities: + print(f'Rendering {e}') + render(env, template_file, output_dir, asciidoc_file(e), entity=e) + + +def _sanitize_path_segment(s: str) -> str: + return s.replace("[", "-lb") \ + .replace("]", "-rb")\ + .replace("(", "-lp")\ + .replace(")", "-rp")\ + .replace("<=>", "-spshp")\ + .replace("->", "-arrow")\ + .replace("operator>", "operator-gt")\ + .replace("operator~", "operator-bnot")\ + .replace("=", "-eq")\ + .replace("!", "-not")\ + .replace("+", "-plus")\ + .replace("&", "-and")\ + .replace("|", "-or")\ + .replace("^", "-xor")\ + .replace("*", "-star")\ + .replace("/", "-slash")\ + .replace("%", "-mod")\ + .replace("<", "-lt")\ + .replace(">", "-gt")\ + .replace("~", "dtor-")\ + .replace(",", "-comma")\ + .replace(":", "-")\ + .replace(" ", "-") + + +def asciidoc_file(e: Entity) -> str: + file_path = '/'.join(_sanitize_path_segment(elm.name) for elm in e.path) + return f'{file_path}.adoc' + + +def main(): + args = parse_args(sys.argv) + + file, ctx, data_dir = open_input(sys.stdin, args, os.getcwd()) + with ctx: + refs = list(collect_compound_refs(file)) + data = collect_data(data_dir, refs) + + output_dir: str = args.output + + config = load_configs(args) + + env = construct_environment( + jinja2.FileSystemLoader(DEFAULT_TPLT_DIR), config) + env.filters['adocfile'] = asciidoc_file + + # Namespaces (not rendered directly) + namespaces = [e for e in data.values() if isinstance(e, Namespace)] + + # Classes (including member types) + classes = [e for e in data.values() + if isinstance(e, Class) and e.access == Access.public and + not e.is_specialization] + render_entities(env, 'class.jinja2', output_dir, classes) + + # Functions + fns = [] + for e in [e2 for e2 in data.values() if isinstance(e2, Compound)]: + fns += [mem for mem in e.members.values() if isinstance(mem, OverloadSet) and mem.access == Access.public] + render_entities(env, 'overload-set.jinja2', output_dir, fns) + + # Type aliases + type_alias = [e for e in data.values() if isinstance(e, TypeAlias)] + render_entities(env, 'type-alias.jinja2', output_dir, type_alias) + + # Enums + enums = [e for e in data.values() if isinstance(e, Enum)] + render_entities(env, 'enum.jinja2', output_dir, enums) + + # Constants + constants = [] + for ns in namespaces: + constants += [e for e in ns.members.values() if isinstance(e, Variable)] + render_entities(env, 'variable.jinja2', output_dir, constants) + + # Quickref + render( + env, + 'quickref.jinja2', + output_dir, + 'reference.adoc', + classes=classes, + enums=enums, + free_functions=[e for e in fns if isinstance(e.scope, Namespace)], + type_aliases=[e for e in type_alias if isinstance(e.scope, Namespace)], + constants=constants + ) + + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/include/docca/asciidoc/class.jinja2 b/include/docca/asciidoc/class.jinja2 new file mode 100644 index 0000000..b9dba91 --- /dev/null +++ b/include/docca/asciidoc/class.jinja2 @@ -0,0 +1,148 @@ +{% from "common.jinja2" import description, link, template_parameters, phrase, header_file %} + +== {{ entity.fully_qualified_name }} + + +{{ header_file(entity) }} + +{{ description(entity.brief) }} + +[source, cpp, subs="+macros", role="raw-code"] +---- +{{ template_parameters(entity) }} +{{ entity.declarator }} {{ entity.name }} +{%- for entry in entity.bases -%} + {% if loop.first %}:{% else %},{% endif -%} + {{ ' ' ~ entry.access ~ ' ' }} + {%- if entry.is_virtual %}virtual {% endif -%} + {{ phrase(entry.base, in_code=True) }} +{%- endfor -%} +; +---- + +{{ description(entity.description) }} + +{% for type in entity.members.values() + | select("Type") + | selectattr("access", "eq", Access.public) %} +{% if loop.first %} +=== Member types + +[cols="1,2", grid=rows, frame=none, role="mt-0"] +|=== +{% endif %} +.^|{{ link(type, '[link-to-entity bg-white]`' + type.name + '`') }} +.^|{{ description(type.brief) }} + +{% if loop.last %} +|=== +{% endif %} + +{%- endfor -%} + + +{% for fn in entity.members.values() + | select("OverloadSet") + | selectattr("access", "eq", Access.public) + | selectattr("kind", "eq", FunctionKind.nonstatic) %} +{% if loop.first %} +=== Member functions + +[cols="1,2", grid=rows, frame=none, role="mt-0"] +|=== +{% endif %} +.^|{{ link(fn, '[link-to-entity bg-white]`' + fn.name + '`') }} +.^|{{ description(fn.brief[0]) }} + +{% if loop.last %} +|=== +{% endif %} + +{%- endfor -%} + + + +{% for fn in entity.members.values() + | select("OverloadSet") + | selectattr("access", "eq", Access.public) + | selectattr("kind", "eq", FunctionKind.static) %} +{% if loop.first %} +=== Static functions + +[cols="1,2", grid=rows, frame=none, role="mt-0"] +|=== +{% endif %} +.^|{{ link(fn, '[link-to-entity bg-white]`' + fn.name + '`') }} +.^|{{ description(fn.brief[0]) }} + +{% if loop.last %} +|=== +{% endif %} +{%- endfor -%} + + + +{% for mem in entity.members.values() + | select("Variable") + | selectattr("access", "eq", Access.public) + | selectattr("is_static", "eq", False) %} + +{% if loop.first %} +=== Data members + +[cols="1", grid=none, frame=none, role="mt-0 space-rows"] +|=== +{% endif %} +.^a| +[source, cpp, subs="+macros", id={{ mem.name }}] +---- +{{ phrase(mem.type) }} {{ mem.name }}{%- if mem.value %} {{ phrase(mem.value) }} {%- endif -%}; +---- + + +{{ description(mem.brief) }} + +{{ description(mem.description) }} + +{% if loop.last %} +|=== +{% endif %} +{%- endfor -%} + + +{# TODO: this is duplicate #} +{% for mem in entity.members.values() + | select("Variable") + | selectattr("access", "eq", Access.public) + | selectattr("is_static", "eq", True) %} + +{% if loop.first %} +=== Static data members + +[cols="1", grid=none, frame=none, role="mt-0 space-rows"] +|=== +{% endif %} +.^a| +[source, cpp, subs="+macros", id={{ mem.name }}] +---- +{{ template_parameters(mem) }} +{%- set qualifiers = ['static'] -%} +{%- if mem.is_constexpr -%} + {%- set qualifiers = qualifiers + ['constexpr'] -%} +{%- endif -%} +{%- if mem.is_inline -%} + {%- set qualifiers = qualifiers + ['inline'] -%} +{%- endif -%} + +{{ qualifiers | join(' ') }} {{ phrase(mem.type) }} {{ mem.name }}{%- if mem.value %} {{ phrase(mem.value) }} {%- endif -%}; +---- + + +{{ description(mem.brief) }} + +{{ description(mem.description) }} + +{% if loop.last %} +|=== +{% endif %} +{%- endfor -%} \ No newline at end of file diff --git a/include/docca/asciidoc/common.jinja2 b/include/docca/asciidoc/common.jinja2 new file mode 100644 index 0000000..a367e0f --- /dev/null +++ b/include/docca/asciidoc/common.jinja2 @@ -0,0 +1,182 @@ +{% macro escape(s) -%} + {{ s.replace("[", "\\[").replace("]", "\\]") }} +{%- endmacro %} + +{%- macro header_file(e) -%} + Defined in header [link-to-entity bg-white]`` +{%- endmacro -%} + + +{% macro subsection(sub) -%} +{% if sub.title %} + +=== {{ phrase(sub.title) }} +{% elif sub.kind %} + +=== {%- if sub.kind == 'see' %} See Also + {%- elif sub.kind == 'return' %} Return Value + {%- elif sub.kind == 'author' %} Author + {%- elif sub.kind == 'authors' %} Authors + {%- elif sub.kind == 'version' %} Version + {%- elif sub.kind == 'since' %} Since + {%- elif sub.kind == 'date' %} Date + {%- elif sub.kind == 'note' %} Remarks + {%- elif sub.kind == 'warning' %} Warning + {%- elif sub.kind == 'pre' %} Preconditions + {%- elif sub.kind == 'post' %} Postconditions + {%- elif sub.kind == 'copyright' %} Copyright + {%- elif sub.kind == 'invariant' %} Invariants + {%- elif sub.kind == 'remark' %} Remarks + {%- elif sub.kind == 'attention' %} Attention + {%- elif sub.kind == 'par' %} Paragraph + {%- elif sub.kind == 'rcs'%} RCS + {%- else %} Unknown + {%- endif -%} +{%- endif %} +{{ description(sub) }} +{%- endmacro %} + +{% macro link(entity, text) -%} + {%- if entity is Enumerator -%} + {{ link(entity.enum, text) }} + {%- elif entity is Variable and entity.scope is Class -%} + xref:{{ entity.scope | adocfile }}#{{ entity.name }}[{{ text }}] + {%- else -%} + xref:{{ entity | adocfile }}[{{ text }}] + {%- endif -%} +{%- endmacro %} + +{%- macro itemised(lst, nesting='') -%} + {%- for item in lst -%} + {{ nesting }} + {%- if lst.is_ordered -%} + # + {%- else -%} + * + {%- endif %} {{ description(item, nesting + ' ') }} + {%- endfor -%} +{%- endmacro %} + + +{% macro text_helper(s, in_code=False) -%} + {%- if s -%} + {%- set replacements=Config.get('replace_strings', {}) -%} + + {%- set ns = namespace(s=s) -%} + {%- if in_code -%} + {%- set ns.s = ns.s | replace(" ", " ") + | replace(" ", " ") + | replace(" ", " ") + | replace(" ", " ") + -%} + {%- if ns.s.endswith(" &") -%} + {%- set ns.s = ns.s[:-2] + "&" -%} + {%- elif ns.s.endswith(" *") -%} + {%- set ns.s = ns.s[:-2] + "*" -%} + {%- elif ns.s.endswith(" &&") -%} + {%- set ns.s = ns.s[:-3] + "&&" -%} + {%- elif ns.s.endswith(" &...") -%} + {%- set ns.s = ns.s[:-5] + "&..." -%} + {%- elif ns.s.endswith(" *...") -%} + {%- set ns.s = ns.s[:-5] + "*..." -%} + {%- elif ns.s.endswith(" &&...") -%} + {%- set ns.s = ns.s[:-6] + "&&..." -%} + {%- endif -%} + {%- else -%} + {%- set ns.s = escape(s) -%} + {%- endif -%} + {%- for src, tgt in replacements.items() -%} + {%- set ns.s = ns.s.replace(src, tgt) -%} + {%- endfor -%} + {{ ns.s }} + {%- else -%} + {{ s }} + {%- endif -%} +{%- endmacro %} + + + + +{% macro phrase(para, in_code=False) -%} +{%- for part in para -%}{{ phrase_part(part, in_code=in_code) }}{%- endfor -%} +{%- endmacro %} + +{% macro phrase_part(part, in_code=False) -%} + {%- if part is string -%} + {{ text_helper(part, in_code=in_code) }} + {%- elif part is Monospaced -%} + `+++{{ phrase(part, in_code=True) }}+++` + {%- elif part is Emphasised -%} + _{{ phrase(part, in_code=in_code) }}_ + {%- elif part is Strong -%} + *{{ phrase(part, in_code=in_code) }}* + {%- elif part is EntityRef -%} + {# Qualify only entities that are not in a namespace #} + {%- if part.entity.scope is Namespace -%} + {{ link(part.entity, part.entity.name) }} + {%- else -%} + {{ link(part.entity, part.entity.scope.name + '::' + part.entity.name) }} + {%- endif -%} + {%- elif part is UrlLink -%} + {{ part.url }}:[{{ phrase(part, in_code=in_code) }}] + {%- elif part is Linebreak %}{# indent is intentional here #} + +{% elif part is Phrase -%} + {{ phrase(part, in_code=in_code) }} + {%- else -%} + {{ part.unhandled_type() }} + {%- endif -%} +{%- endmacro %} + +{% macro description(parts, nesting='') -%} + +{%- for part in parts -%} + +{%- if part is Paragraph -%} +{{ phrase(part) }} +{% elif part is List -%} +{{ itemised(part, nesting) }} +{%- elif part is Section -%} +{{ subsection(part) }} +{%- elif part is CodeBlock %} +{{ nesting }}``` +{% for line in part -%} +{{nesting}}{{line}} +{% endfor -%} +{{ nesting }}``` +{% elif part is ParameterList -%} +{# {{ parameter_list(part) }} #} +{% elif part is Table -%} +{{ table(part) }} +{%- else -%} +{{ part.unhandled_type() }} +{%- endif -%} + +{%- endfor -%} + +{%- endmacro %} + +{%- macro template_parameters(entity) -%} +{%- if entity.template_parameters or entity.is_specialization -%}template<{%- endif -%} +{%- for tparam in entity.template_parameters %} + {{ phrase(tparam.type, in_code=True) }} + {%- if tparam.array %} (&{% endif -%} + {%- if tparam.name -%} + {%- if not tparam.array %} {% endif -%} + {{ tparam.name }} + {%- endif -%} + {%- if tparam.array %}) {{ phrase(tparam.array, in_code=True) }}{% endif -%} + {%- if tparam.default_value %} = {{ phrase(tparam.default_value, in_code=True) }}{% endif -%} + +{%- if loop.last -%} +> +{%- else -%} +, +{%- endif -%} + +{%- else -%} +{%- if entity.is_specialization -%} +> +{%- endif -%} +{%- endfor %} +{%- endmacro %} \ No newline at end of file diff --git a/include/docca/asciidoc/enum.jinja2 b/include/docca/asciidoc/enum.jinja2 new file mode 100644 index 0000000..6d21b0a --- /dev/null +++ b/include/docca/asciidoc/enum.jinja2 @@ -0,0 +1,34 @@ +{% from "common.jinja2" import phrase, template_parameters, description, header_file %} + +== {{ entity.fully_qualified_name }} + + +{{ header_file(entity) }} + +[source, cpp, subs="+macros", role="raw-code"] +---- +{{ entity.declarator }} {{ entity.name }} +{%- if entity.underlying_type -%} +: {{ phrase(entity.underlying_type) }} +{%- endif -%}; +---- + +{{ description(entity.brief) }} + +{{ description(entity.description) }} + +{% for enum in entity.objects %} +{% if loop.first %} +=== Enumerators + +[cols="1,2", grid=rows, frame=none, role="mt-0"] +|=== +{% endif %} +.^|[link-to-entity bg-white]`{{ enum.name }}` +.^|{{ description(enum.brief) }} {{ description(enum.description) }} + +{% if loop.last %} +|=== +{% endif %} + +{% endfor %} \ No newline at end of file diff --git a/include/docca/asciidoc/overload-set.jinja2 b/include/docca/asciidoc/overload-set.jinja2 new file mode 100644 index 0000000..ff0df65 --- /dev/null +++ b/include/docca/asciidoc/overload-set.jinja2 @@ -0,0 +1,80 @@ + +{%- from "common.jinja2" import template_parameters, description, phrase -%} + +== {{ entity.fully_qualified_name }} + + +[cols="8,1", grid=rows, frame=none, role="mt-0"] +|=== + +{% for fn in entity %} + +a| +[source, cpp, subs="+macros", role="raw-code"] +---- +{{ template_parameters(fn) }} +{%- set qualifiers = [] -%} +{%- if fn.is_explicit -%} + {%- set qualifiers = qualifiers + ['explicit'] -%} +{%- endif -%} +{%- if fn.is_static -%} + {%- set qualifiers = qualifiers + ['static'] -%} +{%- endif -%} +{%- if fn.is_constexpr -%} + {%- set qualifiers = qualifiers + ['constexpr'] -%} +{%- endif -%} + +{%- if qualifiers | length -%} + {{ qualifiers | join(' ') }}{{' '}} +{%- endif -%} +{{ phrase(fn.return_type, in_code=True) }} +{{ fn.name }}( +{%- for param in fn.parameters %} + {{ phrase(param.type, in_code=True) }} + {%- if param.array %} (&{% endif -%} + {%- if param.name -%} + {%- if not param.array %} {% endif -%} + {{ param.name }} + {%- endif -%} + {%- if param.array %}) {{ phrase(param.array, in_code=True) }}{% endif -%} + {%- if param.default_value %} = {{ phrase(param.default_value, in_code=True) }}{% endif -%} + + {%- if not loop.last %},{% endif -%} +{%- endfor -%} +) +{%- if fn.refqual or fn.is_const -%} + {{ " " }} + {%- if fn.is_const %}const{% endif -%} + {%- if "lvalue" == fn.refqual %}& + {%- elif "rvalue" == fn.refqual %}&& + {%- endif -%} +{%- endif -%} +{%- if fn.is_noexcept and not fn.is_destructor %} noexcept{% endif -%} +{%- if not fn.is_noexcept and fn.is_destructor %} noexcept(false){% endif -%} +{%- if fn.is_deleted %} = delete +{%- elif fn.is_defaulted %} = default +{%- endif -%} +; +---- + +.^| {%- if entity | length > 1 -%} ({{ loop.index }}) {%- endif -%} + +{% endfor %} + +|=== + +{{ description(entity.brief[0]) }} + +{{ description(entity.description) }} + +{%- if entity | length > 1 -%} +[cols="1,8", grid=rows, frame=none, role="mt-0"] +|=== +{% for fn in entity -%} + {%- if fn.overload_specific | length -%} + .^|({{ loop.index }}) + |{{ description(fn.overload_specific) }} + {%- endif -%} +{%- endfor %} +|=== +{%- endif -%} diff --git a/include/docca/asciidoc/quickref.jinja2 b/include/docca/asciidoc/quickref.jinja2 new file mode 100644 index 0000000..53b6183 --- /dev/null +++ b/include/docca/asciidoc/quickref.jinja2 @@ -0,0 +1,47 @@ + +{% from "common.jinja2" import link %} + +{% macro reflink(entity) %} +[.m-0] +{{ link(entity, '[link-to-entity bg-white]`' + entity.name + '`') }} +{% endmacro %} + +[#reference] += Reference +:role: quickref + +[cols="1,1"] +|=== + +a| [.pb-1]*Classes* + +{% for e in classes | sort -%} +{{ reflink(e) }} +{%- endfor %} + +a| [.pb-1]*Enumerations* + +{% for e in enums | sort -%} +{{ reflink(e) }} +{%- endfor %} + +[.pb-1]*Functions* + +{% for e in free_functions | sort -%} +{{ reflink(e) }} +{%- endfor %} + +[.pb-1]*Type aliases* + +{% for e in type_aliases | sort -%} +{{ reflink(e) }} +{%- endfor %} + +[.pb-1]*Constants* + +{% for e in constants | sort -%} +{{ reflink(e) }} +{%- endfor %} + +|=== + diff --git a/include/docca/asciidoc/type-alias.jinja2 b/include/docca/asciidoc/type-alias.jinja2 new file mode 100644 index 0000000..d99ac79 --- /dev/null +++ b/include/docca/asciidoc/type-alias.jinja2 @@ -0,0 +1,17 @@ +{% from "common.jinja2" import phrase, template_parameters, description, header_file %} + +== {{ entity.fully_qualified_name }} + + +{{ header_file(entity) }} + +[source, cpp, subs="+macros", role="raw-code"] +---- +{{ template_parameters(entity) }} +{{ entity.declarator }} {{ entity.name }} = {{ phrase(entity.aliased) }}; +---- + +{{ description(entity.brief) }} + +{{ description(entity.description) }} + diff --git a/include/docca/asciidoc/variable.jinja2 b/include/docca/asciidoc/variable.jinja2 new file mode 100644 index 0000000..f99843b --- /dev/null +++ b/include/docca/asciidoc/variable.jinja2 @@ -0,0 +1,34 @@ +{% from "common.jinja2" import phrase, template_parameters, description, header_file %} + +== {{ entity.fully_qualified_name }} + + +{{ header_file(entity) }} + +[source, cpp, subs="+macros", role="raw-code"] +---- +{{ template_parameters(entity) }} +{%- set qualifiers = [] -%} +{%- if entity.is_static -%} + {%- set qualifiers = qualifiers + ['static'] -%} +{%- endif -%} +{%- if entity.is_constexpr -%} + {%- set qualifiers = qualifiers + ['constexpr'] -%} +{%- endif -%} +{%- if entity.is_inline -%} + {%- set qualifiers = qualifiers + ['inline'] -%} +{%- endif -%} + +{%- if qualifiers | length -%} + {{ qualifiers | join(' ') }}{{' '}} +{%- endif -%} + +{{ phrase(entity.type) }} {{ entity.name }} +{%- if entity.value %} {{ phrase(entity.value) }}{% endif -%} +; +---- + +{{ description(entity.brief) }} + +{{ description(entity.description) }} + From bdab2a865fca4e46ab17a4f2faa10ebd84574274 Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Wed, 14 Aug 2024 23:54:09 +0200 Subject: [PATCH 2/3] nowrap for code --- include/docca/asciidoc/common.jinja2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/docca/asciidoc/common.jinja2 b/include/docca/asciidoc/common.jinja2 index a367e0f..ddeb151 100644 --- a/include/docca/asciidoc/common.jinja2 +++ b/include/docca/asciidoc/common.jinja2 @@ -105,7 +105,7 @@ {%- if part is string -%} {{ text_helper(part, in_code=in_code) }} {%- elif part is Monospaced -%} - `+++{{ phrase(part, in_code=True) }}+++` + [.whitespace-nowrap]`+++{{ phrase(part, in_code=True) }}+++` {%- elif part is Emphasised -%} _{{ phrase(part, in_code=in_code) }}_ {%- elif part is Strong -%} From 71eafff4a450e9b511f1a3cfba0b45b7de74e770 Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Wed, 14 Aug 2024 23:54:48 +0200 Subject: [PATCH 3/3] temporary: overload-specific descriptions --- docca.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docca.py b/docca.py index 4b5369a..b0447e1 100755 --- a/docca.py +++ b/docca.py @@ -546,6 +546,10 @@ def __init__(self, element, scope, index=dict()): self.index = index index[self.id] = self + def __repr__(self) -> str: + return f'{type(self).__name__}({self.fully_qualified_name})' + + @property def location(self): return ( @@ -895,6 +899,20 @@ def overload_index(self): return -1 def resolve_references(self): + assert self._description is not None + node = self._description.find('.//xrefsect/..') + if node is not None: + subnode = node.find('xrefsect') + assert subnode is not None + xreftitle = subnode.find('xreftitle') + assert xreftitle is not None + assert xreftitle.text == 'overload_specific' + xrefdescription = subnode.find('xrefdescription') + assert xrefdescription is not None + self.overload_specific = make_blocks(xrefdescription, self.index) + node.remove(subnode) + else: + self.overload_specific = [] super().resolve_references() self.return_type = resolve_type(self._return_type, self.index) @@ -964,6 +982,9 @@ def __init__(self, funcs): self.funcs = funcs assert len(funcs) self._resort() + + def __repr__(self) -> str: + return f'OverloadSet({self.fully_qualified_name})' def append(self, func): self.funcs.append(func)