1 | 1 | from typing import Dict, Optional |
|
2 | |||
3 | 1 | from cleo.io.io import IO |
|
4 | |||
5 | 1 | from sdoc.sdoc2 import in_scope, out_scope |
|
6 | 1 | from sdoc.sdoc2.node.DateNode import DateNode |
|
7 | 1 | from sdoc.sdoc2.node.Node import Node |
|
8 | 1 | from sdoc.sdoc2.node.TitleNode import TitleNode |
|
9 | 1 | from sdoc.sdoc2.node.VersionNode import VersionNode |
|
10 | 1 | from sdoc.sdoc2.NodeStore import NodeStore |
|
11 | |||
12 | |||
13 | 1 | View Code Duplication | class DocumentNode(Node): |
0 ignored issues
–
show
Duplication
introduced
by
![]() |
|||
14 | """ |
||
15 | SDoc2 node for documents. |
||
16 | """ |
||
17 | |||
18 | # ------------------------------------------------------------------------------------------------------------------ |
||
19 | 1 | def __init__(self, io: IO, options: Dict[str, str]): |
|
20 | """ |
||
21 | Object constructor. |
||
22 | |||
23 | :param OutputStyle io: The IO object. |
||
24 | :param dict[str,str] options: The options of this document. |
||
25 | """ |
||
26 | 1 | super().__init__(io, 'document', options) |
|
27 | |||
28 | 1 | self.title_node_id: Optional[int] = None |
|
29 | """ |
||
30 | The ID of the node the title of the sdoc document. |
||
31 | """ |
||
32 | |||
33 | 1 | self.date_node_id: Optional[int] = None |
|
34 | """ |
||
35 | The ID of the node the date of the sdoc document. |
||
36 | """ |
||
37 | |||
38 | 1 | self.version_node_id: Optional[int] = None |
|
39 | 1 | """ |
|
40 | The ID of the node with the version of the sdoc document. |
||
41 | """ |
||
42 | |||
43 | # ------------------------------------------------------------------------------------------------------------------ |
||
44 | 1 | def get_command(self) -> str: |
|
45 | """ |
||
46 | Returns the command of this node, i.e. document. |
||
47 | """ |
||
48 | 1 | return 'document' |
|
49 | |||
50 | # ------------------------------------------------------------------------------------------------------------------ |
||
51 | 1 | def get_hierarchy_level(self, parent_hierarchy_level: int = -1) -> int: |
|
52 | """ |
||
53 | Returns 0. |
||
54 | """ |
||
55 | 1 | return 0 |
|
56 | |||
57 | # ------------------------------------------------------------------------------------------------------------------ |
||
58 | 1 | def get_hierarchy_name(self) -> str: |
|
59 | """ |
||
60 | Returns 'sectioning'. |
||
61 | """ |
||
62 | 1 | return 'sectioning' |
|
63 | |||
64 | # ------------------------------------------------------------------------------------------------------------------ |
||
65 | 1 | def is_block_command(self) -> bool: |
|
66 | """ |
||
67 | Returns True. |
||
68 | """ |
||
69 | 1 | return True |
|
70 | |||
71 | # ------------------------------------------------------------------------------------------------------------------ |
||
72 | 1 | def is_document_root(self) -> bool: |
|
73 | """ |
||
74 | Returns True. |
||
75 | """ |
||
76 | 1 | return True |
|
77 | |||
78 | # ------------------------------------------------------------------------------------------------------------------ |
||
79 | 1 | def is_inline_command(self) -> bool: |
|
80 | """ |
||
81 | Returns False. |
||
82 | """ |
||
83 | return False |
||
84 | |||
85 | # ------------------------------------------------------------------------------------------------------------------ |
||
86 | 1 | def is_phrasing(self) -> bool: |
|
87 | """ |
||
88 | Returns False. |
||
89 | """ |
||
90 | return False |
||
91 | |||
92 | # ------------------------------------------------------------------------------------------------------------------ |
||
93 | 1 | def prepare_content_tree(self) -> None: |
|
94 | """ |
||
95 | Prepares this node for further processing. |
||
96 | """ |
||
97 | 1 | for node_id in self.child_nodes: |
|
98 | 1 | node = in_scope(node_id) |
|
99 | |||
100 | 1 | node.prepare_content_tree() |
|
101 | 1 | self.__set_document_info(node) |
|
102 | |||
103 | 1 | out_scope(node) |
|
104 | |||
105 | 1 | self.__remove_document_info_nodes() |
|
106 | |||
107 | # ------------------------------------------------------------------------------------------------------------------ |
||
108 | 1 | def __set_document_info(self, node: Node) -> None: |
|
109 | """ |
||
110 | Sets the info of a document (i.e. date, version or title) to DocumentNode attributes. |
||
111 | |||
112 | :param Node node: The current node. |
||
113 | """ |
||
114 | 1 | if isinstance(node, DateNode): |
|
115 | self.__check_document_info(self.date_node_id, node) |
||
116 | self.date_node_id = node.id |
||
117 | |||
118 | 1 | elif isinstance(node, TitleNode): |
|
119 | self.__check_document_info(self.title_node_id, node) |
||
120 | self.title_node_id = node.id |
||
121 | |||
122 | 1 | elif isinstance(node, VersionNode): |
|
123 | self.__check_document_info(self.version_node_id, node) |
||
124 | self.version_node_id = node.id |
||
125 | |||
126 | # ------------------------------------------------------------------------------------------------------------------ |
||
127 | 1 | @staticmethod |
|
128 | 1 | def __check_document_info(info_node_current: Optional[int], info_node_new: Node) -> None: |
|
129 | """ |
||
130 | Checks if a document info node has been set already. If so, an error will be logged. |
||
131 | |||
132 | :param int|None info_node_current: The current document info node (i.e. a property of the document). |
||
133 | :param Node info_node_new: The (new) document info node. |
||
134 | """ |
||
135 | if info_node_current: |
||
136 | node = in_scope(info_node_current) |
||
137 | position = node.position |
||
138 | out_scope(node) |
||
139 | |||
140 | NodeStore.error("Document info {0} can be specified only once. Previous definition at {1}.".format( |
||
141 | info_node_new.name, str(position)), info_node_new) |
||
142 | |||
143 | # ------------------------------------------------------------------------------------------------------------------ |
||
144 | 1 | def __remove_document_info_nodes(self): |
|
145 | """ |
||
146 | Removes the nodes with document info from the list of child nodes. |
||
147 | """ |
||
148 | 1 | obsolete_node_ids = [self.date_node_id, self.title_node_id, self.version_node_id] |
|
149 | 1 | obsolete_node_ids = [node_id for node_id in obsolete_node_ids if node_id is not None] |
|
150 | 1 | self._remove_child_nodes(obsolete_node_ids) |
|
151 | |||
152 | |||
153 | # ---------------------------------------------------------------------------------------------------------------------- |
||
154 | NodeStore.register_block_command('document', DocumentNode) |
||
155 |