specitems 1.7.0__tar.gz → 1.7.2__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.7.0 → specitems-1.7.2}/PKG-INFO +1 -1
- {specitems-1.7.0 → specitems-1.7.2}/pyproject.toml +1 -1
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/__init__.py +11 -4
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/cite.py +108 -10
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/spec.pickle +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/specconfig.py +38 -2
- {specitems-1.7.0 → specitems-1.7.2}/README.md +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/clangformat.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/clihash.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/clipickle.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/clispecdoc.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/clitypeview.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/cliutil.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/cliverify.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/cliyamlquery.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/content.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/contentcommonmark.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/contentmarkdown.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/contentsphinx.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/contenttext.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/copyrights.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/getvaluesubprocess.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/glossary.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/hashutil.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/itemmapper.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/items.py +1 -1
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/licenseinfo.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/py.typed +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/spdx.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/specdoc.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/specformatter.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/specverify.py +0 -0
- {specitems-1.7.0 → specitems-1.7.2}/src/specitems/subprocessaction.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specitems
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.2
|
|
4
4
|
Summary: Provides interfaces to work with specification items.
|
|
5
5
|
Keywords: certification,documentation,markdown,qualification,requirements-management,traceability
|
|
6
6
|
Author: The specitems Authors
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
25
25
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
26
26
|
|
|
27
|
-
from .cite import BibTeXCitationProvider
|
|
27
|
+
from .cite import (BibTeXCitationProvider, get_reference_target,
|
|
28
|
+
get_reference_work, make_anchor, ReferenceTarget)
|
|
28
29
|
from .clangformat import ClangFormatter
|
|
29
30
|
from .cliutil import (
|
|
30
31
|
LoggingStatus,
|
|
@@ -144,9 +145,10 @@ from .itemmapper import (
|
|
|
144
145
|
from .licenseinfo import (LicenseAggregate, LicenseEntry, LicenseProvider)
|
|
145
146
|
from .spdx import (get_license_list_version, parse_license_expression,
|
|
146
147
|
parse_license_identifier, permits)
|
|
147
|
-
from .specconfig import (CONFIG_FILE, CONFIG_UID,
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
from .specconfig import (CONFIG_FILE, CONFIG_UID, add_inline_items,
|
|
149
|
+
check_license_items, create_content_context,
|
|
150
|
+
create_type_provider, find_config_file,
|
|
151
|
+
load_config_item, yield_tasks)
|
|
150
152
|
from .specdoc import (SpecDocumentConfig, add_specification_documentation,
|
|
151
153
|
generate_specification_documentation)
|
|
152
154
|
from .specformatter import SpecYAMLFormatter
|
|
@@ -207,6 +209,7 @@ __all__ = [
|
|
|
207
209
|
"MarkdownContent",
|
|
208
210
|
"MarkdownMapper",
|
|
209
211
|
"ROW_SPAN",
|
|
212
|
+
"ReferenceTarget",
|
|
210
213
|
"SpecDocumentConfig",
|
|
211
214
|
"SpecTypeProvider",
|
|
212
215
|
"SpecVerifier",
|
|
@@ -216,6 +219,7 @@ __all__ = [
|
|
|
216
219
|
"SubstitutionError",
|
|
217
220
|
"TextContent",
|
|
218
221
|
"TextMapper",
|
|
222
|
+
"add_inline_items",
|
|
219
223
|
"add_license_arguments",
|
|
220
224
|
"add_specification_documentation",
|
|
221
225
|
"atomic_dump_to_file",
|
|
@@ -238,6 +242,8 @@ __all__ = [
|
|
|
238
242
|
"get_item_cache_arguments",
|
|
239
243
|
"get_license_list_version",
|
|
240
244
|
"get_reference",
|
|
245
|
+
"get_reference_target",
|
|
246
|
+
"get_reference_work",
|
|
241
247
|
"get_value_default",
|
|
242
248
|
"get_value_plural",
|
|
243
249
|
"get_value_subprocess",
|
|
@@ -258,6 +264,7 @@ __all__ = [
|
|
|
258
264
|
"load_config_item",
|
|
259
265
|
"load_data",
|
|
260
266
|
"load_data_by_uid",
|
|
267
|
+
"make_anchor",
|
|
261
268
|
"make_copyright_statement",
|
|
262
269
|
"make_label",
|
|
263
270
|
"make_lines",
|
|
@@ -24,9 +24,11 @@
|
|
|
24
24
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
25
25
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
import dataclasses
|
|
28
|
+
import re
|
|
29
|
+
from typing import Callable, Optional
|
|
28
30
|
|
|
29
|
-
from .items import Item
|
|
31
|
+
from .items import Item, Link
|
|
30
32
|
from .itemmapper import ItemGetValueContext, ItemType, ItemValueProvider
|
|
31
33
|
from .content import list_terms
|
|
32
34
|
from .contenttext import TextContent, TextMapper, latex_escape
|
|
@@ -50,6 +52,79 @@ _DOUBLE_QUOTE = {
|
|
|
50
52
|
|
|
51
53
|
_PERSONS = {"author", "editor"}
|
|
52
54
|
|
|
55
|
+
_NOT_ID_CHARS = re.compile(r"[^a-z0-9]+")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def make_anchor(label: str) -> str:
|
|
59
|
+
"""
|
|
60
|
+
Make the anchor of the label in the way Sphinx makes the identifier of a
|
|
61
|
+
label target.
|
|
62
|
+
"""
|
|
63
|
+
return _NOT_ID_CHARS.sub("-", label.lower()).strip("-")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@dataclasses.dataclass
|
|
67
|
+
class ReferenceTarget:
|
|
68
|
+
""" Represents the target of a reference link. """
|
|
69
|
+
|
|
70
|
+
# pylint: disable=too-many-instance-attributes
|
|
71
|
+
|
|
72
|
+
#: The referenced work.
|
|
73
|
+
work: Item
|
|
74
|
+
|
|
75
|
+
#: The name of the area within the work.
|
|
76
|
+
name: Optional[str]
|
|
77
|
+
|
|
78
|
+
#: The label of the area within the work.
|
|
79
|
+
label: Optional[str]
|
|
80
|
+
|
|
81
|
+
#: The location of the area within the work.
|
|
82
|
+
location: Optional[str]
|
|
83
|
+
|
|
84
|
+
#: The path of the area relative to the base URL of the work.
|
|
85
|
+
path: str
|
|
86
|
+
|
|
87
|
+
#: The URL of the area. The caller substitutes it in the context of the
|
|
88
|
+
#: work.
|
|
89
|
+
url: Optional[str]
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def get_reference_work(item: Item) -> Item:
|
|
93
|
+
"""
|
|
94
|
+
Get the referenced work of the reference or reference location item.
|
|
95
|
+
"""
|
|
96
|
+
if item.type == "reference-location":
|
|
97
|
+
works = list(item.parents("reference-location"))
|
|
98
|
+
if len(works) != 1:
|
|
99
|
+
raise ValueError(f"{item.uid}: a reference location shall have "
|
|
100
|
+
"exactly one link to the referenced work")
|
|
101
|
+
return works[0]
|
|
102
|
+
return item
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def get_reference_target(item: Item,
|
|
106
|
+
link: Optional[Link] = None) -> ReferenceTarget:
|
|
107
|
+
"""
|
|
108
|
+
Get the target of the reference or reference location item.
|
|
109
|
+
|
|
110
|
+
The attributes of the optional reference link take precedence over the
|
|
111
|
+
attributes of the reference location. The paths of the reference location
|
|
112
|
+
and the reference link are concatenated.
|
|
113
|
+
"""
|
|
114
|
+
work = get_reference_work(item)
|
|
115
|
+
link_data = {} if link is None else link.data
|
|
116
|
+
area = item.data if item is not work else {}
|
|
117
|
+
name = area.get("name")
|
|
118
|
+
label = link_data.get("label", area.get("label"))
|
|
119
|
+
location = link_data.get("location", area.get("location"))
|
|
120
|
+
path = f"{area.get('path', '')}{link_data.get('path', '')}"
|
|
121
|
+
base = work.get("work-base-url")
|
|
122
|
+
url: Optional[str] = None
|
|
123
|
+
if base is not None:
|
|
124
|
+
anchor = "" if label is None else f"#{make_anchor(label)}"
|
|
125
|
+
url = f"{base}{path}{anchor}"
|
|
126
|
+
return ReferenceTarget(work, name, label, location, path, url)
|
|
127
|
+
|
|
53
128
|
|
|
54
129
|
def _get_fields(item: Item) -> tuple[str, _Fields]:
|
|
55
130
|
_, _, publication_type = item.type.partition("/")
|
|
@@ -70,6 +145,10 @@ class BibTeXCitationProvider(ItemValueProvider):
|
|
|
70
145
|
self._get_fields: dict[str, _GetFields] = {}
|
|
71
146
|
mapper.add_get_value("reference:/cite", self._get_cite)
|
|
72
147
|
mapper.add_get_value("reference:/cite-long", self._get_cite_long)
|
|
148
|
+
mapper.add_get_value("reference-location:/cite",
|
|
149
|
+
self._get_cite_location)
|
|
150
|
+
mapper.add_get_value("reference-location:/cite-long",
|
|
151
|
+
self._get_cite_long_location)
|
|
73
152
|
|
|
74
153
|
def reset(self) -> None:
|
|
75
154
|
self._citations.clear()
|
|
@@ -135,18 +214,37 @@ class BibTeXCitationProvider(ItemValueProvider):
|
|
|
135
214
|
content.append(f" {field} = {{{value}}},")
|
|
136
215
|
content.append("}")
|
|
137
216
|
|
|
138
|
-
def
|
|
139
|
-
self._citations.add(
|
|
217
|
+
def _cite(self, work: Item) -> str:
|
|
218
|
+
self._citations.add(work)
|
|
140
219
|
assert isinstance(self.mapper, TextMapper)
|
|
141
220
|
content = self.mapper.create_content()
|
|
142
|
-
return content.cite(
|
|
221
|
+
return content.cite(work.ident)
|
|
143
222
|
|
|
144
|
-
def
|
|
145
|
-
|
|
146
|
-
_, fields = self.get_fields(
|
|
223
|
+
def _cite_long(self, ctx: ItemGetValueContext, work: Item,
|
|
224
|
+
name: Optional[str]) -> str:
|
|
225
|
+
_, fields = self.get_fields(work)
|
|
147
226
|
assert isinstance(self.mapper, TextMapper)
|
|
148
227
|
content = self.mapper.create_content()
|
|
149
228
|
title = fields["title"]
|
|
150
229
|
assert isinstance(title, str)
|
|
151
|
-
|
|
152
|
-
|
|
230
|
+
if work is ctx.item:
|
|
231
|
+
title = ctx.substitute(title)
|
|
232
|
+
else:
|
|
233
|
+
title = self.mapper.substitute_data(title, work)
|
|
234
|
+
title = content.emphasize(ctx.transform(title))
|
|
235
|
+
if name is not None:
|
|
236
|
+
title = f"{title}, {ctx.substitute_and_transform(name)}"
|
|
237
|
+
return f"{title} {self._cite(work)}"
|
|
238
|
+
|
|
239
|
+
def _get_cite(self, ctx: ItemGetValueContext) -> str:
|
|
240
|
+
return self._cite(ctx.item)
|
|
241
|
+
|
|
242
|
+
def _get_cite_long(self, ctx: ItemGetValueContext) -> str:
|
|
243
|
+
return self._cite_long(ctx, ctx.item, None)
|
|
244
|
+
|
|
245
|
+
def _get_cite_location(self, ctx: ItemGetValueContext) -> str:
|
|
246
|
+
return self._cite(get_reference_work(ctx.item))
|
|
247
|
+
|
|
248
|
+
def _get_cite_long_location(self, ctx: ItemGetValueContext) -> str:
|
|
249
|
+
return self._cite_long(ctx, get_reference_work(ctx.item),
|
|
250
|
+
ctx.item.get("name"))
|
|
Binary file
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
25
25
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
26
26
|
|
|
27
|
+
import copy
|
|
27
28
|
import logging
|
|
28
29
|
from pathlib import Path
|
|
29
30
|
from typing import Any, Iterator, Optional
|
|
@@ -31,8 +32,8 @@ from typing import Any, Iterator, Optional
|
|
|
31
32
|
from .cliutil import load_config
|
|
32
33
|
from .content import ContentContext
|
|
33
34
|
from .licenseinfo import LicenseAggregate, LicenseProvider
|
|
34
|
-
from .items import (EmptyItemCache, Item,
|
|
35
|
-
SpecTypeProvider)
|
|
35
|
+
from .items import (EmptyItemCache, Item, ItemCache, ItemDataByUID,
|
|
36
|
+
ItemTypeProvider, SpecTypeProvider)
|
|
36
37
|
from .specverify import SpecVerifier
|
|
37
38
|
|
|
38
39
|
#: The name of the configuration file of a tree.
|
|
@@ -204,6 +205,41 @@ def check_license_items(config: Item, provider: LicenseProvider) -> None:
|
|
|
204
205
|
raise ValueError("\n".join(errors))
|
|
205
206
|
|
|
206
207
|
|
|
208
|
+
def add_inline_items(config: Item, item_cache: ItemCache) -> None:
|
|
209
|
+
"""
|
|
210
|
+
Add the inline items of the configuration to the item cache.
|
|
211
|
+
|
|
212
|
+
An inline item is part of the configuration file. It takes the license
|
|
213
|
+
and the copyrights of the configuration item, unless it states its own.
|
|
214
|
+
An inline item without links gets an empty list of links. An inline item
|
|
215
|
+
without an enabled-by attribute is enabled. An inline item without a type
|
|
216
|
+
has the inline type. An inline item may link to another inline item.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
config: The configuration item.
|
|
220
|
+
item_cache: The item cache of the tree.
|
|
221
|
+
|
|
222
|
+
Raises:
|
|
223
|
+
ValueError: An inline item exists already in the item cache or in the
|
|
224
|
+
configuration.
|
|
225
|
+
"""
|
|
226
|
+
data_by_uid: ItemDataByUID = {}
|
|
227
|
+
for entry in config.get("inline-items", []):
|
|
228
|
+
uid = entry["uid"]
|
|
229
|
+
if (uid in item_cache or uid in item_cache.proxies
|
|
230
|
+
or uid in data_by_uid):
|
|
231
|
+
raise ValueError(f"the inline item {uid} exists already")
|
|
232
|
+
data = copy.deepcopy(entry["data"])
|
|
233
|
+
for key, value in (("SPDX-License-Identifier",
|
|
234
|
+
config["SPDX-License-Identifier"]),
|
|
235
|
+
("copyrights", config["copyrights"]),
|
|
236
|
+
("enabled-by", True), ("links", []), ("type",
|
|
237
|
+
"inline")):
|
|
238
|
+
data.setdefault(key, copy.deepcopy(value))
|
|
239
|
+
data_by_uid[uid] = data
|
|
240
|
+
item_cache.add_items(data_by_uid)
|
|
241
|
+
|
|
242
|
+
|
|
207
243
|
def yield_tasks(config: Item, task_type: str) -> Iterator[dict]:
|
|
208
244
|
"""
|
|
209
245
|
Yield the tasks of the type in the order of the configuration.
|
|
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
|
|
@@ -1215,11 +1215,11 @@ class ItemCache(dict):
|
|
|
1215
1215
|
data_by_uid.update(
|
|
1216
1216
|
load_data_by_uid(path, self._cache_directory, uid_prefix,
|
|
1217
1217
|
the_format))
|
|
1218
|
-
self.add_items(data_by_uid, config.initialize_links, False)
|
|
1219
1218
|
if type_provider is None:
|
|
1220
1219
|
type_provider = ItemTypeProvider(data_by_uid,
|
|
1221
1220
|
config.spec_type_root_uid)
|
|
1222
1221
|
self.type_provider = type_provider
|
|
1222
|
+
self.add_items(data_by_uid, config.initialize_links, False)
|
|
1223
1223
|
for item in self.values():
|
|
1224
1224
|
self.type_provider.set_type(item)
|
|
1225
1225
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|