oodocs 1.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oodocs/__init__.py +294 -0
- oodocs/__main__.py +9 -0
- oodocs/cli.py +191 -0
- oodocs/compatibility.py +102 -0
- oodocs/components/__init__.py +106 -0
- oodocs/components/base.py +116 -0
- oodocs/components/blocks.py +1181 -0
- oodocs/components/equations.py +271 -0
- oodocs/components/generated.py +267 -0
- oodocs/components/inline.py +909 -0
- oodocs/components/markup.py +396 -0
- oodocs/components/media.py +1105 -0
- oodocs/components/people.py +221 -0
- oodocs/components/positioning.py +430 -0
- oodocs/components/references.py +535 -0
- oodocs/core.py +189 -0
- oodocs/document.py +293 -0
- oodocs/importers/__init__.py +18 -0
- oodocs/importers/markdown.py +745 -0
- oodocs/importers/notebook.py +380 -0
- oodocs/layout/__init__.py +35 -0
- oodocs/layout/indexing.py +580 -0
- oodocs/layout/theme.py +991 -0
- oodocs/presets/__init__.py +25 -0
- oodocs/presets/components.py +228 -0
- oodocs/presets/templates.py +203 -0
- oodocs/renderers/__init__.py +7 -0
- oodocs/renderers/context.py +45 -0
- oodocs/renderers/docx.py +3192 -0
- oodocs/renderers/html.py +2305 -0
- oodocs/renderers/pdf.py +3084 -0
- oodocs/renderers/syntax.py +107 -0
- oodocs/settings.py +335 -0
- oodocs/validation.py +1025 -0
- oodocs/workflows.py +296 -0
- oodocs-1.0.1.dist-info/METADATA +354 -0
- oodocs-1.0.1.dist-info/RECORD +41 -0
- oodocs-1.0.1.dist-info/WHEEL +5 -0
- oodocs-1.0.1.dist-info/entry_points.txt +2 -0
- oodocs-1.0.1.dist-info/licenses/LICENSE +21 -0
- oodocs-1.0.1.dist-info/top_level.txt +1 -0
oodocs/__init__.py
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"""Top-level package for oodocs."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version as package_version
|
|
4
|
+
|
|
5
|
+
from oodocs.core import OODocsError
|
|
6
|
+
from oodocs.compatibility import OUTPUT_FORMATS, OutputFormat
|
|
7
|
+
from oodocs.components.blocks import (
|
|
8
|
+
Assumption,
|
|
9
|
+
Axiom,
|
|
10
|
+
Box,
|
|
11
|
+
BulletList,
|
|
12
|
+
Chapter,
|
|
13
|
+
Claim,
|
|
14
|
+
CodeBlock,
|
|
15
|
+
ColumnSpan,
|
|
16
|
+
Conjecture,
|
|
17
|
+
CountableBlock,
|
|
18
|
+
Corollary,
|
|
19
|
+
Definition,
|
|
20
|
+
Divider,
|
|
21
|
+
Equation,
|
|
22
|
+
Example,
|
|
23
|
+
MAX_SECTION_LEVEL,
|
|
24
|
+
MIN_SECTION_LEVEL,
|
|
25
|
+
Lemma,
|
|
26
|
+
MultiColumn,
|
|
27
|
+
NumberedList,
|
|
28
|
+
PageBreak,
|
|
29
|
+
Paragraph,
|
|
30
|
+
Part,
|
|
31
|
+
Proof,
|
|
32
|
+
Proposition,
|
|
33
|
+
Remark,
|
|
34
|
+
Section,
|
|
35
|
+
Subsection,
|
|
36
|
+
Subsubsection,
|
|
37
|
+
Theorem,
|
|
38
|
+
VerticalSpace,
|
|
39
|
+
countable_kind,
|
|
40
|
+
section_for_level,
|
|
41
|
+
shift_heading_level,
|
|
42
|
+
shift_heading_levels,
|
|
43
|
+
)
|
|
44
|
+
from oodocs.components.generated import (
|
|
45
|
+
CommentsPage,
|
|
46
|
+
FigureList,
|
|
47
|
+
ReferencesPage,
|
|
48
|
+
TableList,
|
|
49
|
+
TableOfContents,
|
|
50
|
+
TocLevelStyle,
|
|
51
|
+
)
|
|
52
|
+
from oodocs.components.media import (
|
|
53
|
+
Figure,
|
|
54
|
+
ImageData,
|
|
55
|
+
SubFigure,
|
|
56
|
+
SubFigureGroup,
|
|
57
|
+
Table,
|
|
58
|
+
TableCell,
|
|
59
|
+
TableCellStyle,
|
|
60
|
+
)
|
|
61
|
+
from oodocs.components.markup import markup
|
|
62
|
+
from oodocs.components.people import Affiliation, Author, AuthorLayout
|
|
63
|
+
from oodocs.components.references import CitationLibrary, CitationSource
|
|
64
|
+
from oodocs.components.positioning import ImageBox, Shape, TextBox
|
|
65
|
+
from oodocs.document import Document
|
|
66
|
+
from oodocs.importers.markdown import (
|
|
67
|
+
from_markdown,
|
|
68
|
+
from_markdown_file,
|
|
69
|
+
parse_markdown,
|
|
70
|
+
parse_markdown_file,
|
|
71
|
+
)
|
|
72
|
+
from oodocs.importers.notebook import (
|
|
73
|
+
from_ipynb,
|
|
74
|
+
from_notebook,
|
|
75
|
+
parse_ipynb,
|
|
76
|
+
parse_notebook,
|
|
77
|
+
)
|
|
78
|
+
from oodocs.components.inline import (
|
|
79
|
+
Comment,
|
|
80
|
+
Footnote,
|
|
81
|
+
InlineChip,
|
|
82
|
+
InlineChipStyle,
|
|
83
|
+
LineBreak,
|
|
84
|
+
Math,
|
|
85
|
+
Text,
|
|
86
|
+
badge,
|
|
87
|
+
bold,
|
|
88
|
+
code,
|
|
89
|
+
color,
|
|
90
|
+
cite,
|
|
91
|
+
comment,
|
|
92
|
+
footnote,
|
|
93
|
+
highlight,
|
|
94
|
+
italic,
|
|
95
|
+
keyboard,
|
|
96
|
+
link,
|
|
97
|
+
line_break,
|
|
98
|
+
math,
|
|
99
|
+
prescript,
|
|
100
|
+
reference,
|
|
101
|
+
status,
|
|
102
|
+
strike,
|
|
103
|
+
strikethrough,
|
|
104
|
+
styled,
|
|
105
|
+
subscript,
|
|
106
|
+
superscript,
|
|
107
|
+
tag,
|
|
108
|
+
)
|
|
109
|
+
from oodocs.settings import (
|
|
110
|
+
BlockOptions,
|
|
111
|
+
BoxStyle,
|
|
112
|
+
CaptionOptions,
|
|
113
|
+
CitationOptions,
|
|
114
|
+
DocumentSettings,
|
|
115
|
+
GeneratedPageOptions,
|
|
116
|
+
HeadingNumbering,
|
|
117
|
+
ListStyle,
|
|
118
|
+
PageNumberOptions,
|
|
119
|
+
PageMargins,
|
|
120
|
+
PageSize,
|
|
121
|
+
ParagraphStyle,
|
|
122
|
+
TableStyle,
|
|
123
|
+
TextStyle,
|
|
124
|
+
TitleMatterOptions,
|
|
125
|
+
TypographyOptions,
|
|
126
|
+
Theme,
|
|
127
|
+
)
|
|
128
|
+
from oodocs.validation import DocumentValidationError, ValidationIssue, ValidationResult
|
|
129
|
+
from oodocs.workflows import (
|
|
130
|
+
RenderedOutputs,
|
|
131
|
+
build_python_document,
|
|
132
|
+
convert_source,
|
|
133
|
+
load_document,
|
|
134
|
+
load_python_document,
|
|
135
|
+
render_document,
|
|
136
|
+
validate_source,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
_FALLBACK_VERSION = "1.0.1"
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _resolve_version() -> str:
|
|
144
|
+
try:
|
|
145
|
+
return package_version("oodocs")
|
|
146
|
+
except PackageNotFoundError:
|
|
147
|
+
try:
|
|
148
|
+
from setuptools_scm import get_version
|
|
149
|
+
except ImportError:
|
|
150
|
+
return _FALLBACK_VERSION
|
|
151
|
+
return get_version(
|
|
152
|
+
root="../..",
|
|
153
|
+
relative_to=__file__,
|
|
154
|
+
fallback_version=_FALLBACK_VERSION,
|
|
155
|
+
tag_regex=r"^v(?P<version>\d+\.\d+\.\d+)$",
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
__version__ = _resolve_version()
|
|
160
|
+
|
|
161
|
+
__all__ = [
|
|
162
|
+
"Affiliation",
|
|
163
|
+
"Assumption",
|
|
164
|
+
"Author",
|
|
165
|
+
"AuthorLayout",
|
|
166
|
+
"Axiom",
|
|
167
|
+
"BlockOptions",
|
|
168
|
+
"Box",
|
|
169
|
+
"BoxStyle",
|
|
170
|
+
"BulletList",
|
|
171
|
+
"CaptionOptions",
|
|
172
|
+
"CitationOptions",
|
|
173
|
+
"CitationLibrary",
|
|
174
|
+
"CitationSource",
|
|
175
|
+
"Chapter",
|
|
176
|
+
"Claim",
|
|
177
|
+
"Comment",
|
|
178
|
+
"CommentsPage",
|
|
179
|
+
"CodeBlock",
|
|
180
|
+
"ColumnSpan",
|
|
181
|
+
"Conjecture",
|
|
182
|
+
"CountableBlock",
|
|
183
|
+
"Corollary",
|
|
184
|
+
"Definition",
|
|
185
|
+
"Document",
|
|
186
|
+
"DocumentSettings",
|
|
187
|
+
"OODocsError",
|
|
188
|
+
"Divider",
|
|
189
|
+
"Equation",
|
|
190
|
+
"Example",
|
|
191
|
+
"Figure",
|
|
192
|
+
"FigureList",
|
|
193
|
+
"Footnote",
|
|
194
|
+
"GeneratedPageOptions",
|
|
195
|
+
"HeadingNumbering",
|
|
196
|
+
"ImageBox",
|
|
197
|
+
"ImageData",
|
|
198
|
+
"InlineChip",
|
|
199
|
+
"InlineChipStyle",
|
|
200
|
+
"LineBreak",
|
|
201
|
+
"ListStyle",
|
|
202
|
+
"Lemma",
|
|
203
|
+
"Math",
|
|
204
|
+
"MAX_SECTION_LEVEL",
|
|
205
|
+
"MIN_SECTION_LEVEL",
|
|
206
|
+
"MultiColumn",
|
|
207
|
+
"NumberedList",
|
|
208
|
+
"OUTPUT_FORMATS",
|
|
209
|
+
"OutputFormat",
|
|
210
|
+
"PageNumberOptions",
|
|
211
|
+
"PageMargins",
|
|
212
|
+
"PageSize",
|
|
213
|
+
"PageBreak",
|
|
214
|
+
"Paragraph",
|
|
215
|
+
"Part",
|
|
216
|
+
"Proof",
|
|
217
|
+
"Proposition",
|
|
218
|
+
"ParagraphStyle",
|
|
219
|
+
"ReferencesPage",
|
|
220
|
+
"RenderedOutputs",
|
|
221
|
+
"Remark",
|
|
222
|
+
"Section",
|
|
223
|
+
"Shape",
|
|
224
|
+
"SubFigure",
|
|
225
|
+
"SubFigureGroup",
|
|
226
|
+
"Subsection",
|
|
227
|
+
"Subsubsection",
|
|
228
|
+
"Table",
|
|
229
|
+
"TableCell",
|
|
230
|
+
"TableCellStyle",
|
|
231
|
+
"TableStyle",
|
|
232
|
+
"TableOfContents",
|
|
233
|
+
"TableList",
|
|
234
|
+
"Text",
|
|
235
|
+
"TextBox",
|
|
236
|
+
"TextStyle",
|
|
237
|
+
"Theorem",
|
|
238
|
+
"TitleMatterOptions",
|
|
239
|
+
"Theme",
|
|
240
|
+
"TocLevelStyle",
|
|
241
|
+
"TypographyOptions",
|
|
242
|
+
"DocumentValidationError",
|
|
243
|
+
"ValidationIssue",
|
|
244
|
+
"ValidationResult",
|
|
245
|
+
"VerticalSpace",
|
|
246
|
+
"__version__",
|
|
247
|
+
"badge",
|
|
248
|
+
"bold",
|
|
249
|
+
"build_python_document",
|
|
250
|
+
"code",
|
|
251
|
+
"color",
|
|
252
|
+
"cite",
|
|
253
|
+
"comment",
|
|
254
|
+
"countable_kind",
|
|
255
|
+
"convert_source",
|
|
256
|
+
"footnote",
|
|
257
|
+
"from_ipynb",
|
|
258
|
+
"from_markdown",
|
|
259
|
+
"from_markdown_file",
|
|
260
|
+
"from_notebook",
|
|
261
|
+
"highlight",
|
|
262
|
+
"italic",
|
|
263
|
+
"keyboard",
|
|
264
|
+
"link",
|
|
265
|
+
"line_break",
|
|
266
|
+
"load_document",
|
|
267
|
+
"load_python_document",
|
|
268
|
+
"math",
|
|
269
|
+
"prescript",
|
|
270
|
+
"reference",
|
|
271
|
+
"render_document",
|
|
272
|
+
"status",
|
|
273
|
+
"strike",
|
|
274
|
+
"strikethrough",
|
|
275
|
+
"markup",
|
|
276
|
+
"styled",
|
|
277
|
+
"parse_ipynb",
|
|
278
|
+
"parse_markdown",
|
|
279
|
+
"parse_markdown_file",
|
|
280
|
+
"parse_notebook",
|
|
281
|
+
"section_for_level",
|
|
282
|
+
"shift_heading_level",
|
|
283
|
+
"shift_heading_levels",
|
|
284
|
+
"subscript",
|
|
285
|
+
"superscript",
|
|
286
|
+
"tag",
|
|
287
|
+
"validate_source",
|
|
288
|
+
]
|
|
289
|
+
|
|
290
|
+
for _module_name in ("components", "core", "document", "layout", "settings"):
|
|
291
|
+
globals().pop(_module_name, None)
|
|
292
|
+
|
|
293
|
+
del _resolve_version
|
|
294
|
+
del _module_name
|
oodocs/__main__.py
ADDED
oodocs/cli.py
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"""Command line interface for OODocs workflows."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import sys
|
|
8
|
+
from typing import Sequence
|
|
9
|
+
|
|
10
|
+
from oodocs.compatibility import normalize_output_formats
|
|
11
|
+
from oodocs.validation import DocumentValidationError
|
|
12
|
+
from oodocs.workflows import build_python_document, convert_source, validate_source
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def main(argv: Sequence[str] | None = None) -> int:
|
|
16
|
+
"""Run the OODocs CLI."""
|
|
17
|
+
|
|
18
|
+
parser = _build_parser()
|
|
19
|
+
args = parser.parse_args(argv)
|
|
20
|
+
try:
|
|
21
|
+
return args.func(args)
|
|
22
|
+
except DocumentValidationError as exc:
|
|
23
|
+
print(exc, file=sys.stderr)
|
|
24
|
+
return 1
|
|
25
|
+
except (AttributeError, FileNotFoundError, ImportError, TypeError, ValueError) as exc:
|
|
26
|
+
print(f"oodocs: {exc}", file=sys.stderr)
|
|
27
|
+
return 2
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _build_parser() -> argparse.ArgumentParser:
|
|
31
|
+
parser = argparse.ArgumentParser(
|
|
32
|
+
prog="oodocs",
|
|
33
|
+
description="Build, convert, and validate OODocs documents.",
|
|
34
|
+
)
|
|
35
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
36
|
+
|
|
37
|
+
build = subparsers.add_parser(
|
|
38
|
+
"build",
|
|
39
|
+
help="Build a Python-authored OODocs document.",
|
|
40
|
+
)
|
|
41
|
+
build.add_argument("source", help="Python file exposing a Document or build function.")
|
|
42
|
+
_add_render_options(build, default_out=".")
|
|
43
|
+
build.add_argument(
|
|
44
|
+
"--factory",
|
|
45
|
+
help="Document variable or zero-argument function to use from the Python source.",
|
|
46
|
+
)
|
|
47
|
+
build.add_argument(
|
|
48
|
+
"--no-chdir",
|
|
49
|
+
action="store_true",
|
|
50
|
+
help="Do not run the Python source with its directory as the working directory.",
|
|
51
|
+
)
|
|
52
|
+
build.set_defaults(func=_run_build)
|
|
53
|
+
|
|
54
|
+
convert = subparsers.add_parser(
|
|
55
|
+
"convert",
|
|
56
|
+
help="Convert Markdown or notebook source to rendered outputs.",
|
|
57
|
+
)
|
|
58
|
+
convert.add_argument("source", help="Markdown (.md) or notebook (.ipynb) file.")
|
|
59
|
+
_add_render_options(convert, default_out=None)
|
|
60
|
+
convert.add_argument("--title", help="Override the imported document title.")
|
|
61
|
+
convert.set_defaults(func=_run_convert)
|
|
62
|
+
|
|
63
|
+
validate = subparsers.add_parser(
|
|
64
|
+
"validate",
|
|
65
|
+
help="Validate a Python, Markdown, or notebook source document.",
|
|
66
|
+
)
|
|
67
|
+
validate.add_argument("source", help="Source file to validate.")
|
|
68
|
+
validate.add_argument(
|
|
69
|
+
"--to",
|
|
70
|
+
default="docx,pdf,html",
|
|
71
|
+
help="Comma-separated output formats to validate for. Defaults to docx,pdf,html.",
|
|
72
|
+
)
|
|
73
|
+
validate.add_argument(
|
|
74
|
+
"--type",
|
|
75
|
+
choices=("python", "py", "markdown", "md", "notebook", "ipynb"),
|
|
76
|
+
help="Override source type inference.",
|
|
77
|
+
)
|
|
78
|
+
validate.add_argument("--title", help="Override imported Markdown/notebook title.")
|
|
79
|
+
validate.add_argument(
|
|
80
|
+
"--factory",
|
|
81
|
+
help="Document variable or zero-argument function for Python sources.",
|
|
82
|
+
)
|
|
83
|
+
validate.add_argument(
|
|
84
|
+
"--strict",
|
|
85
|
+
action="store_true",
|
|
86
|
+
help="Return a non-zero exit code when warnings are present.",
|
|
87
|
+
)
|
|
88
|
+
validate.add_argument(
|
|
89
|
+
"--no-chdir",
|
|
90
|
+
action="store_true",
|
|
91
|
+
help="Do not run Python sources with their directory as the working directory.",
|
|
92
|
+
)
|
|
93
|
+
validate.set_defaults(func=_run_validate)
|
|
94
|
+
|
|
95
|
+
return parser
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _add_render_options(
|
|
99
|
+
parser: argparse.ArgumentParser,
|
|
100
|
+
*,
|
|
101
|
+
default_out: str | None,
|
|
102
|
+
) -> None:
|
|
103
|
+
parser.add_argument(
|
|
104
|
+
"--out",
|
|
105
|
+
default=default_out,
|
|
106
|
+
help=(
|
|
107
|
+
"Output directory. Defaults to the current directory for build and "
|
|
108
|
+
"the source directory for convert."
|
|
109
|
+
),
|
|
110
|
+
)
|
|
111
|
+
parser.add_argument(
|
|
112
|
+
"--to",
|
|
113
|
+
default="docx,pdf,html",
|
|
114
|
+
help="Comma-separated output formats. Defaults to docx,pdf,html.",
|
|
115
|
+
)
|
|
116
|
+
parser.add_argument("--stem", help="Output filename stem.")
|
|
117
|
+
parser.add_argument(
|
|
118
|
+
"--no-validate",
|
|
119
|
+
action="store_true",
|
|
120
|
+
help="Skip validation before rendering.",
|
|
121
|
+
)
|
|
122
|
+
parser.add_argument(
|
|
123
|
+
"--verbose",
|
|
124
|
+
action="store_true",
|
|
125
|
+
help="Print slow major build steps.",
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _run_build(args: argparse.Namespace) -> int:
|
|
130
|
+
formats = _parse_formats(args.to)
|
|
131
|
+
outputs = build_python_document(
|
|
132
|
+
args.source,
|
|
133
|
+
args.out,
|
|
134
|
+
formats=formats,
|
|
135
|
+
stem=args.stem,
|
|
136
|
+
factory=args.factory,
|
|
137
|
+
validate=not args.no_validate,
|
|
138
|
+
chdir=not args.no_chdir,
|
|
139
|
+
verbose=args.verbose,
|
|
140
|
+
)
|
|
141
|
+
_print_outputs(outputs.outputs)
|
|
142
|
+
return 0
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _run_convert(args: argparse.Namespace) -> int:
|
|
146
|
+
formats = _parse_formats(args.to)
|
|
147
|
+
outputs = convert_source(
|
|
148
|
+
args.source,
|
|
149
|
+
args.out,
|
|
150
|
+
formats=formats,
|
|
151
|
+
stem=args.stem,
|
|
152
|
+
title=args.title,
|
|
153
|
+
validate=not args.no_validate,
|
|
154
|
+
verbose=args.verbose,
|
|
155
|
+
)
|
|
156
|
+
_print_outputs(outputs.outputs)
|
|
157
|
+
return 0
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _run_validate(args: argparse.Namespace) -> int:
|
|
161
|
+
formats = _parse_formats(args.to)
|
|
162
|
+
result = validate_source(
|
|
163
|
+
args.source,
|
|
164
|
+
source_type=args.type,
|
|
165
|
+
title=args.title,
|
|
166
|
+
factory=args.factory,
|
|
167
|
+
formats=formats,
|
|
168
|
+
chdir=not args.no_chdir,
|
|
169
|
+
)
|
|
170
|
+
print(result.format_table(formats=formats))
|
|
171
|
+
if result.errors_for(formats):
|
|
172
|
+
return 1
|
|
173
|
+
if args.strict and result.warnings_for(formats):
|
|
174
|
+
return 1
|
|
175
|
+
return 0
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _parse_formats(value: str) -> tuple[str, ...]:
|
|
179
|
+
pieces = tuple(piece.strip() for piece in value.split(",") if piece.strip())
|
|
180
|
+
if not pieces:
|
|
181
|
+
raise ValueError("--to must include at least one output format")
|
|
182
|
+
return normalize_output_formats(pieces)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def _print_outputs(outputs: dict[object, Path]) -> None:
|
|
186
|
+
for output_format, path in outputs.items():
|
|
187
|
+
print(f"Wrote {output_format}: {path}")
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
if __name__ == "__main__":
|
|
191
|
+
raise SystemExit(main())
|
oodocs/compatibility.py
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""Shared output-format compatibility helpers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Iterable, Literal
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
OutputFormat = Literal["docx", "pdf", "html"]
|
|
10
|
+
OUTPUT_FORMATS: tuple[OutputFormat, ...] = ("docx", "pdf", "html")
|
|
11
|
+
OUTPUT_FORMAT_LABELS: dict[OutputFormat, str] = {
|
|
12
|
+
"docx": "Word",
|
|
13
|
+
"pdf": "PDF",
|
|
14
|
+
"html": "HTML",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True, slots=True)
|
|
19
|
+
class CompatibilityNote:
|
|
20
|
+
"""Renderer compatibility note surfaced by document validation."""
|
|
21
|
+
|
|
22
|
+
code: str
|
|
23
|
+
message: str
|
|
24
|
+
formats: tuple[OutputFormat, ...]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
COMPATIBILITY_NOTES: dict[str, CompatibilityNote] = {
|
|
28
|
+
"html-toc-page-numbers": CompatibilityNote(
|
|
29
|
+
code="html-toc-page-numbers",
|
|
30
|
+
message=(
|
|
31
|
+
"HTML output does not have stable rendered page numbers, "
|
|
32
|
+
"so the TOC is link-only there."
|
|
33
|
+
),
|
|
34
|
+
formats=("html",),
|
|
35
|
+
),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def compatibility_note(code: str) -> CompatibilityNote:
|
|
40
|
+
"""Return a named compatibility note."""
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
return COMPATIBILITY_NOTES[code]
|
|
44
|
+
except KeyError as exc:
|
|
45
|
+
raise KeyError(f"Unknown compatibility note: {code}") from exc
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def normalize_output_format(value: str) -> OutputFormat:
|
|
49
|
+
"""Normalize a renderer/output format name."""
|
|
50
|
+
|
|
51
|
+
normalized = value.lower().strip().removeprefix(".")
|
|
52
|
+
if normalized == "htm":
|
|
53
|
+
normalized = "html"
|
|
54
|
+
if normalized not in OUTPUT_FORMATS:
|
|
55
|
+
raise ValueError(
|
|
56
|
+
"Unsupported document output format. Use one of: .docx, .pdf, .html "
|
|
57
|
+
"(or docx, pdf, html in save_all)."
|
|
58
|
+
)
|
|
59
|
+
return normalized # type: ignore[return-value]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def normalize_output_formats(
|
|
63
|
+
values: Iterable[str] | None = None,
|
|
64
|
+
) -> tuple[OutputFormat, ...]:
|
|
65
|
+
"""Normalize a sequence of output formats while preserving order."""
|
|
66
|
+
|
|
67
|
+
if values is None:
|
|
68
|
+
return OUTPUT_FORMATS
|
|
69
|
+
|
|
70
|
+
normalized: list[OutputFormat] = []
|
|
71
|
+
seen: set[OutputFormat] = set()
|
|
72
|
+
for value in values:
|
|
73
|
+
output_format = normalize_output_format(value)
|
|
74
|
+
if output_format in seen:
|
|
75
|
+
continue
|
|
76
|
+
normalized.append(output_format)
|
|
77
|
+
seen.add(output_format)
|
|
78
|
+
return tuple(normalized)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def format_output_formats(formats: Iterable[OutputFormat]) -> str:
|
|
82
|
+
"""Return a compact display label for output formats."""
|
|
83
|
+
|
|
84
|
+
normalized = normalize_output_formats(formats)
|
|
85
|
+
if not normalized:
|
|
86
|
+
return "None"
|
|
87
|
+
if set(normalized) == set(OUTPUT_FORMATS):
|
|
88
|
+
return "All"
|
|
89
|
+
return "/".join(OUTPUT_FORMAT_LABELS[output_format] for output_format in normalized)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
__all__ = [
|
|
93
|
+
"COMPATIBILITY_NOTES",
|
|
94
|
+
"OUTPUT_FORMATS",
|
|
95
|
+
"OUTPUT_FORMAT_LABELS",
|
|
96
|
+
"CompatibilityNote",
|
|
97
|
+
"OutputFormat",
|
|
98
|
+
"compatibility_note",
|
|
99
|
+
"format_output_formats",
|
|
100
|
+
"normalize_output_format",
|
|
101
|
+
"normalize_output_formats",
|
|
102
|
+
]
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""Grouped component namespaces for more granular imports."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib import import_module
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
_EXPORTS = {
|
|
9
|
+
"Affiliation": "oodocs.components.people",
|
|
10
|
+
"Assumption": "oodocs.components.blocks",
|
|
11
|
+
"Author": "oodocs.components.people",
|
|
12
|
+
"AuthorLayout": "oodocs.components.people",
|
|
13
|
+
"Axiom": "oodocs.components.blocks",
|
|
14
|
+
"Bold": "oodocs.components.inline",
|
|
15
|
+
"Box": "oodocs.components.blocks",
|
|
16
|
+
"BulletList": "oodocs.components.blocks",
|
|
17
|
+
"Chapter": "oodocs.components.blocks",
|
|
18
|
+
"Citation": "oodocs.components.inline",
|
|
19
|
+
"CitationLibrary": "oodocs.components.references",
|
|
20
|
+
"CitationSource": "oodocs.components.references",
|
|
21
|
+
"Claim": "oodocs.components.blocks",
|
|
22
|
+
"CodeBlock": "oodocs.components.blocks",
|
|
23
|
+
"ColumnSpan": "oodocs.components.blocks",
|
|
24
|
+
"Comment": "oodocs.components.inline",
|
|
25
|
+
"Conjecture": "oodocs.components.blocks",
|
|
26
|
+
"CommentsPage": "oodocs.components.generated",
|
|
27
|
+
"Corollary": "oodocs.components.blocks",
|
|
28
|
+
"CountableBlock": "oodocs.components.blocks",
|
|
29
|
+
"Definition": "oodocs.components.blocks",
|
|
30
|
+
"Divider": "oodocs.components.blocks",
|
|
31
|
+
"Equation": "oodocs.components.blocks",
|
|
32
|
+
"Example": "oodocs.components.blocks",
|
|
33
|
+
"Figure": "oodocs.components.media",
|
|
34
|
+
"FigureList": "oodocs.components.generated",
|
|
35
|
+
"Footnote": "oodocs.components.inline",
|
|
36
|
+
"FootnotesPage": "oodocs.components.generated",
|
|
37
|
+
"Highlight": "oodocs.components.inline",
|
|
38
|
+
"Hyperlink": "oodocs.components.inline",
|
|
39
|
+
"ImageBox": "oodocs.components.positioning",
|
|
40
|
+
"ImageData": "oodocs.components.media",
|
|
41
|
+
"InlineChip": "oodocs.components.inline",
|
|
42
|
+
"InlineChipStyle": "oodocs.components.inline",
|
|
43
|
+
"Italic": "oodocs.components.inline",
|
|
44
|
+
"Lemma": "oodocs.components.blocks",
|
|
45
|
+
"LineBreak": "oodocs.components.inline",
|
|
46
|
+
"Math": "oodocs.components.inline",
|
|
47
|
+
"Monospace": "oodocs.components.inline",
|
|
48
|
+
"MultiColumn": "oodocs.components.blocks",
|
|
49
|
+
"NumberedList": "oodocs.components.blocks",
|
|
50
|
+
"Paragraph": "oodocs.components.blocks",
|
|
51
|
+
"Part": "oodocs.components.blocks",
|
|
52
|
+
"Proposition": "oodocs.components.blocks",
|
|
53
|
+
"Proof": "oodocs.components.blocks",
|
|
54
|
+
"ReferencesPage": "oodocs.components.generated",
|
|
55
|
+
"Remark": "oodocs.components.blocks",
|
|
56
|
+
"Section": "oodocs.components.blocks",
|
|
57
|
+
"Shape": "oodocs.components.positioning",
|
|
58
|
+
"SubFigure": "oodocs.components.media",
|
|
59
|
+
"SubFigureGroup": "oodocs.components.media",
|
|
60
|
+
"Subsection": "oodocs.components.blocks",
|
|
61
|
+
"Subsubsection": "oodocs.components.blocks",
|
|
62
|
+
"Table": "oodocs.components.media",
|
|
63
|
+
"TableCell": "oodocs.components.media",
|
|
64
|
+
"TableCellStyle": "oodocs.components.media",
|
|
65
|
+
"TableList": "oodocs.components.generated",
|
|
66
|
+
"TableOfContents": "oodocs.components.generated",
|
|
67
|
+
"Text": "oodocs.components.inline",
|
|
68
|
+
"TextBox": "oodocs.components.positioning",
|
|
69
|
+
"Theorem": "oodocs.components.blocks",
|
|
70
|
+
"VerticalSpace": "oodocs.components.blocks",
|
|
71
|
+
"badge": "oodocs.components.inline",
|
|
72
|
+
"bold": "oodocs.components.inline",
|
|
73
|
+
"code": "oodocs.components.inline",
|
|
74
|
+
"color": "oodocs.components.inline",
|
|
75
|
+
"cite": "oodocs.components.inline",
|
|
76
|
+
"comment": "oodocs.components.inline",
|
|
77
|
+
"countable_kind": "oodocs.components.blocks",
|
|
78
|
+
"footnote": "oodocs.components.inline",
|
|
79
|
+
"highlight": "oodocs.components.inline",
|
|
80
|
+
"italic": "oodocs.components.inline",
|
|
81
|
+
"keyboard": "oodocs.components.inline",
|
|
82
|
+
"link": "oodocs.components.inline",
|
|
83
|
+
"line_break": "oodocs.components.inline",
|
|
84
|
+
"math": "oodocs.components.inline",
|
|
85
|
+
"markup": "oodocs.components.markup",
|
|
86
|
+
"prescript": "oodocs.components.inline",
|
|
87
|
+
"reference": "oodocs.components.inline",
|
|
88
|
+
"status": "oodocs.components.inline",
|
|
89
|
+
"strike": "oodocs.components.inline",
|
|
90
|
+
"strikethrough": "oodocs.components.inline",
|
|
91
|
+
"styled": "oodocs.components.inline",
|
|
92
|
+
"subscript": "oodocs.components.inline",
|
|
93
|
+
"superscript": "oodocs.components.inline",
|
|
94
|
+
"tag": "oodocs.components.inline",
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
__all__ = list(_EXPORTS)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def __getattr__(name: str) -> object:
|
|
101
|
+
module_name = _EXPORTS.get(name)
|
|
102
|
+
if module_name is None:
|
|
103
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
104
|
+
value = getattr(import_module(module_name), name)
|
|
105
|
+
globals()[name] = value
|
|
106
|
+
return value
|