dita-convert 1.2.2__tar.gz → 1.2.3__tar.gz
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.
- {dita_convert-1.2.2 → dita_convert-1.2.3}/PKG-INFO +2 -2
- {dita_convert-1.2.2 → dita_convert-1.2.3}/pyproject.toml +2 -1
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/convert/__init__.py +1 -1
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/convert/cli.py +17 -10
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/convert/xslt/task-generated.xsl +3 -3
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita_convert.egg-info/PKG-INFO +2 -2
- {dita_convert-1.2.2 → dita_convert-1.2.3}/test/test_convert_cli.py +9 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/test/test_convert_to_task_generated.py +65 -1
- {dita_convert-1.2.2 → dita_convert-1.2.3}/LICENSE +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/README.md +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/setup.cfg +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/__init__.py +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/convert/__main__.py +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/convert/transform.py +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/convert/xslt/concept-generated.xsl +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/convert/xslt/concept.xsl +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/convert/xslt/reference-generated.xsl +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/convert/xslt/reference.xsl +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/convert/xslt/task.xsl +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/convert/xslt/topic.xsl +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita/convert/xslt.py +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita_convert.egg-info/SOURCES.txt +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita_convert.egg-info/dependency_links.txt +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita_convert.egg-info/entry_points.txt +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita_convert.egg-info/requires.txt +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/src/dita_convert.egg-info/top_level.txt +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/test/test_convert.py +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/test/test_convert_to_concept.py +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/test/test_convert_to_concept_generated.py +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/test/test_convert_to_reference.py +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/test/test_convert_to_reference_generated.py +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/test/test_convert_to_task.py +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/test/test_convert_transform.py +0 -0
- {dita_convert-1.2.2 → dita_convert-1.2.3}/test/test_convert_xslt.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dita-convert
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.3
|
|
4
4
|
Summary: Convert a generic DITA topic to a specialized concept, task, or reference.
|
|
5
5
|
Author-email: Jaromir Hradilek <jhradilek@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
6
7
|
Project-URL: Homepage, https://github.com/jhradilek/dita-custom-xslt
|
|
7
8
|
Project-URL: Repository, https://github.com/jhradilek/dita-custom-xslt
|
|
8
9
|
Project-URL: Issues, https://github.com/jhradilek/dita-custom-xslt/issues
|
|
9
10
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Development Status :: 5 - Production/Stable
|
|
13
13
|
Classifier: Environment :: Console
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
name = "dita-convert"
|
|
3
3
|
authors = [{name = "Jaromir Hradilek", email="jhradilek@gmail.com"}]
|
|
4
4
|
description = "Convert a generic DITA topic to a specialized concept, task, or reference."
|
|
5
|
+
license = "MIT"
|
|
6
|
+
license-files = ["LICENSE"]
|
|
5
7
|
readme = "README.md"
|
|
6
8
|
requires-python = ">= 3.10"
|
|
7
9
|
classifiers = [
|
|
8
10
|
"Programming Language :: Python :: 3",
|
|
9
|
-
"License :: OSI Approved :: MIT License",
|
|
10
11
|
"Operating System :: OS Independent",
|
|
11
12
|
"Development Status :: 5 - Production/Stable",
|
|
12
13
|
"Environment :: Console",
|
|
@@ -28,7 +28,7 @@ __author__ = 'Jaromir Hradilek'
|
|
|
28
28
|
__copyright__ = 'Copyright (C) 2024, 2025 Jaromir Hradilek'
|
|
29
29
|
__license__ = 'MIT License'
|
|
30
30
|
__description__ = __doc__
|
|
31
|
-
__version__ = '1.2.
|
|
31
|
+
__version__ = '1.2.3'
|
|
32
32
|
|
|
33
33
|
# Expose general information about the project:
|
|
34
34
|
NAME = 'dita-convert'
|
|
@@ -32,7 +32,7 @@ from .transform import to_concept, to_reference, to_task, \
|
|
|
32
32
|
to_task_generated
|
|
33
33
|
|
|
34
34
|
# Print a message to standard error output and terminate the script:
|
|
35
|
-
def exit_with_error(error_message, exit_status=errno.EPERM):
|
|
35
|
+
def exit_with_error(error_message: str, exit_status: int = errno.EPERM) -> None:
|
|
36
36
|
# Print the supplied message to standard error output:
|
|
37
37
|
print(f'{NAME}: {error_message}', file=sys.stderr)
|
|
38
38
|
|
|
@@ -40,7 +40,7 @@ def exit_with_error(error_message, exit_status=errno.EPERM):
|
|
|
40
40
|
sys.exit(exit_status)
|
|
41
41
|
|
|
42
42
|
# Extract the content type from the root element outputclass:
|
|
43
|
-
def get_type(source_file, source_xml):
|
|
43
|
+
def get_type(source_file: str, source_xml: etree._ElementTree) -> str:
|
|
44
44
|
# Get the root element attributes:
|
|
45
45
|
attributes = source_xml.getroot().attrib
|
|
46
46
|
|
|
@@ -49,17 +49,23 @@ def get_type(source_file, source_xml):
|
|
|
49
49
|
exit_with_error(f'{source_file}: error: outputclass not found, use -t/--type', errno.EINVAL)
|
|
50
50
|
|
|
51
51
|
# Get the outputclass attribute value:
|
|
52
|
-
output_class = attributes['outputclass'].lower()
|
|
52
|
+
output_class = str(attributes['outputclass'].lower())
|
|
53
53
|
|
|
54
54
|
# Verify that the outputclass value is supported:
|
|
55
|
-
if output_class not in ['concept', 'procedure', 'task', 'reference']:
|
|
55
|
+
if output_class not in ['assembly', 'concept', 'procedure', 'task', 'reference']:
|
|
56
56
|
exit_with_error(f'{source_file}: error: unsupported outputclass "{output_class}", use -t/--type', errno.EINVAL)
|
|
57
57
|
|
|
58
|
+
# Adjust the outputclass if needed:
|
|
59
|
+
if output_class == 'assembly':
|
|
60
|
+
output_class = output_class.replace('assembly', 'concept')
|
|
61
|
+
if output_class == 'procedure':
|
|
62
|
+
output_class = output_class.replace('procedure', 'task')
|
|
63
|
+
|
|
58
64
|
# Return the adjusted outputclass:
|
|
59
|
-
return output_class
|
|
65
|
+
return output_class
|
|
60
66
|
|
|
61
67
|
# Convert the selected file:
|
|
62
|
-
def convert(source_file, target_type=None, generated=False):
|
|
68
|
+
def convert(source_file: str, target_type: str | None = None, generated: bool = False) -> str:
|
|
63
69
|
# Parse the source file:
|
|
64
70
|
try:
|
|
65
71
|
source_xml = etree.parse(source_file)
|
|
@@ -91,14 +97,15 @@ def convert(source_file, target_type=None, generated=False):
|
|
|
91
97
|
exit_with_error(f'{source_file}: {message}')
|
|
92
98
|
|
|
93
99
|
# Print any warning messages to standard error output:
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
if hasattr(transform, 'error_log'):
|
|
101
|
+
for error in transform.error_log:
|
|
102
|
+
print(f'{source_file}: {error.message}', file=sys.stderr)
|
|
96
103
|
|
|
97
104
|
# Return the result:
|
|
98
105
|
return str(xml)
|
|
99
106
|
|
|
100
107
|
# Parse supplied command-line options:
|
|
101
|
-
def parse_args(argv=None):
|
|
108
|
+
def parse_args(argv: list[str] | None = None) -> None:
|
|
102
109
|
# Configure the option parser:
|
|
103
110
|
parser = argparse.ArgumentParser(prog=NAME,
|
|
104
111
|
description=DESCRIPTION,
|
|
@@ -151,7 +158,7 @@ def parse_args(argv=None):
|
|
|
151
158
|
try:
|
|
152
159
|
xml = convert(args.file, args.type, args.generated)
|
|
153
160
|
except OSError as message:
|
|
154
|
-
exit_with_error(message, errno.ENOENT)
|
|
161
|
+
exit_with_error(str(message), errno.ENOENT)
|
|
155
162
|
|
|
156
163
|
# Determine whether to write to standard output:
|
|
157
164
|
if args.output == sys.stdout or args.output == '-':
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
<!-- Compose the result element: -->
|
|
113
113
|
<xsl:call-template name="compose-element">
|
|
114
114
|
<xsl:with-param name="name" select="'result'" />
|
|
115
|
-
<xsl:with-param name="contents" select="*[not(@outputclass='title') and preceding-sibling::p[@outputclass='title'][1][b='Verification']]" />
|
|
115
|
+
<xsl:with-param name="contents" select="*[not(@outputclass='title') and preceding-sibling::p[@outputclass='title'][1][b='Verification' or b='Result' or b='Results']]" />
|
|
116
116
|
</xsl:call-template>
|
|
117
117
|
<!-- Compose the tasktroubleshooting element: -->
|
|
118
118
|
<xsl:call-template name="compose-element">
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
<!-- Compose the postreq element: -->
|
|
123
123
|
<xsl:call-template name="compose-element">
|
|
124
124
|
<xsl:with-param name="name" select="'postreq'" />
|
|
125
|
-
<xsl:with-param name="contents" select="*[not(@outputclass='title') and preceding-sibling::p[@outputclass='title'][1][b='Next
|
|
125
|
+
<xsl:with-param name="contents" select="*[not(@outputclass='title') and preceding-sibling::p[@outputclass='title'][1][b='Next step' or b='Next steps']]" />
|
|
126
126
|
</xsl:call-template>
|
|
127
127
|
</xsl:element>
|
|
128
128
|
<!-- Compose the related-links element: -->
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
|
|
133
133
|
<!-- Issue a warning if the converted file contains an unsupported title: -->
|
|
134
134
|
<xsl:for-each select="p[@outputclass='title']/b/text()">
|
|
135
|
-
<xsl:variable name="titles" select="'|Prerequisites|Procedure|Verification|Troubleshooting|Troubleshooting steps|Next steps|Next step|Additional resources|'" />
|
|
135
|
+
<xsl:variable name="titles" select="'|Prerequisites|Procedure|Verification|Result|Results|Troubleshooting|Troubleshooting steps|Next steps|Next step|Additional resources|'" />
|
|
136
136
|
<xsl:if test="not(contains($titles, concat('|', ., '|')))">
|
|
137
137
|
<xsl:message terminate="no">WARNING: Unsupported title '<xsl:copy-of select="." />' found, skipping...</xsl:message>
|
|
138
138
|
</xsl:if>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dita-convert
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.3
|
|
4
4
|
Summary: Convert a generic DITA topic to a specialized concept, task, or reference.
|
|
5
5
|
Author-email: Jaromir Hradilek <jhradilek@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
6
7
|
Project-URL: Homepage, https://github.com/jhradilek/dita-custom-xslt
|
|
7
8
|
Project-URL: Repository, https://github.com/jhradilek/dita-custom-xslt
|
|
8
9
|
Project-URL: Issues, https://github.com/jhradilek/dita-custom-xslt/issues
|
|
9
10
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Development Status :: 5 - Production/Stable
|
|
13
13
|
Classifier: Environment :: Console
|
|
@@ -206,6 +206,15 @@ class TestDitaCli(unittest.TestCase):
|
|
|
206
206
|
self.assertEqual(cm.exception.code, errno.ENOENT)
|
|
207
207
|
self.assertRegex(err.getvalue(), rf'^{NAME}:.*topic\.dita')
|
|
208
208
|
|
|
209
|
+
def test_get_type_assembly(self):
|
|
210
|
+
xml = etree.parse(StringIO('<topic outputclass="assembly" />'))
|
|
211
|
+
|
|
212
|
+
with contextlib.redirect_stderr(StringIO()) as err:
|
|
213
|
+
target_type = cli.get_type('topic.dita', xml)
|
|
214
|
+
|
|
215
|
+
self.assertEqual(err.getvalue().rstrip(), '')
|
|
216
|
+
self.assertEqual(target_type, 'concept')
|
|
217
|
+
|
|
209
218
|
def test_get_type_concept(self):
|
|
210
219
|
xml = etree.parse(StringIO('<topic outputclass="concept" />'))
|
|
211
220
|
|
|
@@ -308,7 +308,7 @@ class TestDitaConvertToTaskGenerated(unittest.TestCase):
|
|
|
308
308
|
<ol>
|
|
309
309
|
<li>Troubleshooting step</li>
|
|
310
310
|
</ol>
|
|
311
|
-
<p outputclass="title"><b>Next
|
|
311
|
+
<p outputclass="title"><b>Next step</b></p>
|
|
312
312
|
<ul>
|
|
313
313
|
<li>Next step</li>
|
|
314
314
|
</ul>
|
|
@@ -335,6 +335,70 @@ class TestDitaConvertToTaskGenerated(unittest.TestCase):
|
|
|
335
335
|
self.assertTrue(task.xpath('boolean(/task/taskbody/tasktroubleshooting/ol/li[text()="Troubleshooting step"])'))
|
|
336
336
|
self.assertTrue(task.xpath('boolean(/task/taskbody/postreq/ul/li[text()="Next step"])'))
|
|
337
337
|
|
|
338
|
+
def test_result(self):
|
|
339
|
+
xml = etree.parse(StringIO('''\
|
|
340
|
+
<topic id="example-topic">
|
|
341
|
+
<body>
|
|
342
|
+
<p outputclass="title"><b>Result</b></p>
|
|
343
|
+
<ul>
|
|
344
|
+
<li>Verification step</li>
|
|
345
|
+
</ul>
|
|
346
|
+
</body>
|
|
347
|
+
</topic>
|
|
348
|
+
'''))
|
|
349
|
+
|
|
350
|
+
task = transform.to_task_generated(xml)
|
|
351
|
+
|
|
352
|
+
self.assertTrue(task.xpath('boolean(/task/taskbody/result/ul/li[text()="Verification step"])'))
|
|
353
|
+
|
|
354
|
+
def test_results(self):
|
|
355
|
+
xml = etree.parse(StringIO('''\
|
|
356
|
+
<topic id="example-topic">
|
|
357
|
+
<body>
|
|
358
|
+
<p outputclass="title"><b>Results</b></p>
|
|
359
|
+
<ul>
|
|
360
|
+
<li>Verification step</li>
|
|
361
|
+
</ul>
|
|
362
|
+
</body>
|
|
363
|
+
</topic>
|
|
364
|
+
'''))
|
|
365
|
+
|
|
366
|
+
task = transform.to_task_generated(xml)
|
|
367
|
+
|
|
368
|
+
self.assertTrue(task.xpath('boolean(/task/taskbody/result/ul/li[text()="Verification step"])'))
|
|
369
|
+
|
|
370
|
+
def test_troubleshooting_steps(self):
|
|
371
|
+
xml = etree.parse(StringIO('''\
|
|
372
|
+
<topic id="example-topic">
|
|
373
|
+
<body>
|
|
374
|
+
<p outputclass="title"><b>Troubleshooting steps</b></p>
|
|
375
|
+
<ol>
|
|
376
|
+
<li>Troubleshooting step</li>
|
|
377
|
+
</ol>
|
|
378
|
+
</body>
|
|
379
|
+
</topic>
|
|
380
|
+
'''))
|
|
381
|
+
|
|
382
|
+
task = transform.to_task_generated(xml)
|
|
383
|
+
|
|
384
|
+
self.assertTrue(task.xpath('boolean(/task/taskbody/tasktroubleshooting/ol/li[text()="Troubleshooting step"])'))
|
|
385
|
+
|
|
386
|
+
def test_next_steps(self):
|
|
387
|
+
xml = etree.parse(StringIO('''\
|
|
388
|
+
<topic id="example-topic">
|
|
389
|
+
<body>
|
|
390
|
+
<p outputclass="title"><b>Next steps</b></p>
|
|
391
|
+
<ul>
|
|
392
|
+
<li>Next step</li>
|
|
393
|
+
</ul>
|
|
394
|
+
</body>
|
|
395
|
+
</topic>
|
|
396
|
+
'''))
|
|
397
|
+
|
|
398
|
+
task = transform.to_task_generated(xml)
|
|
399
|
+
|
|
400
|
+
self.assertTrue(task.xpath('boolean(/task/taskbody/postreq/ul/li[text()="Next step"])'))
|
|
401
|
+
|
|
338
402
|
def test_multiple_abstracts(self):
|
|
339
403
|
xml = etree.parse(StringIO('''\
|
|
340
404
|
<topic id="example-topic">
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|