specitems 1.1.1__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.
- specitems-1.1.1/PKG-INFO +60 -0
- specitems-1.1.1/README.md +27 -0
- specitems-1.1.1/pyproject.toml +79 -0
- specitems-1.1.1/src/specitems/__init__.py +218 -0
- specitems-1.1.1/src/specitems/cite.py +149 -0
- specitems-1.1.1/src/specitems/clihash.py +92 -0
- specitems-1.1.1/src/specitems/clipickle.py +66 -0
- specitems-1.1.1/src/specitems/clispecdoc.py +110 -0
- specitems-1.1.1/src/specitems/cliutil.py +105 -0
- specitems-1.1.1/src/specitems/cliyamlquery.py +46 -0
- specitems-1.1.1/src/specitems/content.py +578 -0
- specitems-1.1.1/src/specitems/contentmarkdown.py +142 -0
- specitems-1.1.1/src/specitems/contentsphinx.py +384 -0
- specitems-1.1.1/src/specitems/contenttext.py +253 -0
- specitems-1.1.1/src/specitems/getvaluesubprocess.py +152 -0
- specitems-1.1.1/src/specitems/glossary.py +199 -0
- specitems-1.1.1/src/specitems/hashutil.py +111 -0
- specitems-1.1.1/src/specitems/itemmapper.py +524 -0
- specitems-1.1.1/src/specitems/items.py +1240 -0
- specitems-1.1.1/src/specitems/py.typed +0 -0
- specitems-1.1.1/src/specitems/spec.pickle +0 -0
- specitems-1.1.1/src/specitems/specdoc.py +576 -0
- specitems-1.1.1/src/specitems/specverify.py +793 -0
- specitems-1.1.1/src/specitems/subprocessaction.py +110 -0
specitems-1.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: specitems
|
|
3
|
+
Version: 1.1.1
|
|
4
|
+
Summary: Provides interfaces to work with specification items.
|
|
5
|
+
Keywords: certification,documentation,markdown,qualification,requirements-management,traceability
|
|
6
|
+
Author: The specitems Authors
|
|
7
|
+
Author-email: The specitems Authors <specthings@embedded-brains.de>
|
|
8
|
+
License-Expression: BSD-2-Clause
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: POSIX
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Topic :: Text Processing :: Markup
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Dist: mdformat>=0.7.22
|
|
23
|
+
Requires-Dist: mdformat-deflist>=0.1.3
|
|
24
|
+
Requires-Dist: mdformat-footnote>=0.1.3
|
|
25
|
+
Requires-Dist: mdformat-frontmatter>=2.0.10
|
|
26
|
+
Requires-Dist: mdformat-myst>=0.3.0
|
|
27
|
+
Requires-Dist: mdformat-tables>=1.0.0
|
|
28
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
29
|
+
Requires-Python: >=3.11
|
|
30
|
+
Project-URL: Source Code, https://github.com/specthings/specitems
|
|
31
|
+
Project-URL: Bug Tracker, https://github.com/specthings/specitems/issues
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
<!--
|
|
35
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
36
|
+
|
|
37
|
+
Copyright (C) 2026 embedded brains GmbH & Co. KG
|
|
38
|
+
-->
|
|
39
|
+
## Overview
|
|
40
|
+
|
|
41
|
+
The *specitems* Python package provides interfaces to work with specification
|
|
42
|
+
items. Specifications are written in specification items which may contain
|
|
43
|
+
dictionaries, lists, integers, floating-point numbers, and strings. The format
|
|
44
|
+
of these items is extensible, human readable, machine readable, Git friendly,
|
|
45
|
+
and can be customized according to domain-specific needs. The items are
|
|
46
|
+
connected through links which may contain role-specific extra information.
|
|
47
|
+
This enables different views to a specification item graph depending on the use
|
|
48
|
+
case.
|
|
49
|
+
|
|
50
|
+
The package is maintained by the
|
|
51
|
+
[specthings](https://github.com/specthings)
|
|
52
|
+
project. Users of the package are
|
|
53
|
+
[specware](https://github.com/specthings/specitems)
|
|
54
|
+
and
|
|
55
|
+
[specbuild](https://github.com/specthings/specbuild).
|
|
56
|
+
|
|
57
|
+
## Contributing
|
|
58
|
+
|
|
59
|
+
Please refer to our
|
|
60
|
+
[Contributing Guidelines](https://github.com/specthings/specitems/blob/main/CONTRIBUTING.md).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2026 embedded brains GmbH & Co. KG
|
|
5
|
+
-->
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
The *specitems* Python package provides interfaces to work with specification
|
|
9
|
+
items. Specifications are written in specification items which may contain
|
|
10
|
+
dictionaries, lists, integers, floating-point numbers, and strings. The format
|
|
11
|
+
of these items is extensible, human readable, machine readable, Git friendly,
|
|
12
|
+
and can be customized according to domain-specific needs. The items are
|
|
13
|
+
connected through links which may contain role-specific extra information.
|
|
14
|
+
This enables different views to a specification item graph depending on the use
|
|
15
|
+
case.
|
|
16
|
+
|
|
17
|
+
The package is maintained by the
|
|
18
|
+
[specthings](https://github.com/specthings)
|
|
19
|
+
project. Users of the package are
|
|
20
|
+
[specware](https://github.com/specthings/specitems)
|
|
21
|
+
and
|
|
22
|
+
[specbuild](https://github.com/specthings/specbuild).
|
|
23
|
+
|
|
24
|
+
## Contributing
|
|
25
|
+
|
|
26
|
+
Please refer to our
|
|
27
|
+
[Contributing Guidelines](https://github.com/specthings/specitems/blob/main/CONTRIBUTING.md).
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2026 embedded brains GmbH & Co. KG
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "specitems"
|
|
7
|
+
version = "1.1.1"
|
|
8
|
+
description = "Provides interfaces to work with specification items."
|
|
9
|
+
authors = [
|
|
10
|
+
{name = "The specitems Authors", email = "specthings@embedded-brains.de"}
|
|
11
|
+
]
|
|
12
|
+
license = "BSD-2-Clause"
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
requires-python = ">=3.11"
|
|
15
|
+
dependencies = [
|
|
16
|
+
"mdformat>=0.7.22",
|
|
17
|
+
"mdformat-deflist>=0.1.3",
|
|
18
|
+
"mdformat-footnote>=0.1.3",
|
|
19
|
+
"mdformat-frontmatter>=2.0.10",
|
|
20
|
+
"mdformat-myst>=0.3.0",
|
|
21
|
+
"mdformat-tables>=1.0.0",
|
|
22
|
+
"pyyaml>=6.0.3",
|
|
23
|
+
]
|
|
24
|
+
keywords = [
|
|
25
|
+
"certification",
|
|
26
|
+
"documentation",
|
|
27
|
+
"markdown",
|
|
28
|
+
"qualification",
|
|
29
|
+
"requirements-management",
|
|
30
|
+
"traceability",
|
|
31
|
+
]
|
|
32
|
+
classifiers = [
|
|
33
|
+
"Development Status :: 5 - Production/Stable",
|
|
34
|
+
"Environment :: Console",
|
|
35
|
+
"Intended Audience :: Developers",
|
|
36
|
+
"Operating System :: POSIX",
|
|
37
|
+
"Programming Language :: Python :: 3",
|
|
38
|
+
"Programming Language :: Python :: 3.11",
|
|
39
|
+
"Programming Language :: Python :: 3.12",
|
|
40
|
+
"Programming Language :: Python :: 3.13",
|
|
41
|
+
"Programming Language :: Python :: 3.14",
|
|
42
|
+
"Topic :: Software Development :: Documentation",
|
|
43
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
44
|
+
"Topic :: Text Processing :: Markup",
|
|
45
|
+
"Typing :: Typed",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[project.urls]
|
|
49
|
+
"Source Code" = "https://github.com/specthings/specitems"
|
|
50
|
+
"Bug Tracker" = "https://github.com/specthings/specitems/issues"
|
|
51
|
+
|
|
52
|
+
[project.scripts]
|
|
53
|
+
specpickle = "specitems.clipickle:clipickle"
|
|
54
|
+
specdocitems = "specitems.clispecdoc:clispecdocitems"
|
|
55
|
+
spechash = "specitems.clihash:clihash"
|
|
56
|
+
specyamlquery = "specitems.cliyamlquery:cliyamlquery"
|
|
57
|
+
|
|
58
|
+
[build-system]
|
|
59
|
+
requires = ["uv_build>=0.10.0,<0.11.0"]
|
|
60
|
+
build-backend = "uv_build"
|
|
61
|
+
|
|
62
|
+
[dependency-groups]
|
|
63
|
+
dev = [
|
|
64
|
+
"coverage>=7.13.3",
|
|
65
|
+
"flake8>=7.3.0",
|
|
66
|
+
"mypy>=1.19.1",
|
|
67
|
+
"pylint>=4.0.4",
|
|
68
|
+
"pytest>=9.0.2",
|
|
69
|
+
"pytest-cov>=7.0.0",
|
|
70
|
+
"sphinx>=9.0.4",
|
|
71
|
+
"sphinx-autodoc-napoleon-typehints>=2.1.6",
|
|
72
|
+
"sphinx-autodoc-typehints>=3.6.1",
|
|
73
|
+
"sphinx-rtd-theme>=3.1.0",
|
|
74
|
+
"types-pyyaml>=6.0.12.20250915",
|
|
75
|
+
"yapf>=0.43.0",
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
[tool.pytest.ini_options]
|
|
79
|
+
addopts = "--cov=specitems --cov-fail-under=100 --cov-branch --cov-report=term-missing"
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
""" The specitems package. """
|
|
3
|
+
|
|
4
|
+
# Copyright (C) 2019, 2026 embedded brains GmbH & Co. KG
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted provided that the following conditions
|
|
8
|
+
# are met:
|
|
9
|
+
# 1. Redistributions of source code must retain the above copyright
|
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
|
14
|
+
#
|
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
18
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
19
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
20
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
21
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
22
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
23
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
24
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
25
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
26
|
+
|
|
27
|
+
from .cite import BibTeXCitationProvider
|
|
28
|
+
from .cliutil import (
|
|
29
|
+
create_argument_parser,
|
|
30
|
+
create_config,
|
|
31
|
+
init_logging,
|
|
32
|
+
load_config,
|
|
33
|
+
)
|
|
34
|
+
from .content import (
|
|
35
|
+
Content,
|
|
36
|
+
ContentAddContext,
|
|
37
|
+
Copyright,
|
|
38
|
+
Copyrights,
|
|
39
|
+
GenericContent,
|
|
40
|
+
GenericContentIterable,
|
|
41
|
+
MARKDOWN_ROLES,
|
|
42
|
+
get_value_plural,
|
|
43
|
+
list_terms,
|
|
44
|
+
make_copyright_statement,
|
|
45
|
+
split_copyright_statement,
|
|
46
|
+
to_camel_case,
|
|
47
|
+
)
|
|
48
|
+
from .contenttext import (
|
|
49
|
+
TextContent,
|
|
50
|
+
TextMapper,
|
|
51
|
+
latex_escape,
|
|
52
|
+
make_label,
|
|
53
|
+
)
|
|
54
|
+
from .contentmarkdown import (
|
|
55
|
+
MarkdownContent,
|
|
56
|
+
MarkdownMapper,
|
|
57
|
+
)
|
|
58
|
+
from .contentsphinx import (
|
|
59
|
+
SphinxContent,
|
|
60
|
+
SphinxMapper,
|
|
61
|
+
escape_code_line,
|
|
62
|
+
get_reference,
|
|
63
|
+
)
|
|
64
|
+
from .getvaluesubprocess import get_value_subprocess
|
|
65
|
+
from .glossary import (
|
|
66
|
+
DocumentGlossaryConfig,
|
|
67
|
+
GlossaryConfig,
|
|
68
|
+
augment_glossary_terms,
|
|
69
|
+
generate_glossary,
|
|
70
|
+
)
|
|
71
|
+
from .hashutil import (
|
|
72
|
+
base64_to_hex,
|
|
73
|
+
base64_to_hex_text,
|
|
74
|
+
hash_file,
|
|
75
|
+
hash_file_lines,
|
|
76
|
+
hash_file_lines_md5,
|
|
77
|
+
hash_file_lines_sha256,
|
|
78
|
+
hash_file_md5,
|
|
79
|
+
hash_file_sha256,
|
|
80
|
+
)
|
|
81
|
+
from .items import (
|
|
82
|
+
EmptyItem,
|
|
83
|
+
EmptyItemCache,
|
|
84
|
+
EnabledSet,
|
|
85
|
+
IS_ENABLED_OPS,
|
|
86
|
+
IsEnabled,
|
|
87
|
+
IsLinkEnabled,
|
|
88
|
+
Item,
|
|
89
|
+
ItemCache,
|
|
90
|
+
ItemCacheConfig,
|
|
91
|
+
ItemDataByUID,
|
|
92
|
+
ItemSelection,
|
|
93
|
+
ItemType,
|
|
94
|
+
ItemTypeProvider,
|
|
95
|
+
ItemView,
|
|
96
|
+
ItemViewGetMissing,
|
|
97
|
+
JSONItemCache,
|
|
98
|
+
Link,
|
|
99
|
+
SpecTypeProvider,
|
|
100
|
+
create_unique_link,
|
|
101
|
+
data_digest,
|
|
102
|
+
is_enabled,
|
|
103
|
+
is_enabled_with_ops,
|
|
104
|
+
item_is_enabled,
|
|
105
|
+
link_is_enabled,
|
|
106
|
+
load_data,
|
|
107
|
+
load_data_by_uid,
|
|
108
|
+
pickle_load_data_by_uid,
|
|
109
|
+
save_data,
|
|
110
|
+
to_collection,
|
|
111
|
+
to_iterable,
|
|
112
|
+
)
|
|
113
|
+
from .itemmapper import (
|
|
114
|
+
ItemGetValue,
|
|
115
|
+
ItemGetValueContext,
|
|
116
|
+
ItemGetValueMap,
|
|
117
|
+
ItemMapper,
|
|
118
|
+
ItemValueProvider,
|
|
119
|
+
get_value_default,
|
|
120
|
+
unpack_arg,
|
|
121
|
+
)
|
|
122
|
+
from .specdoc import SpecDocumentConfig, generate_specification_documentation
|
|
123
|
+
from .specverify import (
|
|
124
|
+
SpecVerifier,
|
|
125
|
+
VerifyStatus,
|
|
126
|
+
verify_specification_format,
|
|
127
|
+
)
|
|
128
|
+
from .subprocessaction import (
|
|
129
|
+
make_subprocess_environment,
|
|
130
|
+
run_subprocess_action,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
__all__ = [
|
|
134
|
+
"BibTeXCitationProvider",
|
|
135
|
+
"Content",
|
|
136
|
+
"ContentAddContext",
|
|
137
|
+
"Copyright",
|
|
138
|
+
"Copyrights",
|
|
139
|
+
"DocumentGlossaryConfig",
|
|
140
|
+
"EmptyItem",
|
|
141
|
+
"EmptyItemCache",
|
|
142
|
+
"EnabledSet",
|
|
143
|
+
"GenericContent",
|
|
144
|
+
"GenericContentIterable",
|
|
145
|
+
"GlossaryConfig",
|
|
146
|
+
"IS_ENABLED_OPS",
|
|
147
|
+
"IsEnabled",
|
|
148
|
+
"IsLinkEnabled",
|
|
149
|
+
"Item",
|
|
150
|
+
"ItemCache",
|
|
151
|
+
"ItemCacheConfig",
|
|
152
|
+
"ItemDataByUID",
|
|
153
|
+
"ItemGetValue",
|
|
154
|
+
"ItemGetValueContext",
|
|
155
|
+
"ItemGetValueMap",
|
|
156
|
+
"ItemMapper",
|
|
157
|
+
"ItemSelection",
|
|
158
|
+
"ItemType",
|
|
159
|
+
"ItemTypeProvider",
|
|
160
|
+
"ItemValueProvider",
|
|
161
|
+
"ItemView",
|
|
162
|
+
"ItemViewGetMissing",
|
|
163
|
+
"JSONItemCache",
|
|
164
|
+
"Link",
|
|
165
|
+
"MARKDOWN_ROLES",
|
|
166
|
+
"MarkdownContent",
|
|
167
|
+
"MarkdownMapper",
|
|
168
|
+
"SpecDocumentConfig",
|
|
169
|
+
"SpecTypeProvider",
|
|
170
|
+
"SpecVerifier",
|
|
171
|
+
"SphinxContent",
|
|
172
|
+
"SphinxMapper",
|
|
173
|
+
"TextContent",
|
|
174
|
+
"TextMapper",
|
|
175
|
+
"VerifyStatus",
|
|
176
|
+
"augment_glossary_terms",
|
|
177
|
+
"base64_to_hex",
|
|
178
|
+
"base64_to_hex_text",
|
|
179
|
+
"create_argument_parser",
|
|
180
|
+
"create_config",
|
|
181
|
+
"create_unique_link",
|
|
182
|
+
"data_digest",
|
|
183
|
+
"escape_code_line",
|
|
184
|
+
"generate_glossary",
|
|
185
|
+
"generate_specification_documentation",
|
|
186
|
+
"get_reference",
|
|
187
|
+
"get_value_default",
|
|
188
|
+
"get_value_plural",
|
|
189
|
+
"get_value_subprocess",
|
|
190
|
+
"hash_file",
|
|
191
|
+
"hash_file_lines",
|
|
192
|
+
"hash_file_lines_md5",
|
|
193
|
+
"hash_file_lines_sha256",
|
|
194
|
+
"hash_file_md5",
|
|
195
|
+
"hash_file_sha256",
|
|
196
|
+
"init_logging",
|
|
197
|
+
"is_enabled",
|
|
198
|
+
"is_enabled_with_ops",
|
|
199
|
+
"item_is_enabled",
|
|
200
|
+
"latex_escape",
|
|
201
|
+
"link_is_enabled",
|
|
202
|
+
"list_terms",
|
|
203
|
+
"load_config",
|
|
204
|
+
"load_data",
|
|
205
|
+
"load_data_by_uid",
|
|
206
|
+
"make_copyright_statement",
|
|
207
|
+
"make_label",
|
|
208
|
+
"make_subprocess_environment",
|
|
209
|
+
"pickle_load_data_by_uid",
|
|
210
|
+
"run_subprocess_action",
|
|
211
|
+
"save_data",
|
|
212
|
+
"split_copyright_statement",
|
|
213
|
+
"to_camel_case",
|
|
214
|
+
"to_collection",
|
|
215
|
+
"to_iterable",
|
|
216
|
+
"unpack_arg",
|
|
217
|
+
"verify_specification_format",
|
|
218
|
+
]
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
""" Provides an item value provider for citations. """
|
|
3
|
+
|
|
4
|
+
# Copyright (C) 2025, 2026 embedded brains GmbH & Co. KG
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted provided that the following conditions
|
|
8
|
+
# are met:
|
|
9
|
+
# 1. Redistributions of source code must retain the above copyright
|
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
|
14
|
+
#
|
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
18
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
19
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
20
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
21
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
22
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
23
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
24
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
25
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
26
|
+
|
|
27
|
+
from typing import Callable
|
|
28
|
+
|
|
29
|
+
from .items import Item
|
|
30
|
+
from .itemmapper import ItemGetValueContext, ItemType, ItemValueProvider
|
|
31
|
+
from .content import list_terms
|
|
32
|
+
from .contenttext import TextContent, TextMapper, latex_escape
|
|
33
|
+
|
|
34
|
+
_Fields = dict[str, str | list[str]]
|
|
35
|
+
_GetFields = Callable[[Item], tuple[str, _Fields]]
|
|
36
|
+
|
|
37
|
+
_FIELDS = {
|
|
38
|
+
"author", "booktitle", "chapter", "doi", "edition", "editor",
|
|
39
|
+
"howpublished", "institution", "journal", "month", "note", "number",
|
|
40
|
+
"organization", "pages", "publisher", "school", "series", "title",
|
|
41
|
+
"volume", "year"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
_NO_LATEX_ESCAPE = {"url"}
|
|
45
|
+
|
|
46
|
+
_DOUBLE_QUOTE = {
|
|
47
|
+
"author", "booktitle", "editor", "howpublished", "institution",
|
|
48
|
+
"organization", "publisher", "school", "title"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
_PERSONS = {"author", "editor"}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _get_fields(item: Item) -> tuple[str, _Fields]:
|
|
55
|
+
_, _, publication_type = item.type.partition("/")
|
|
56
|
+
fields: _Fields = dict(
|
|
57
|
+
(key, item[key]) for key in _FIELDS.intersection(item.data.keys()))
|
|
58
|
+
url = item.get("work-url", None)
|
|
59
|
+
if url is not None:
|
|
60
|
+
fields["url"] = url
|
|
61
|
+
return publication_type, fields
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class BibTeXCitationProvider(ItemValueProvider):
|
|
65
|
+
""" Provides citation values and BibTeX entries. """
|
|
66
|
+
|
|
67
|
+
def __init__(self, mapper: TextMapper) -> None:
|
|
68
|
+
super().__init__(mapper)
|
|
69
|
+
self._citations: set[Item] = set()
|
|
70
|
+
self._get_fields: dict[str, _GetFields] = {}
|
|
71
|
+
mapper.add_get_value("reference:/cite", self._get_cite)
|
|
72
|
+
mapper.add_get_value("reference:/cite-long", self._get_cite_long)
|
|
73
|
+
|
|
74
|
+
def reset(self) -> None:
|
|
75
|
+
self._citations.clear()
|
|
76
|
+
|
|
77
|
+
def get_cite_group(self, ctx: ItemGetValueContext) -> str:
|
|
78
|
+
"""
|
|
79
|
+
Get the citations associated with the citation group key provided by
|
|
80
|
+
the arguments of the context.
|
|
81
|
+
"""
|
|
82
|
+
citations: list[str] = []
|
|
83
|
+
for link in ctx.item.links_to_children("citation-group-member"):
|
|
84
|
+
if link["citation-group-key"] == ctx.args:
|
|
85
|
+
citations.append(f"${{{link.uid}:/cite}}")
|
|
86
|
+
return ctx.substitute(list_terms(citations))
|
|
87
|
+
|
|
88
|
+
def get_bibtex_entries(self, ctx: ItemGetValueContext) -> str:
|
|
89
|
+
""" Get the BibTeX entries for the collected citations. """
|
|
90
|
+
mapper = ctx.mapper
|
|
91
|
+
assert isinstance(mapper, TextMapper)
|
|
92
|
+
content = mapper.create_content()
|
|
93
|
+
self.add_bibtex_entries(content)
|
|
94
|
+
return content.join()
|
|
95
|
+
|
|
96
|
+
def _add_get_fields_for_subtypes(self, spec_type: ItemType, type_path: str,
|
|
97
|
+
get_fields: _GetFields) -> None:
|
|
98
|
+
if spec_type.refinements:
|
|
99
|
+
for key, refinement in spec_type.refinements.items():
|
|
100
|
+
self._add_get_fields_for_subtypes(refinement,
|
|
101
|
+
f"{type_path}/{key}",
|
|
102
|
+
get_fields)
|
|
103
|
+
else:
|
|
104
|
+
self._get_fields[type_path] = get_fields
|
|
105
|
+
|
|
106
|
+
def add_get_fields(self, item_type: str, get_fields: _GetFields) -> None:
|
|
107
|
+
""" Add the get fields method for the item type. """
|
|
108
|
+
self.mapper.add_get_value(f"{item_type}:/cite", self._get_cite)
|
|
109
|
+
self.mapper.add_get_value(f"{item_type}:/cite-long",
|
|
110
|
+
self._get_cite_long)
|
|
111
|
+
spec_type = self.mapper.item.cache.type_provider.root_type
|
|
112
|
+
for name in item_type.split("/"):
|
|
113
|
+
spec_type = spec_type.refinements[name]
|
|
114
|
+
self._add_get_fields_for_subtypes(spec_type, item_type, get_fields)
|
|
115
|
+
|
|
116
|
+
def add_bibtex_entries(self, content: TextContent) -> None:
|
|
117
|
+
""" Add BibTeX entries for the collected citations to the content. """
|
|
118
|
+
for item in sorted(self._citations):
|
|
119
|
+
publication_type, fields = self._get_fields.get(
|
|
120
|
+
item.type, _get_fields)(item)
|
|
121
|
+
for key in _PERSONS.intersection(fields.keys()):
|
|
122
|
+
if isinstance(fields[key], list):
|
|
123
|
+
fields[key] = " and ".join(fields[key])
|
|
124
|
+
content.append(f"@{publication_type}{{{item.ident},")
|
|
125
|
+
for field, value in sorted(fields.items()):
|
|
126
|
+
assert isinstance(value, str)
|
|
127
|
+
value = self.mapper.substitute(value)
|
|
128
|
+
if field not in _NO_LATEX_ESCAPE:
|
|
129
|
+
value = latex_escape(value)
|
|
130
|
+
if field in _DOUBLE_QUOTE:
|
|
131
|
+
value = f"{{{value}}}"
|
|
132
|
+
content.append(f" {field} = {{{value}}},")
|
|
133
|
+
content.append("}")
|
|
134
|
+
|
|
135
|
+
def _get_cite(self, ctx: ItemGetValueContext) -> str:
|
|
136
|
+
self._citations.add(ctx.item)
|
|
137
|
+
assert isinstance(self.mapper, TextMapper)
|
|
138
|
+
content = self.mapper.create_content()
|
|
139
|
+
return content.cite(ctx.item.ident)
|
|
140
|
+
|
|
141
|
+
def _get_cite_long(self, ctx: ItemGetValueContext) -> str:
|
|
142
|
+
self._citations.add(ctx.item)
|
|
143
|
+
_, fields = self._get_fields.get(ctx.item.type, _get_fields)(ctx.item)
|
|
144
|
+
assert isinstance(self.mapper, TextMapper)
|
|
145
|
+
content = self.mapper.create_content()
|
|
146
|
+
title = fields["title"]
|
|
147
|
+
assert isinstance(title, str)
|
|
148
|
+
title = content.emphasize(ctx.substitute_and_transform(title))
|
|
149
|
+
return f"{title} {content.cite(ctx.item.ident)}"
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
""" Provides a command line interface to hash a list of files. """
|
|
3
|
+
|
|
4
|
+
# Copyright (C) 2023, 2026 embedded brains GmbH & Co. KG
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted provided that the following conditions
|
|
8
|
+
# are met:
|
|
9
|
+
# 1. Redistributions of source code must retain the above copyright
|
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
|
14
|
+
#
|
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
18
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
19
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
20
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
21
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
22
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
23
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
24
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
25
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
26
|
+
|
|
27
|
+
import argparse
|
|
28
|
+
import sys
|
|
29
|
+
|
|
30
|
+
from .hashutil import (base64_to_hex, hash_file, hash_file_lines,
|
|
31
|
+
hash_file_md5, hash_file_lines_md5, hash_file_sha256,
|
|
32
|
+
hash_file_lines_sha256)
|
|
33
|
+
|
|
34
|
+
_HASH_FILE = {
|
|
35
|
+
"MD5": hash_file_md5,
|
|
36
|
+
"SHA256": hash_file_sha256,
|
|
37
|
+
"SHA512": hash_file
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
_HASH_FILE_LINES = {
|
|
41
|
+
"MD5": hash_file_lines_md5,
|
|
42
|
+
"SHA256": hash_file_lines_sha256,
|
|
43
|
+
"SHA512": hash_file_lines
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _identity(digest: str) -> str:
|
|
48
|
+
return digest
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
_FORMATTER = {"base64url": _identity, "hex": base64_to_hex}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def clihash(argv: list[str] = sys.argv) -> None:
|
|
55
|
+
""" Hash the list of files. """
|
|
56
|
+
parser = argparse.ArgumentParser()
|
|
57
|
+
parser.add_argument('--algorithm',
|
|
58
|
+
choices=["MD5", "SHA256", "SHA512"],
|
|
59
|
+
type=str.upper,
|
|
60
|
+
default="SHA512",
|
|
61
|
+
help="hash algorithm (default: SHA512)")
|
|
62
|
+
parser.add_argument('--format',
|
|
63
|
+
choices=["base64url", "hex"],
|
|
64
|
+
type=str.lower,
|
|
65
|
+
default="base64url",
|
|
66
|
+
help="digest format (default: base64url)")
|
|
67
|
+
parser.add_argument('--line',
|
|
68
|
+
action="append",
|
|
69
|
+
default=None,
|
|
70
|
+
help=("hash line B (format: B) or lines "
|
|
71
|
+
"from B to E excluding E (format B:E); "
|
|
72
|
+
"the line numbering starts with one"))
|
|
73
|
+
parser.add_argument("files",
|
|
74
|
+
metavar="FILES",
|
|
75
|
+
nargs="+",
|
|
76
|
+
help="the files to hash")
|
|
77
|
+
args = parser.parse_args(argv[1:])
|
|
78
|
+
formatter = _FORMATTER[args.format]
|
|
79
|
+
if args.line:
|
|
80
|
+
lines: list[tuple[int, int]] = []
|
|
81
|
+
do_hash_file_lines = _HASH_FILE_LINES[args.algorithm]
|
|
82
|
+
for line in args.line:
|
|
83
|
+
begin, _, end = line.partition(":")
|
|
84
|
+
if not end:
|
|
85
|
+
end = int(begin) + 1
|
|
86
|
+
lines.append((int(begin), int(end)))
|
|
87
|
+
for path in args.files:
|
|
88
|
+
print(path, formatter(do_hash_file_lines(path, lines)))
|
|
89
|
+
else:
|
|
90
|
+
do_hash_file = _HASH_FILE[args.algorithm]
|
|
91
|
+
for path in args.files:
|
|
92
|
+
print(path, formatter(do_hash_file(path)))
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
"""
|
|
3
|
+
Provides a command line interface to convert specification items inside
|
|
4
|
+
specification directories to a pickle data file.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# Copyright (C) 2025 embedded brains GmbH & Co. KG
|
|
8
|
+
#
|
|
9
|
+
# Redistribution and use in source and binary forms, with or without
|
|
10
|
+
# modification, are permitted provided that the following conditions
|
|
11
|
+
# are met:
|
|
12
|
+
# 1. Redistributions of source code must retain the above copyright
|
|
13
|
+
# notice, this list of conditions and the following disclaimer.
|
|
14
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
|
15
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
16
|
+
# documentation and/or other materials provided with the distribution.
|
|
17
|
+
#
|
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
21
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
22
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
23
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
24
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
25
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
26
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
27
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
28
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
29
|
+
|
|
30
|
+
import argparse
|
|
31
|
+
import os
|
|
32
|
+
import pickle
|
|
33
|
+
import sys
|
|
34
|
+
|
|
35
|
+
from .items import ItemCache, ItemCacheConfig
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _filter(data: dict) -> dict:
|
|
39
|
+
return dict((key, value) for key, value in sorted(data.items())
|
|
40
|
+
if not key.startswith("_"))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def clipickle(argv: list[str] = sys.argv) -> None:
|
|
44
|
+
"""
|
|
45
|
+
Convert specification items inside specification directories to a pickle
|
|
46
|
+
data file.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
parser = argparse.ArgumentParser()
|
|
50
|
+
parser.add_argument("specdirs",
|
|
51
|
+
metavar="SPECIFICATION_DIRECTORIES",
|
|
52
|
+
nargs="+",
|
|
53
|
+
help="a non-empty list of specification directories")
|
|
54
|
+
parser.add_argument("pickle",
|
|
55
|
+
metavar="PICKLE",
|
|
56
|
+
nargs=1,
|
|
57
|
+
help="the pickle file to generate")
|
|
58
|
+
args = parser.parse_args(argv[1:])
|
|
59
|
+
config = ItemCacheConfig(paths=args.specdirs, initialize_links=False)
|
|
60
|
+
item_cache = ItemCache(config)
|
|
61
|
+
data = dict(
|
|
62
|
+
(uid, _filter(item.data)) for uid, item in sorted(item_cache.items()))
|
|
63
|
+
pickle_file = args.pickle[0]
|
|
64
|
+
os.makedirs(os.path.dirname(pickle_file), exist_ok=True)
|
|
65
|
+
with open(pickle_file, "wb") as out:
|
|
66
|
+
pickle.dump(data, out)
|