Coverage for liitos/meta.py: 99.66%
644 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-05 17:22:35 +00:00
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-05 17:22:35 +00:00
1"""Weave the content of the meta file(s) of metadata.tex.in into the output metadata.tex."""
3import datetime as dti
4import os
5import pathlib
6from typing import Union, no_type_check
8import yaml
10import liitos.gather as gat
11import liitos.template as tpl
12import liitos.tools as too
13from liitos import ENCODING, ExternalsType, KNOWN_APPROVALS_STRATEGIES, LOG_SEPARATOR, PathLike, log
15VALUE_SLOT = 'VALUE.SLOT'
16DOC_BASE = pathlib.Path('..', '..')
17STRUCTURE_PATH = DOC_BASE / 'structure.yml'
18MAGIC_OF_TODAY = 'PUBLICATIONDATE'
19SLASH = '\\'
21WEAVE_DEFAULTS = {
22 'approvals_adjustable_vertical_space': '2.5em',
23 'approvals_strategy': KNOWN_APPROVALS_STRATEGIES[0],
24 'bold_font': 'ITCFranklinGothicStd-Demi',
25 'bold_italic_font': 'ITCFranklinGothicStd-DemiIt',
26 'bookmatter_path': '',
27 'change_log_tune_header_sep': '-0em',
28 'chosen_logo': '/opt/logo/liitos-logo.png',
29 'chosen_title_page_logo': '/opt/logo/liitos-logo.png',
30 'code_fontsize': r'\scriptsize',
31 'driver_path': '',
32 'fixed_font_package': 'sourcecodepro',
33 'font_path': '/opt/fonts/',
34 'font_suffix': '.otf',
35 'footer_frame_note': os.getenv('LIITOS_FOOTER_FRAME_NOTE', ' '), # TODO
36 'footer_outer_field_normal_pages': r'\theMetaPageNumPrefix { } \thepage { }',
37 'italic_font': 'ITCFranklinGothicStd-BookIt',
38 'lox_indent': r'\hspace*{0.40\textwidth}', # old default was '' for left align
39 'main_font': 'ITCFranklinGothicStd-Book',
40 'metadata_path': '',
41 'proprietary_information': '/opt/legal/proprietary-information.txt',
42 'proprietary_information_adjustable_vertical_space': '-0em',
43 'proprietary_information_tune_header_sep': '-0em',
44 'publisher_path': '',
45 'setup_path': '',
46 'stretch': '1.04', # old default was 1.2
47 'table_captions_below': False,
48 'table_uglify': False,
49 'toc_all_dots': '', # old default was not toc all dots, so '%' would restore
50}
51ACROSS = {
52 'eff_font_folder': '',
53 'eff_font_suffix': '',
54}
57@no_type_check
58def load(aspects: dict[str, str], doc_base: Union[PathLike, None] = None) -> Union[gat.Meta, int]:
59 """Best effort loading of meta data.
61 Examples:
63 >>> aspects = {gat.KEY_META: 'missing-file'}
64 >>> load(aspects)
65 1
67 >>> doc_base = pathlib.Path('test/fixtures/basic/')
68 >>> meta_name = 'empty-as-meta.yml'
69 >>> aspects = {gat.KEY_META: meta_name}
70 >>> load(aspects, doc_base)
71 1
73 >>> doc_base = pathlib.Path('.')
74 >>> aspects = {gat.KEY_META: __file__}
75 >>> load(aspects, doc_base)
76 2
78 >>> doc_base = pathlib.Path('test/fixtures/basic/')
79 >>> meta_name = 'space-as-meta.yml'
80 >>> str(doc_base)
81 'test/fixtures/basic'
82 >>> doc_base.is_dir()
83 True
84 >>> (doc_base / meta_name).is_file()
85 True
86 >>> (doc_base / meta_name).stat().st_size
87 1
88 >>> aspects = {gat.KEY_META: meta_name}
89 >>> load(aspects, doc_base)
90 3
92 >>> doc_base = pathlib.Path('test/fixtures/basic/')
93 >>> str(doc_base)
94 'test/fixtures/basic'
95 >>> doc_base.is_dir()
96 True
97 >>> meta_name = 'meta-importing-empty-other-meta.yml'
98 >>> aspects = {gat.KEY_META: meta_name}
99 >>> load(aspects, doc_base)
100 4
101 """
102 doc_base = doc_base if doc_base is not None else DOC_BASE
103 meta_path = doc_base / aspects[gat.KEY_META]
104 if not meta_path.is_file() or not meta_path.stat().st_size:
105 log.error(f'destructure failed to find non-empty meta file at {meta_path}')
106 return 1
107 if meta_path.suffix.lower() not in ('.yaml', '.yml'):
108 return 2
109 with open(meta_path, 'rt', encoding=ENCODING) as handle:
110 metadata = yaml.safe_load(handle)
111 if not metadata:
112 log.error(f'empty metadata file? Please add metadata to ({meta_path})')
113 return 3
114 if 'import' in metadata['document']:
115 base_meta_path = doc_base / metadata['document']['import']
116 if not base_meta_path.is_file() or not base_meta_path.stat().st_size:
117 log.error(
118 f'metadata declares import of base data from ({base_meta_path.name})'
119 f' but failed to find non-empty base file at {base_meta_path}'
120 )
121 return 4
122 with open(base_meta_path, 'rt', encoding=ENCODING) as handle:
123 base_data = yaml.safe_load(handle)
124 for key, value in metadata['document']['patch'].items():
125 base_data['document']['common'][key] = value
126 metadata = base_data
127 with open('metadata.yml', 'wt', encoding=ENCODING) as handle:
128 yaml.dump(metadata, handle, default_flow_style=False)
129 return metadata
132@no_type_check
133def weave_setup_font_path(
134 mapper: dict[str, Union[str, int, bool, None]],
135 text: str,
136) -> str:
137 """Weave in the font_path from mapper or default for driver.
139 Trigger is text.rstrip().endswith('%%_PATCH_%_FONT_%_PATH_%%')
141 Examples:
143 >>> mapper = {'font_path': '/fonts/here/'} # expect warning if folder not present
144 >>> weave_setup_font_path(mapper, 'Path = VALUE.SLOT,%%_PATCH_%_FONT_%_PATH_%%')
145 'Path = /fonts/here/,%%_PATCH_%_FONT_%_PATH_%%'
146 >>> ACROSS['eff_font_folder']
147 '/fonts/here/'
149 >>> mapper = {'no_font_path': 'sorry'}
150 >>> weave_setup_font_path(mapper, 'Path = VALUE.SLOT,%%_PATCH_%_FONT_%_PATH_%%')
151 'Path = /opt/fonts/,%%_PATCH_%_FONT_%_PATH_%%'
152 >>> ACROSS['eff_font_folder']
153 '/opt/fonts/'
154 """
155 defaults = {**WEAVE_DEFAULTS}
156 if mapper.get('font_path'):
157 font_path = mapper.get('font_path')
158 if not pathlib.Path(font_path).is_dir():
159 log.warning(f'font_path ({font_path}) is no directory on this system - rendering may not work as intended')
160 ACROSS['eff_font_folder'] = font_path
161 return text.replace(VALUE_SLOT, font_path)
162 else:
163 log.warning(f'font_path value not set ... setting default ({defaults["font_path"]})')
164 ACROSS['eff_font_folder'] = defaults['font_path']
165 return text.replace(VALUE_SLOT, defaults['font_path'])
168@no_type_check
169def weave_setup_font_suffix(
170 mapper: dict[str, Union[str, int, bool, None]],
171 text: str,
172) -> str:
173 """Weave in the font_suffix from mapper or default for driver.
175 Trigger is text.rstrip().endswith('%%_PATCH_%_FONT_%_SUFFIX_%%')
177 Examples:
179 >>> mapper = {'font_suffix': '.xtf'} # Expect warning because of unknown suffix for fonts
180 >>> weave_setup_font_suffix(mapper, 'Extension = VALUE.SLOT,%%_PATCH_%_FONT_%_SUFFIX_%%')
181 'Extension = .xtf,%%_PATCH_%_FONT_%_SUFFIX_%%'
182 >>> ACROSS['eff_font_suffix']
183 '.xtf'
185 >>> mapper = {'no_font_suffix': 'sorry'}
186 >>> weave_setup_font_suffix(mapper, 'Extension = VALUE.SLOT,%%_PATCH_%_FONT_%_SUFFIX_%%')
187 'Extension = .otf,%%_PATCH_%_FONT_%_SUFFIX_%%'
188 >>> ACROSS['eff_font_suffix']
189 '.otf'
190 """
191 defaults = {**WEAVE_DEFAULTS}
192 if mapper.get('font_suffix'):
193 font_suffix = mapper.get('font_suffix')
194 if font_suffix not in ('.otf', '.ttf'):
195 log.warning(f'font_suffix ({font_suffix}) is unexpected - rendering may not work as intended')
196 ACROSS['eff_font_suffix'] = font_suffix
197 return text.replace(VALUE_SLOT, font_suffix)
198 else:
199 log.warning(f'font_suffix value not set ... setting default ({defaults["font_suffix"]})')
200 ACROSS['eff_font_suffix'] = defaults['font_suffix']
201 return text.replace(VALUE_SLOT, defaults['font_suffix'])
204@no_type_check
205def weave_setup_bold_font(
206 mapper: dict[str, Union[str, int, bool, None]],
207 text: str,
208) -> str:
209 """Weave in the bold_font from mapper or default for driver.
211 Trigger is text.rstrip().endswith('%%_PATCH_%_BOLD_%_FONT_%%')
213 Examples:
215 >>> mapper = {'bold_font': 'MadeUp'} # Expect warning when file does not exist at font path and suffix
216 >>> weave_setup_bold_font(mapper, 'BoldFont={VALUE.SLOT},%%_PATCH_%_BOLD_%_FONT_%%')
217 'BoldFont={MadeUp},%%_PATCH_%_BOLD_%_FONT_%%'
218 >>> assert ACROSS['eff_font_folder'] in ('', WEAVE_DEFAULTS['font_path'])
219 >>> assert ACROSS['eff_font_suffix'] in ('', WEAVE_DEFAULTS['font_suffix'])
221 >>> mapper = {'no_bold_font': 'sorry'}
222 >>> weave_setup_bold_font(mapper, 'BoldFont={VALUE.SLOT},%%_PATCH_%_BOLD_%_FONT_%%')
223 'BoldFont={ITCFranklinGothicStd-Demi},%%_PATCH_%_BOLD_%_FONT_%%'
224 >>> assert ACROSS['eff_font_folder'] in ('', WEAVE_DEFAULTS['font_path'])
225 >>> assert ACROSS['eff_font_suffix'] in ('', WEAVE_DEFAULTS['font_suffix'])
226 """
227 defaults = {**WEAVE_DEFAULTS}
228 eff_font_folder = ACROSS['eff_font_folder']
229 eff_font_suffix = ACROSS['eff_font_suffix']
230 if mapper.get('bold_font'):
231 bold_font = mapper.get('bold_font')
232 font_path = pathlib.Path(eff_font_folder) / f'{bold_font}{eff_font_suffix}'
233 if not font_path.is_file():
234 log.warning(
235 f'bold_font ({bold_font}) is not found'
236 f' as ({font_path}) on this system - rendering may not work as intended'
237 )
238 return text.replace(VALUE_SLOT, bold_font)
239 else:
240 log.warning(f'bold_font value not set ... setting default ({defaults["bold_font"]})')
241 return text.replace(VALUE_SLOT, defaults['bold_font'])
244@no_type_check
245def weave_setup_italic_font(
246 mapper: dict[str, Union[str, int, bool, None]],
247 text: str,
248) -> str:
249 """Weave in the italic_font from mapper or default for driver.
251 Trigger is text.rstrip().endswith('%%_PATCH_%_ITALIC_%_FONT_%%')
253 Examples:
255 >>> mapper = {'italic_font': 'MadeUpToo'} # Expect warning when file does not exist at font path and suffix
256 >>> weave_setup_italic_font(mapper, 'ItalicFont={VALUE.SLOT},%%_PATCH_%_ITALIC_%_FONT_%%')
257 'ItalicFont={MadeUpToo},%%_PATCH_%_ITALIC_%_FONT_%%'
258 >>> assert ACROSS['eff_font_folder'] in ('', WEAVE_DEFAULTS['font_path'])
259 >>> assert ACROSS['eff_font_suffix'] in ('', WEAVE_DEFAULTS['font_suffix'])
261 >>> mapper = {'no_italic_font': 'sorry'}
262 >>> weave_setup_italic_font(mapper, 'ItalicFont={VALUE.SLOT},%%_PATCH_%_ITALIC_%_FONT_%%')
263 'ItalicFont={ITCFranklinGothicStd-BookIt},%%_PATCH_%_ITALIC_%_FONT_%%'
264 >>> assert ACROSS['eff_font_folder'] in ('', WEAVE_DEFAULTS['font_path'])
265 >>> assert ACROSS['eff_font_suffix'] in ('', WEAVE_DEFAULTS['font_suffix'])
266 """
267 defaults = {**WEAVE_DEFAULTS}
268 eff_font_folder = ACROSS['eff_font_folder']
269 eff_font_suffix = ACROSS['eff_font_suffix']
270 if mapper.get('italic_font'):
271 italic_font = mapper.get('italic_font')
272 font_path = pathlib.Path(eff_font_folder) / f'{italic_font}{eff_font_suffix}'
273 if not font_path.is_file():
274 log.warning(
275 f'italic_font ({italic_font}) is not found'
276 f' as ({font_path}) on this system - rendering may not work as intended'
277 )
278 return text.replace(VALUE_SLOT, italic_font)
279 else:
280 log.warning(f'italic_font value not set ... setting default ({defaults["italic_font"]})')
281 return text.replace(VALUE_SLOT, defaults['italic_font'])
284@no_type_check
285def weave_setup_bold_italic_font(
286 mapper: dict[str, Union[str, int, bool, None]],
287 text: str,
288) -> str:
289 """Weave in the bold_italic_font from mapper or default for driver.
291 Trigger is text.rstrip().endswith('%%_PATCH_%_BOLDITALIC_%_FONT_%%')
293 Examples:
295 >>> mapper = {'bold_italic_font': 'AlsoMadeUp'} # Expect warning when file does not exist at font path and suffix
296 >>> weave_setup_bold_italic_font(mapper, 'BoldItalicFont={VALUE.SLOT}%%_PATCH_%_BOLDITALIC_%_FONT_%%')
297 'BoldItalicFont={AlsoMadeUp}%%_PATCH_%_BOLDITALIC_%_FONT_%%'
298 >>> assert ACROSS['eff_font_folder'] in ('', WEAVE_DEFAULTS['font_path'])
299 >>> assert ACROSS['eff_font_suffix'] in ('', WEAVE_DEFAULTS['font_suffix'])
301 >>> mapper = {'no_bold_italic_font': 'sorry'}
302 >>> weave_setup_bold_italic_font(mapper, 'BoldItalicFont={VALUE.SLOT}%%_PATCH_%_BOLDITALIC_%_FONT_%%')
303 'BoldItalicFont={ITCFranklinGothicStd-DemiIt}%%_PATCH_%_BOLDITALIC_%_FONT_%%'
304 >>> assert ACROSS['eff_font_folder'] in ('', WEAVE_DEFAULTS['font_path'])
305 >>> assert ACROSS['eff_font_suffix'] in ('', WEAVE_DEFAULTS['font_suffix'])
306 """
307 defaults = {**WEAVE_DEFAULTS}
308 eff_font_folder = ACROSS['eff_font_folder']
309 eff_font_suffix = ACROSS['eff_font_suffix']
310 if mapper.get('bold_italic_font'):
311 bold_italic_font = mapper.get('bold_italic_font')
312 font_path = pathlib.Path(eff_font_folder) / f'{bold_italic_font}{eff_font_suffix}'
313 if not font_path.is_file():
314 log.warning(
315 f'bold_italic_font ({bold_italic_font}) is not found'
316 f' as ({font_path}) on this system - rendering may not work as intended'
317 )
318 return text.replace(VALUE_SLOT, bold_italic_font)
319 else:
320 log.warning(f'bold_italic_font value not set ... setting default ({defaults["bold_italic_font"]})')
321 return text.replace(VALUE_SLOT, defaults['bold_italic_font'])
324@no_type_check
325def weave_setup_main_font(
326 mapper: dict[str, Union[str, int, bool, None]],
327 text: str,
328) -> str:
329 """Weave in the main_font from mapper or default for driver.
331 Trigger is text.rstrip().endswith('%%_PATCH_%_MAIN_%_FONT_%%')
333 Examples:
335 >>> mapper = {'main_font': 'IsMadeUp'} # Expect warning when file does not exist at font path and suffix
336 >>> weave_setup_main_font(mapper, ']{VALUE.SLOT}%%_PATCH_%_MAIN_%_FONT_%%')
337 ']{IsMadeUp}%%_PATCH_%_MAIN_%_FONT_%%'
338 >>> assert ACROSS['eff_font_folder'] in ('', WEAVE_DEFAULTS['font_path'])
339 >>> assert ACROSS['eff_font_suffix'] in ('', WEAVE_DEFAULTS['font_suffix'])
341 >>> mapper = {'no_main_font': 'sorry'}
342 >>> weave_setup_main_font(mapper, ']{VALUE.SLOT}%%_PATCH_%_MAIN_%_FONT_%%')
343 ']{ITCFranklinGothicStd-Book}%%_PATCH_%_MAIN_%_FONT_%%'
344 >>> assert ACROSS['eff_font_folder'] in ('', WEAVE_DEFAULTS['font_path'])
345 >>> assert ACROSS['eff_font_suffix'] in ('', WEAVE_DEFAULTS['font_suffix'])
346 """
347 defaults = {**WEAVE_DEFAULTS}
348 eff_font_folder = ACROSS['eff_font_folder']
349 eff_font_suffix = ACROSS['eff_font_suffix']
350 if mapper.get('main_font'):
351 main_font = mapper.get('main_font')
352 font_path = pathlib.Path(eff_font_folder) / f'{main_font}{eff_font_suffix}'
353 if not font_path.is_file():
354 log.warning(
355 f'main_font ({main_font}) is not found'
356 f' as ({font_path}) on this system - rendering may not work as intended'
357 )
358 return text.replace(VALUE_SLOT, main_font)
359 else:
360 log.warning(f'main_font value not set ... setting default ({defaults["main_font"]})')
361 return text.replace(VALUE_SLOT, defaults['main_font'])
364@no_type_check
365def weave_setup_fixed_font_package(
366 mapper: dict[str, Union[str, int, bool, None]],
367 text: str,
368) -> str:
369 r"""Weave in the fixed_font_package from mapper or default for driver.
371 Trigger is text.rstrip().endswith('%%_PATCH_%_FIXED_%_FONT_%_PACKAGE_%%')
373 Examples:
375 >>> mapper = {'fixed_font_package': 'MadeUpAgain'} # Expect warning when font differs from default
376 >>> weave_setup_fixed_font_package(mapper, r'\usepackage{VALUE.SLOT}%%_PATCH_%_FIXED_%_FONT_%_PACKAGE_%%')
377 '\\usepackage{MadeUpAgain}%%_PATCH_%_FIXED_%_FONT_%_PACKAGE_%%'
379 >>> mapper = {'no_fixed_font_package': 'sorry'}
380 >>> weave_setup_fixed_font_package(mapper, r'\usepackage{VALUE.SLOT}%%_PATCH_%_FIXED_%_FONT_%_PACKAGE_%%')
381 '\\usepackage{sourcecodepro}%%_PATCH_%_FIXED_%_FONT_%_PACKAGE_%%'
382 """
383 defaults = {**WEAVE_DEFAULTS}
384 if mapper.get('fixed_font_package'):
385 fixed_font_package = mapper.get('fixed_font_package')
386 if fixed_font_package != defaults['fixed_font_package']:
387 log.warning(
388 f'fixed_font_package ({fixed_font_package}) has not'
389 ' been tested on this system - rendering may not work as intended'
390 )
391 return text.replace(VALUE_SLOT, fixed_font_package)
392 else:
393 log.warning(f'fixed_font_package value not set ... setting default ({defaults["fixed_font_package"]})')
394 return text.replace(VALUE_SLOT, defaults['fixed_font_package'])
397@no_type_check
398def weave_setup_code_fontsize(
399 mapper: dict[str, Union[str, int, bool, None]],
400 text: str,
401) -> str:
402 r"""Weave in the code_fontsize from mapper or default for driver.
404 Trigger is text.rstrip().endswith('%%_PATCH_%_CODE_%_FONTSIZE_%%')
406 Examples:
408 >>> mapper = {'code_fontsize': r'\Huge'}
409 >>> weave_setup_code_fontsize(mapper, 'fontsize=VALUE.SLOT}%%_PATCH_%_CODE_%_FONTSIZE_%%')
410 'fontsize=\\Huge}%%_PATCH_%_CODE_%_FONTSIZE_%%'
412 >>> mapper = {'code_fontsize': r'footnotesize'}
413 >>> weave_setup_code_fontsize(mapper, 'fontsize=VALUE.SLOT}%%_PATCH_%_CODE_%_FONTSIZE_%%')
414 'fontsize=\\footnotesize}%%_PATCH_%_CODE_%_FONTSIZE_%%'
416 >>> mapper = {'code_fontsize': r'scriptsize'}
417 >>> weave_setup_code_fontsize(mapper, 'fontsize=VALUE.SLOT}%%_PATCH_%_CODE_%_FONTSIZE_%%')
418 'fontsize=\\scriptsize}%%_PATCH_%_CODE_%_FONTSIZE_%%'
420 >>> mapper = {'code_fontsize': r'tini'} # Expect warnings on override with available sizes
421 >>> weave_setup_code_fontsize(mapper, 'fontsize=VALUE.SLOT}%%_PATCH_%_CODE_%_FONTSIZE_%%')
422 'fontsize=\\scriptsize}%%_PATCH_%_CODE_%_FONTSIZE_%%'
424 >>> mapper = {'code_fontsize': r'\\LARGE'}
425 >>> weave_setup_code_fontsize(mapper, 'fontsize=VALUE.SLOT}%%_PATCH_%_CODE_%_FONTSIZE_%%')
426 'fontsize=\\LARGE}%%_PATCH_%_CODE_%_FONTSIZE_%%'
428 >>> mapper = {'no_code_fontsize': 'sorry'}
429 >>> weave_setup_code_fontsize(mapper, 'fontsize=VALUE.SLOT}%%_PATCH_%_CODE_%_FONTSIZE_%%')
430 'fontsize=\\scriptsize}%%_PATCH_%_CODE_%_FONTSIZE_%%'
431 """
432 defaults = {**WEAVE_DEFAULTS}
433 if mapper.get('code_fontsize'):
434 code_fontsize = mapper.get('code_fontsize')
435 valid_code_font_sizes = (
436 r'\Huge',
437 r'\huge',
438 r'\LARGE',
439 r'\Large',
440 r'\large',
441 r'\normalsize',
442 r'\small',
443 r'\footnotesize',
444 r'\scriptsize',
445 r'\tiny',
446 )
447 bs = '\\'
448 sizes = tuple(size[1:] for size in valid_code_font_sizes)
449 if code_fontsize.startswith(SLASH + SLASH):
450 code_fontsize = code_fontsize[1:]
451 if not code_fontsize.startswith(SLASH):
452 code_fontsize = SLASH + code_fontsize
453 if code_fontsize not in valid_code_font_sizes:
454 log.error(
455 f'code_fontsize ({code_fontsize}) is not a valid font size value'
456 ' - rendering would not work as intended'
457 )
458 log.info(f'valid values for code_fontsize must be in {bs}{(", " + bs).join(sizes)}')
459 log.warning(
460 f'overriding code font size value with the (working) default of ({defaults["code_fontsize"]})'
461 f' - in config that would be {defaults["code_fontsize"]}'
462 )
463 return text.replace(VALUE_SLOT, defaults['code_fontsize'])
464 else:
465 return text.replace(VALUE_SLOT, code_fontsize)
466 else:
467 log.info(
468 f'code_fontsize value not set ... setting default ({defaults["code_fontsize"]})'
469 f' - in config that would be {defaults["code_fontsize"]}'
470 )
471 return text.replace(VALUE_SLOT, defaults['code_fontsize'])
474@no_type_check
475def weave_setup_chosen_logo(
476 mapper: dict[str, Union[str, int, bool, None]],
477 text: str,
478) -> str:
479 r"""Weave in the chosen_logo from mapper or default for driver.
481 Trigger is text.rstrip().endswith('%%_PATCH_%_CHOSEN_%_LOGO_%%')
483 Examples:
485 >>> mapper = {'chosen_logo': 'not-found.png'} # Expect warning when logo path is no file
486 >>> weave_setup_chosen_logo(mapper, r'\newcommand{\theChosenLogo}{VALUE.SLOT}%%_PATCH_%_CHOSEN_%_LOGO_%%')
487 '\\newcommand{\\theChosenLogo}{not-found.png}%%_PATCH_%_CHOSEN_%_LOGO_%%'
489 >>> mapper = {'no_chosen_logo': 'sorry'}
490 >>> weave_setup_chosen_logo(mapper, r'\newcommand{\theChosenLogo}{VALUE.SLOT}%%_PATCH_%_CHOSEN_%_LOGO_%%')
491 '\\newcommand{\\theChosenLogo}{/opt/logo/liitos-logo.png}%%_PATCH_%_CHOSEN_%_LOGO_%%'
492 """
493 defaults = {**WEAVE_DEFAULTS}
494 if mapper.get('chosen_logo'):
495 chosen_logo = mapper.get('chosen_logo')
496 logo_path = pathlib.Path(chosen_logo)
497 if not logo_path.is_file():
498 log.warning(
499 f'chosen_logo ({chosen_logo}) is not found'
500 f' as ({logo_path}) on this system - rendering may not work as intended'
501 )
502 return text.replace(VALUE_SLOT, chosen_logo)
503 else:
504 log.info(f'chosen_logo value not set ... setting default ({defaults["chosen_logo"]})')
505 return text.replace(VALUE_SLOT, defaults['chosen_logo'])
508@no_type_check
509def weave_setup_chosen_title_page_logo(
510 mapper: dict[str, Union[str, int, bool, None]],
511 text: str,
512) -> str:
513 r"""Weave in the chosen_logo from mapper or default for driver.
515 Trigger is text.rstrip().endswith('%%_PATCH_%_CHOSEN_%_TITLE_%_PAGE_%_LOGO_%%')
517 Examples:
519 >>> mapper = {'chosen_title_page_logo': 'not-found.png'} # Expect warning when logo path is no file
520 >>> t = r'\newcommand{\theChosenTitlePageLogo}{VALUE.SLOT}%%_PATCH_%_CHOSEN_%_TITLE_%_PAGE_%_LOGO_%%'
521 >>> weave_setup_chosen_title_page_logo(mapper, t)
522 '\\newcommand{\\theChosenTitlePageLogo}{not-found.png}%%_PATCH_%_CHOSEN_%_TITLE_%_PAGE_%_LOGO_%%'
524 >>> mapper = {'no_chosen_title_page_logo': 'sorry'}
525 >>> t = r'\newcommand{\theChosenTitlePageLogo}{VALUE.SLOT}%%_PATCH_%_CHOSEN_%_TITLE_%_PAGE_%_LOGO_%%'
526 >>> weave_setup_chosen_title_page_logo(mapper, t)
527 '\\newcommand{\\theChosenTitlePageLogo}{/opt/logo/liitos-logo.png}%%_PATCH_%_CHOSEN_%_TITLE_%_PAGE_%_LOGO_%%'
528 """
529 defaults = {**WEAVE_DEFAULTS}
530 log.warning(text)
531 if mapper.get('chosen_title_page_logo'):
532 chosen_title_page_logo = mapper.get('chosen_title_page_logo')
533 title_page_logo_path = pathlib.Path(chosen_title_page_logo)
534 log.warning(f'found {chosen_title_page_logo}')
535 if not title_page_logo_path.is_file():
536 log.warning(
537 f'chosen_title_page_logo ({chosen_title_page_logo}) is not found'
538 f' as ({title_page_logo_path}) on this system - rendering may not work as intended'
539 )
540 return text.replace(VALUE_SLOT, chosen_title_page_logo)
541 else:
542 log.warning('default logo')
543 log.info(f'chosen_title_page_logo value not set ... setting default ({defaults["chosen_title_page_logo"]})')
544 return text.replace(VALUE_SLOT, defaults['chosen_title_page_logo'])
547@no_type_check
548def weave_setup_footer_outer_field_normal_pages(
549 mapper: dict[str, Union[str, int, bool, None]],
550 text: str,
551) -> str:
552 r"""Weave in the footer_outer_field_normal_pages from mapper or default for driver.
554 Trigger is text.rstrip().endswith('%%_PATCH_%_NORMAL_%_PAGES_%_OUTER_%_FOOT_%_CONTENT_%_VALUE_%%')
556 Examples:
558 >>> mapper = {'footer_outer_field_normal_pages': 'n/a'}
559 >>> t = ' VALUE.SLOT}}%%_PATCH_%_NORMAL_%_PAGES_%_OUTER_%_FOOT_%_CONTENT_%_VALUE_%%'
560 >>> weave_setup_footer_outer_field_normal_pages(mapper, t)
561 ' n/a}}%%_PATCH_%_NORMAL_%_PAGES_%_OUTER_%_FOOT_%_CONTENT_%_VALUE_%%'
563 >>> mapper = {'footer_outer_field_normal_pages': ''}
564 >>> t = ' VALUE.SLOT}}%%_PATCH_%_NORMAL_%_PAGES_%_OUTER_%_FOOT_%_CONTENT_%_VALUE_%%'
565 >>> weave_setup_footer_outer_field_normal_pages(mapper, t)
566 ' }}%%_PATCH_%_NORMAL_%_PAGES_%_OUTER_%_FOOT_%_CONTENT_%_VALUE_%%'
568 >>> mapper = {'no_footer_outer_field_normal_pages': 'sorry'}
569 >>> t = ' VALUE.SLOT}}%%_PATCH_%_NORMAL_%_PAGES_%_OUTER_%_FOOT_%_CONTENT_%_VALUE_%%'
570 >>> weave_setup_footer_outer_field_normal_pages(mapper, t)
571 ' \\theMetaPageNumPrefix { } \\thepage { }}}%%_PATCH_%_NORMAL_%_PAGES_%_OUTER_%_FOOT_%_CONTENT_%_VALUE_%%'
572 """
573 defaults = {**WEAVE_DEFAULTS}
574 if mapper.get('footer_outer_field_normal_pages') is not None:
575 footer_outer_field_normal_pages = mapper.get('footer_outer_field_normal_pages')
576 return text.replace(VALUE_SLOT, footer_outer_field_normal_pages)
577 else:
578 log.info(
579 'footer_outer_field_normal_pages value not set ...'
580 f' setting default ({defaults["footer_outer_field_normal_pages"]})'
581 )
582 return text.replace(VALUE_SLOT, defaults['footer_outer_field_normal_pages'])
585@no_type_check
586def weave_setup_toc_all_dots(
587 mapper: dict[str, Union[str, int, bool, None]],
588 text: str,
589) -> str:
590 r"""Weave in the toc_all_dots from mapper or default for driver.
592 Trigger is text.rstrip().endswith('%%_PATCH_%_TOC_ALL_DOTS_%%')
594 Examples:
596 >>> mapper = {'toc_all_dots': '%'} # Comment out the toc dots
597 >>> weave_setup_toc_all_dots(mapper, 'VALUE.SLOTtoc=sectionentrywithdots,%%_PATCH_%_TOC_ALL_DOTS_%%')
598 '%toc=sectionentrywithdots,%%_PATCH_%_TOC_ALL_DOTS_%%'
600 >>> mapper = {'toc_all_dots': ' '} # Enable the toc dots
601 >>> weave_setup_toc_all_dots(mapper, 'VALUE.SLOTtoc=sectionentrywithdots,%%_PATCH_%_TOC_ALL_DOTS_%%')
602 ' toc=sectionentrywithdots,%%_PATCH_%_TOC_ALL_DOTS_%%'
604 >>> mapper = {'toc_all_dots': '%-does-not-matter'} # Comment out the toc dots
605 >>> weave_setup_toc_all_dots(mapper, 'VALUE.SLOTtoc=sectionentrywithdots,%%_PATCH_%_TOC_ALL_DOTS_%%')
606 '%-does-not-mattertoc=sectionentrywithdots,%%_PATCH_%_TOC_ALL_DOTS_%%'
608 >>> mapper = {'toc_all_dots': 'missing-percent'} # Default toc dots and a warning
609 >>> weave_setup_toc_all_dots(mapper, 'VALUE.SLOTtoc=sectionentrywithdots,%%_PATCH_%_TOC_ALL_DOTS_%%')
610 'toc=sectionentrywithdots,%%_PATCH_%_TOC_ALL_DOTS_%%'
612 >>> mapper = {'no_toc_all_dots': 'sorry'}
613 >>> weave_setup_toc_all_dots(mapper, 'VALUE.SLOTtoc=sectionentrywithdots,%%_PATCH_%_TOC_ALL_DOTS_%%')
614 'toc=sectionentrywithdots,%%_PATCH_%_TOC_ALL_DOTS_%%'
615 """
616 defaults = {**WEAVE_DEFAULTS}
617 if mapper.get('toc_all_dots', None) is not None:
618 toc_all_dots = mapper.get('toc_all_dots')
619 if not toc_all_dots.strip() or toc_all_dots.strip().startswith('%'):
620 dis_ = 'dis' if not toc_all_dots.strip() else ''
621 log.info(f'toc_all_dots value received ... {dis_}abling toc dots')
622 return text.replace(VALUE_SLOT, toc_all_dots)
623 log.warning(
624 f"toc_all_dots value is neither '' nor starts with % ... setting default ({defaults['toc_all_dots']})"
625 )
626 return text.replace(VALUE_SLOT, defaults['toc_all_dots'])
627 else:
628 log.info(f'toc_all_dots value not set ... setting default ({defaults["toc_all_dots"]})')
629 return text.replace(VALUE_SLOT, defaults['toc_all_dots'])
632@no_type_check
633def dispatch_setup_weaver(
634 mapper: dict[str, Union[str, int, bool, None]],
635 text: str,
636) -> str:
637 """Dispatch the driver weaver by mapping to handled groups per source marker."""
638 dispatch = {
639 '%%_PATCH_%_FONT_%_PATH_%%': weave_setup_font_path,
640 '%%_PATCH_%_FONT_%_SUFFIX_%%': weave_setup_font_suffix,
641 '%%_PATCH_%_BOLD_%_FONT_%%': weave_setup_bold_font,
642 '%%_PATCH_%_ITALIC_%_FONT_%%': weave_setup_italic_font,
643 '%%_PATCH_%_BOLDITALIC_%_FONT_%%': weave_setup_bold_italic_font,
644 '%%_PATCH_%_MAIN_%_FONT_%%': weave_setup_main_font,
645 '%%_PATCH_%_FIXED_%_FONT_%_PACKAGE_%%': weave_setup_fixed_font_package,
646 '%%_PATCH_%_CODE_%_FONTSIZE_%%': weave_setup_code_fontsize,
647 '%%_PATCH_%_CHOSEN_%_LOGO_%%': weave_setup_chosen_logo,
648 '%%_PATCH_%_CHOSEN_%_TITLE_%_PAGE_%_LOGO_%%': weave_setup_chosen_title_page_logo,
649 '%%_PATCH_%_NORMAL_%_PAGES_%_OUTER_%_FOOT_%_CONTENT_%_VALUE_%%': weave_setup_footer_outer_field_normal_pages,
650 '%%_PATCH_%_TOC_ALL_DOTS_%%': weave_setup_toc_all_dots,
651 }
652 for trigger, weaver in dispatch.items():
653 if text.rstrip().endswith(trigger):
654 return weaver(mapper, text)
655 return text
658@no_type_check
659def weave_meta_setup(meta_map: gat.Meta, latex: list[str]) -> list[str]:
660 """TODO."""
661 log.info('weaving in the meta data per setup.tex.in into setup.tex ...')
662 completed = [dispatch_setup_weaver(meta_map['document']['common'], line) for line in latex]
663 if completed and completed[-1]:
664 completed.append('\n')
665 return completed
668@no_type_check
669def weave_driver_toc_level(
670 mapper: dict[str, Union[str, int, bool, None]],
671 text: str,
672) -> str:
673 """Weave in the toc_level from mapper or default for driver.
675 Trigger is text.rstrip().endswith('%%_PATCH_%_TOC_%_LEVEL_%%')
676 """
677 toc_level = 2
678 if mapper.get('toc_level'):
679 try:
680 toc_level_read = int(mapper['toc_level'])
681 toc_level = toc_level_read if 0 < toc_level_read < 5 else 2
682 if toc_level != toc_level_read:
683 log.warning(
684 f'ignored toc level ({toc_level_read}) set to default (2) - expected value 0 < toc_level < 5'
685 )
686 except ValueError as err:
687 toc_level = 2
688 log.warning(f'toc_level ({mapper["toc_level"]}) not in (1, 2, 3, 4) - resorting to default ({toc_level})')
689 log.error(f'error detail: {err}')
690 else:
691 log.info(f'toc_level value not set ... setting default ({toc_level})')
692 return text.replace(VALUE_SLOT, str(toc_level))
695@no_type_check
696def weave_driver_list_of_figures(
697 mapper: dict[str, Union[str, int, bool, None]],
698 text: str,
699) -> str:
700 """Weave in the list_of_figures from mapper or default for driver.
702 Trigger is text.rstrip().endswith('%%_PATCH_%_LOF_%%')
703 """
704 if mapper.get('list_of_figures', None) is not None:
705 lof = mapper['list_of_figures']
706 if lof in ('', '%'):
707 return text.replace(VALUE_SLOT, str(lof))
708 else:
709 lof = '%'
710 log.warning(
711 f"list_of_figures ({mapper['list_of_figures']}) not in ('', '%')"
712 f' - resorting to default ({lof}) i.e. commenting out the list of figures'
713 )
714 else:
715 log.info('list_of_figures value not set ... setting default (comment out the lof per %)')
717 return text.replace(VALUE_SLOT, '%')
720@no_type_check
721def weave_driver_list_of_tables(
722 mapper: dict[str, Union[str, int, bool, None]],
723 text: str,
724) -> str:
725 """Weave in the list_of_tables from mapper or default for driver.
727 Trigger is text.rstrip().endswith('%%_PATCH_%_LOT_%%')
728 """
729 if mapper.get('list_of_tables', None) is not None:
730 lof = mapper['list_of_tables']
731 if lof in ('', '%'):
732 return text.replace(VALUE_SLOT, str(lof))
733 else:
734 lof = '%'
735 log.warning(
736 f"list_of_tables ({mapper['list_of_tables']}) not in ('', '%')"
737 f' - resorting to default ({lof}) i.e. commenting out the list of tables'
738 )
739 else:
740 log.info('list_of_tables value not set ... setting default (comment out the lot per %)')
742 return text.replace(VALUE_SLOT, '%')
745@no_type_check
746def dispatch_driver_weaver(
747 mapper: dict[str, Union[str, int, bool, None]],
748 text: str,
749) -> str:
750 """Dispatch the driver weaver by mapping to handled groups per source marker."""
751 dispatch = {
752 '%%_PATCH_%_TOC_%_LEVEL_%%': weave_driver_toc_level,
753 '%%_PATCH_%_LOF_%%': weave_driver_list_of_figures,
754 '%%_PATCH_%_LOT_%%': weave_driver_list_of_tables,
755 }
756 for trigger, weaver in dispatch.items():
757 if text.rstrip().endswith(trigger):
758 return weaver(mapper, text)
759 return text
762@no_type_check
763def weave_meta_driver(meta_map: gat.Meta, latex: list[str]) -> list[str]:
764 """TODO."""
765 log.info('weaving in the meta data per driver.tex.in into driver.tex ...')
766 completed = [dispatch_driver_weaver(meta_map['document']['common'], line) for line in latex]
767 if completed and completed[-1]:
768 completed.append('\n')
769 return completed
772@no_type_check
773def weave_meta_part_header_title(
774 mapper: dict[str, Union[str, int, bool, None]],
775 text: str,
776) -> str:
777 """Weave in the header_title from mapper or default.
779 Trigger is text.rstrip().endswith('%%_PATCH_%_HEADER_%_TITLE_%%')
780 """
781 if mapper.get('header_title'):
782 return text.replace(VALUE_SLOT, mapper['header_title'])
783 else:
784 log.info('header_title value not set ... setting default (the title value)')
785 return text.replace(VALUE_SLOT, mapper['title'])
788@no_type_check
789def weave_meta_part_title_slug(
790 mapper: dict[str, Union[str, int, bool, None]],
791 text: str,
792) -> str:
793 r"""Weave in the title slug deriving from mapper or default.
795 Trigger is text.rstrip().endswith('%%_PATCH_%_TITLE_%_SLUG_%%')
797 Examples:
799 >>> mapper = {'bookmark_title': 'I aM A BMT'}
800 >>> t = r'\newcommand{\theTitleSlug}{VALUE.SLOT}%%_PATCH_%_TITLE_%_SLUG_%%'
801 >>> weave_meta_part_title_slug(mapper, t)
802 '\\newcommand{\\theTitleSlug}{I aM A BMT}%%_PATCH_%_TITLE_%_SLUG_%%'
803 """
804 if mapper.get('bookmark_title'):
805 return text.replace(VALUE_SLOT, mapper['bookmark_title'])
806 else:
807 log.info('bookmark_title value not set ... setting default (the slugged title value)')
808 return text.replace(VALUE_SLOT, mapper['title'].replace('\\\\', '').replace(' ', ' ').title())
811@no_type_check
812def weave_meta_part_title(
813 mapper: dict[str, Union[str, int, bool, None]],
814 text: str,
815) -> str:
816 """Weave in the title from mapper or default.
818 Trigger is text.rstrip().endswith('%%_PATCH_%_MAIN_%_TITLE_%%')
819 """
820 return text.replace(VALUE_SLOT, mapper['title'])
823@no_type_check
824def weave_meta_part_sub_title(
825 mapper: dict[str, Union[str, int, bool, None]],
826 text: str,
827) -> str:
828 """Weave in the sub_title from mapper or default.
830 Trigger is text.rstrip().endswith('%%_PATCH_%_SUB_%_TITLE_%%')
831 """
832 if mapper.get('sub_title'):
833 return text.replace(VALUE_SLOT, mapper['sub_title'])
834 else:
835 log.info('sub_title value not set ... setting default (single space)')
836 return text.replace(VALUE_SLOT, ' ')
839@no_type_check
840def weave_meta_part_header_type(
841 mapper: dict[str, Union[str, int, bool, None]],
842 text: str,
843) -> str:
844 """Weave in the header_type from mapper or default.
846 Trigger is text.rstrip().endswith('%%_PATCH_%_TYPE_%%')
847 """
848 if mapper.get('header_type'):
849 return text.replace(VALUE_SLOT, mapper['header_type'])
850 else:
851 log.info('header_type value not set ... setting default (Engineering Document)')
852 return text.replace(VALUE_SLOT, 'Engineering Document')
855@no_type_check
856def weave_meta_part_header_id_label(
857 mapper: dict[str, Union[str, int, bool, None]],
858 text: str,
859) -> str:
860 r"""Weave in the header_id_label from mapper or default.
862 Trigger is text.rstrip().endswith('%%_PATCH_%_ID_%_LABEL_%%')
864 Examples:
866 >>> mapper = {'header_id_show': False}
867 >>> t = r'\newcommand{\theMetaDocIdLabel}{VALUE.SLOT}%%_PATCH_%_ID_%_LABEL_%%'
868 >>> weave_meta_part_header_id_label(mapper, t)
869 '\\newcommand{\\theMetaDocIdLabel}{ }%%_PATCH_%_ID_%_LABEL_%%'
871 >>> mapper = {'header_id_show': ''}
872 >>> t = r'\newcommand{\theMetaDocIdLabel}{VALUE.SLOT}%%_PATCH_%_ID_%_LABEL_%%'
873 >>> weave_meta_part_header_id_label(mapper, t)
874 '\\newcommand{\\theMetaDocIdLabel}{ }%%_PATCH_%_ID_%_LABEL_%%'
876 >>> mapper = {'header_id_show': None, 'header_id_label': ' '}
877 >>> t = r'\newcommand{\theMetaDocIdLabel}{VALUE.SLOT}%%_PATCH_%_ID_%_LABEL_%%'
878 >>> weave_meta_part_header_id_label(mapper, t)
879 '\\newcommand{\\theMetaDocIdLabel}{ }%%_PATCH_%_ID_%_LABEL_%%'
881 >>> mapper = {'header_id_show': None, 'header_id_label': ' show-this-stripped '}
882 >>> t = r'\newcommand{\theMetaDocIdLabel}{VALUE.SLOT}%%_PATCH_%_ID_%_LABEL_%%'
883 >>> weave_meta_part_header_id_label(mapper, t)
884 '\\newcommand{\\theMetaDocIdLabel}{show-this-stripped}%%_PATCH_%_ID_%_LABEL_%%'
886 >>> mapper = {'no_header_id_show': 'sorry'}
887 >>> t = r'\newcommand{\theMetaDocIdLabel}{VALUE.SLOT}%%_PATCH_%_ID_%_LABEL_%%'
888 >>> weave_meta_part_header_id_label(mapper, t)
889 '\\newcommand{\\theMetaDocIdLabel}{Doc. ID:}%%_PATCH_%_ID_%_LABEL_%%'
890 """
891 if mapper.get('header_id_show', None) is not None and not mapper['header_id_show']:
892 log.info('header_id_show set to false - hiding id slot in header by setting label to a single space(" ")')
893 return text.replace(VALUE_SLOT, ' ')
894 log.info('header_id_show not set - considering header_id_label ...')
895 if mapper.get('header_id_label'):
896 pub_id_label = mapper['header_id_label'].strip()
897 if not pub_id_label:
898 pub_id_label = ' ' # single space to please the backend parser
899 return text.replace(VALUE_SLOT, pub_id_label)
900 else:
901 log.info('header_id_label value not set ... setting default(Doc. ID:)')
902 return text.replace(VALUE_SLOT, 'Doc. ID:')
905@no_type_check
906def weave_meta_part_header_id(
907 mapper: dict[str, Union[str, int, bool, None]],
908 text: str,
909) -> str:
910 r"""Weave in the header_id from mapper or default.
912 Trigger is text.rstrip().endswith('%%_PATCH_%_ID_%%')
914 Examples:
916 >>> mapper = {'header_id_show': False}
917 >>> t = r'\newcommand{\theMetaDocId}{VALUE.SLOT}%%_PATCH_%_ID_%%'
918 >>> weave_meta_part_header_id(mapper, t)
919 '\\newcommand{\\theMetaDocId}{ }%%_PATCH_%_ID_%%'
921 >>> mapper = {'header_id_show': ''}
922 >>> t = r'\newcommand{\theMetaDocId}{VALUE.SLOT}%%_PATCH_%_ID_%%'
923 >>> weave_meta_part_header_id(mapper, t)
924 '\\newcommand{\\theMetaDocId}{ }%%_PATCH_%_ID_%%'
926 >>> mapper = {'header_id_show': None, 'header_id': ' '}
927 >>> t = r'\newcommand{\theMetaDocId}{VALUE.SLOT}%%_PATCH_%_ID_%%'
928 >>> weave_meta_part_header_id(mapper, t)
929 '\\newcommand{\\theMetaDocId}{ }%%_PATCH_%_ID_%%'
931 >>> mapper = {'header_id_show': None, 'header_id': ' show-this-unstripped '}
932 >>> t = r'\newcommand{\theMetaDocId}{VALUE.SLOT}%%_PATCH_%_ID_%%'
933 >>> weave_meta_part_header_id(mapper, t)
934 '\\newcommand{\\theMetaDocId}{ show-this-unstripped }%%_PATCH_%_ID_%%'
936 >>> mapper = {'no_header_id_show': 'sorry'}
937 >>> t = r'\newcommand{\theMetaDocId}{VALUE.SLOT}%%_PATCH_%_ID_%%'
938 >>> weave_meta_part_header_id(mapper, t)
939 '\\newcommand{\\theMetaDocId}{N/A}%%_PATCH_%_ID_%%'
940 """
941 if mapper.get('header_id_show', None) is not None and not mapper['header_id_show']:
942 log.info('header_id_show set to false - hiding id slot in header by setting value to a single space(" ")')
943 return text.replace(VALUE_SLOT, ' ')
944 log.info('header_id_show not set - considering header_id ...')
945 if mapper.get('header_id'):
946 return text.replace(VALUE_SLOT, mapper['header_id'])
947 else:
948 log.info('header_id value not set ... setting default (N/A)')
949 return text.replace(VALUE_SLOT, 'N/A')
952@no_type_check
953def weave_meta_part_issue(
954 mapper: dict[str, Union[str, int, bool, None]],
955 text: str,
956) -> str:
957 """Weave in the issue from mapper or default.
959 Trigger is text.rstrip().endswith('%%_PATCH_%_ISSUE_%%')
960 """
961 if mapper.get('issue'):
962 return text.replace(VALUE_SLOT, mapper['issue'])
963 else:
964 log.info('issue value not set ... setting default (01)')
965 return text.replace(VALUE_SLOT, '01')
968@no_type_check
969def weave_meta_part_revision(
970 mapper: dict[str, Union[str, int, bool, None]],
971 text: str,
972) -> str:
973 """Weave in the revision from mapper or default.
975 Trigger is text.rstrip().endswith('%%_PATCH_%_REVISION_%%')
976 """
977 if mapper.get('revision'):
978 return text.replace(VALUE_SLOT, mapper['revision'])
979 else:
980 log.info('revision value not set ... setting default (00)')
981 return text.replace(VALUE_SLOT, '00')
984@no_type_check
985def weave_meta_part_header_date_label(
986 mapper: dict[str, Union[str, int, bool, None]],
987 text: str,
988) -> str:
989 r"""Weave in the header_date_label from mapper or default.
991 Trigger is text.rstrip().endswith('%%_PATCH_%_DATE_%_LABEL_%%')
993 Examples:
995 >>> mapper = {'header_date_show': False}
996 >>> t = r'\newcommand{\theMetaDateLabel}{VALUE.SLOT}%%_PATCH_%_DATE_%_LABEL_%%'
997 >>> weave_meta_part_header_date_label(mapper, t)
998 '\\newcommand{\\theMetaDateLabel}{ }%%_PATCH_%_DATE_%_LABEL_%%'
1000 >>> mapper = {'header_date_show': ''}
1001 >>> t = r'\newcommand{\theMetaDateLabel}{VALUE.SLOT}%%_PATCH_%_DATE_%_LABEL_%%'
1002 >>> weave_meta_part_header_date_label(mapper, t)
1003 '\\newcommand{\\theMetaDateLabel}{ }%%_PATCH_%_DATE_%_LABEL_%%'
1005 >>> mapper = {'header_date_show': None, 'header_date_label': ' '}
1006 >>> t = r'\newcommand{\theMetaDateLabel}{VALUE.SLOT}%%_PATCH_%_DATE_%_LABEL_%%'
1007 >>> weave_meta_part_header_date_label(mapper, t)
1008 '\\newcommand{\\theMetaDateLabel}{ }%%_PATCH_%_DATE_%_LABEL_%%'
1010 >>> mapper = {'header_date_show': None, 'header_date_label': ' show-this-stripped '}
1011 >>> t = r'\newcommand{\theMetaDateLabel}{VALUE.SLOT}%%_PATCH_%_DATE_%_LABEL_%%'
1012 >>> weave_meta_part_header_date_label(mapper, t)
1013 '\\newcommand{\\theMetaDateLabel}{show-this-stripped}%%_PATCH_%_DATE_%_LABEL_%%'
1015 >>> mapper = {'no_header_date_show': 'sorry'}
1016 >>> t = r'\newcommand{\theMetaDateLabel}{VALUE.SLOT}%%_PATCH_%_DATE_%_LABEL_%%'
1017 >>> weave_meta_part_header_date_label(mapper, t)
1018 '\\newcommand{\\theMetaDateLabel}{ }%%_PATCH_%_DATE_%_LABEL_%%'
1019 """
1020 if mapper.get('header_date_show', None) is not None and not mapper['header_date_show']:
1021 log.info('header_date_show set to false - hiding date slot in header by setting label to a single space(" ")')
1022 return text.replace(VALUE_SLOT, ' ')
1023 log.info('header_date_show not set - considering header_date_label ...')
1024 if mapper.get('header_date_label'):
1025 pub_date_label = mapper['header_date_label'].strip()
1026 if not pub_date_label:
1027 pub_date_label = ' ' # single space to please the backend parser
1028 return text.replace(VALUE_SLOT, pub_date_label)
1029 else:
1030 log.info('header_date_label value not set ... setting default(" ")')
1031 return text.replace(VALUE_SLOT, ' ')
1034@no_type_check
1035def weave_meta_part_header_date(
1036 mapper: dict[str, Union[str, int, bool, None]],
1037 text: str,
1038) -> str:
1039 r"""Weave in the header_date from mapper or default.
1041 Trigger is text.rstrip().endswith('%%_PATCH_%_DATE_%%')
1043 Examples:
1045 >>> mapper = {'header_date_show': False}
1046 >>> t = r'\newcommand{\theMetaDate}{VALUE.SLOT}%%_PATCH_%_DATE_%%'
1047 >>> weave_meta_part_header_date(mapper, t)
1048 '\\newcommand{\\theMetaDate}{ }%%_PATCH_%_DATE_%%'
1050 >>> mapper = {'header_date_show': ''}
1051 >>> t = r'\newcommand{\theMetaDate}{VALUE.SLOT}%%_PATCH_%_DATE_%%'
1052 >>> weave_meta_part_header_date(mapper, t)
1053 '\\newcommand{\\theMetaDate}{ }%%_PATCH_%_DATE_%%'
1055 >>> mapper = {'header_date_show': None, 'header_date': ' '}
1056 >>> t = r'\newcommand{\theMetaDate}{VALUE.SLOT}%%_PATCH_%_DATE_%%'
1057 >>> weave_meta_part_header_date(mapper, t)
1058 '\\newcommand{\\theMetaDate}{}%%_PATCH_%_DATE_%%'
1060 >>> mapper = {'header_date_show': None, 'header_date': ' show-this-stripped '}
1061 >>> t = r'\newcommand{\theMetaDate}{VALUE.SLOT}%%_PATCH_%_DATE_%%'
1062 >>> weave_meta_part_header_date(mapper, t)
1063 '\\newcommand{\\theMetaDate}{show-this-stripped}%%_PATCH_%_DATE_%%'
1065 >>> mapper = {'no_header_date_show': 'sorry'}
1066 >>> t = r'\newcommand{\theMetaDate}{VALUE.SLOT}%%_PATCH_%_DATE_%%'
1067 >>> weave_meta_part_header_date(mapper, t)
1068 '\\newcommand{\\theMetaDate}{ }%%_PATCH_%_DATE_%%'
1070 >>> mapper = {
1071 ... 'no_header_date_show': 'sorry',
1072 ... 'header_date_enable_auto': True,
1073 ... 'header_date': ' ',
1074 ... }
1075 >>> t = r'\newcommand{\theMetaDate}{VALUE.SLOT}%%_PATCH_%_DATE_%%'
1076 >>> weave_meta_part_header_date(mapper, t)
1077 '\\newcommand{\\theMetaDate}{}%%_PATCH_%_DATE_%%'
1079 >>> mapper = {
1080 ... 'no_header_date_show': 'sorry',
1081 ... 'header_date_enable_auto': True,
1082 ... 'header_date': '',
1083 ... }
1084 >>> t = r'\newcommand{\theMetaDate}{VALUE.SLOT}%%_PATCH_%_DATE_%%'
1085 >>> weave_meta_part_header_date(mapper, t)
1086 '\\newcommand{\\theMetaDate}{ }%%_PATCH_%_DATE_%%'
1088 >>> mapper = {
1089 ... 'no_header_date_show': 'sorry',
1090 ... 'header_date_enable_auto': True,
1091 ... 'header_date': ' free-form-stripped ',
1092 ... }
1093 >>> t = r'\newcommand{\theMetaDate}{VALUE.SLOT}%%_PATCH_%_DATE_%%'
1094 >>> weave_meta_part_header_date(mapper, t)
1095 '\\newcommand{\\theMetaDate}{free-form-stripped}%%_PATCH_%_DATE_%%'
1097 >>> mapper = {
1098 ... 'no_header_date_show': 'sorry',
1099 ... 'header_date_enable_auto': False,
1100 ... 'header_date': ' free-form-stripped ',
1101 ... }
1102 >>> t = r'\newcommand{\theMetaDate}{VALUE.SLOT}%%_PATCH_%_DATE_%%'
1103 >>> weave_meta_part_header_date(mapper, t)
1104 '\\newcommand{\\theMetaDate}{free-form-stripped}%%_PATCH_%_DATE_%%'
1106 >>> mapper = {
1107 ... 'no_header_date_show': 'sorry',
1108 ... 'header_date_enable_auto': False,
1109 ... 'header_date': '',
1110 ... }
1111 >>> t = r'\newcommand{\theMetaDate}{VALUE.SLOT}%%_PATCH_%_DATE_%%'
1112 >>> weave_meta_part_header_date(mapper, t)
1113 '\\newcommand{\\theMetaDate}{ }%%_PATCH_%_DATE_%%'
1115 >>> mapper = {
1116 ... 'no_header_date_show': 'sorry',
1117 ... 'header_date_enable_auto': False,
1118 ... 'header_date': ' ',
1119 ... }
1120 >>> t = r'\newcommand{\theMetaDate}{VALUE.SLOT}%%_PATCH_%_DATE_%%'
1121 >>> weave_meta_part_header_date(mapper, t)
1122 '\\newcommand{\\theMetaDate}{ }%%_PATCH_%_DATE_%%'
1123 """
1124 if mapper.get('header_date_show', None) is not None and not mapper['header_date_show']:
1125 log.info('header_date_show set to false - hiding date slot in header by setting value to a single space(" ")')
1126 return text.replace(VALUE_SLOT, ' ')
1127 log.info('header_date_show not set - considering header_date ...')
1128 if mapper.get('header_date_enable_auto', None) is not None and not mapper['header_date_enable_auto']:
1129 log.info('header_date_enable_auto set to false - setting that slot value as is (no date semantics enforced)')
1130 if mapper.get('header_date'):
1131 pub_date_or_any = mapper['header_date'].strip()
1132 if not pub_date_or_any:
1133 pub_date_or_any = ' ' # single space to please the backend parser
1134 return text.replace(VALUE_SLOT, pub_date_or_any)
1135 else:
1136 log.info('header_date value not set and as-is mode ... setting to single space ( ) a.k.a. hiding')
1137 return text.replace(VALUE_SLOT, ' ')
1138 else:
1139 today = dti.datetime.today()
1140 pub_date_today = today.strftime('%d %b %Y').upper()
1141 if mapper.get('header_date'):
1142 pub_date = mapper['header_date'].strip()
1143 if pub_date == MAGIC_OF_TODAY:
1144 pub_date = pub_date_today
1145 return text.replace(VALUE_SLOT, pub_date)
1146 else:
1147 log.info('header_date value not set ... setting default as empty(" ")')
1148 return text.replace(VALUE_SLOT, ' ')
1151@no_type_check
1152def weave_meta_part_footer_frame_note(
1153 mapper: dict[str, Union[str, int, bool, None]],
1154 text: str,
1155) -> str:
1156 """Weave in the footer_frame_note from mapper or default.
1158 Trigger is text.rstrip().endswith('%%_PATCH_%_FRAME_%_NOTE_%%')
1159 """
1160 if mapper.get('footer_frame_note'):
1161 return text.replace(VALUE_SLOT, mapper['footer_frame_note'])
1162 else:
1163 log.info('footer_frame_note value not set ... setting default from module / environment ...')
1164 return text.replace(VALUE_SLOT, WEAVE_DEFAULTS['footer_frame_note'])
1167@no_type_check
1168def weave_meta_part_footer_page_number_prefix(
1169 mapper: dict[str, Union[str, int, bool, None]],
1170 text: str,
1171) -> str:
1172 """Weave in the footer_page_number_prefix from mapper or default.
1174 Trigger is text.rstrip().endswith('%%_PATCH_%_FOOT_%_PAGE_%_COUNTER_%_LABEL_%%')
1175 """
1176 if mapper.get('footer_page_number_prefix'):
1177 return text.replace(VALUE_SLOT, mapper['footer_page_number_prefix'])
1178 else:
1179 log.info('footer_page_number_prefix value not set ... setting default (Page)')
1180 return text.replace(VALUE_SLOT, 'Page')
1183@no_type_check
1184def weave_meta_part_change_log_issue_label(
1185 mapper: dict[str, Union[str, int, bool, None]],
1186 text: str,
1187) -> str:
1188 """Weave in the change_log_issue_label from mapper or default.
1190 Trigger is text.rstrip().endswith('%%_PATCH_%_CHANGELOG_%_ISSUE_%_LABEL_%%')
1191 """
1192 if mapper.get('change_log_issue_label'):
1193 return text.replace(VALUE_SLOT, mapper['change_log_issue_label'])
1194 else:
1195 log.info('change_log_issue_label value not set ... setting default (Iss.)')
1196 return text.replace(VALUE_SLOT, 'Iss.')
1199@no_type_check
1200def weave_meta_part_change_log_revision_label(
1201 mapper: dict[str, Union[str, int, bool, None]],
1202 text: str,
1203) -> str:
1204 """Weave in the change_log_revision_label from mapper or default.
1206 Trigger is text.rstrip().endswith('%%_PATCH_%_CHANGELOG_%_REVISION_%_LABEL_%%')
1207 """
1208 if mapper.get('change_log_revision_label'):
1209 return text.replace(VALUE_SLOT, mapper['change_log_revision_label'])
1210 else:
1211 log.info('change_log_revision_label value not set ... setting default (Rev.)')
1212 return text.replace(VALUE_SLOT, 'Rev.')
1215@no_type_check
1216def weave_meta_part_change_log_date_label(
1217 mapper: dict[str, Union[str, int, bool, None]],
1218 text: str,
1219) -> str:
1220 """Weave in the change_log_date_label from mapper or default.
1222 Trigger is text.rstrip().endswith('%%_PATCH_%_CHANGELOG_%_DATE_%_LABEL_%%')
1223 """
1224 if mapper.get('change_log_date_label'):
1225 return text.replace(VALUE_SLOT, mapper['change_log_date_label'])
1226 else:
1227 log.info('change_log_date_label value not set ... setting default (Date)')
1228 return text.replace(VALUE_SLOT, 'Date')
1231@no_type_check
1232def weave_meta_part_change_log_author_label(
1233 mapper: dict[str, Union[str, int, bool, None]],
1234 text: str,
1235) -> str:
1236 """Weave in the change_log_author_label from mapper or default.
1238 Trigger is text.rstrip().endswith('%%_PATCH_%_CHANGELOG_%_AUTHOR_%_LABEL_%%')
1239 """
1240 if mapper.get('change_log_author_label'):
1241 return text.replace(VALUE_SLOT, mapper['change_log_author_label'])
1242 else:
1243 log.info('change_log_author_label value not set ... setting default (Author)')
1244 return text.replace(VALUE_SLOT, 'Author')
1247@no_type_check
1248def weave_meta_part_change_log_description_label(
1249 mapper: dict[str, Union[str, int, bool, None]],
1250 text: str,
1251) -> str:
1252 """Weave in the change_log_description_label from mapper or default.
1254 Trigger is text.rstrip().endswith('%%_PATCH_%_CHANGELOG_%_DESCRIPTION_%_LABEL_%%')
1255 """
1256 if mapper.get('change_log_description_label'):
1257 return text.replace(VALUE_SLOT, mapper['change_log_description_label'])
1258 else:
1259 log.info('change_log_description_label value not set ... setting default (Description)')
1260 return text.replace(VALUE_SLOT, 'Description')
1263@no_type_check
1264def weave_meta_part_with_default_slot(
1265 mapper: dict[str, Union[str, int, bool, None]],
1266 text: str,
1267 slot: str,
1268) -> str:
1269 """Do the conditional weaving of slot if text matches else used default (and log a warning)."""
1270 if mapper.get(slot):
1271 return text.replace(VALUE_SLOT, mapper[slot])
1272 else:
1273 log.info(f'{slot} value not set ... setting default ({WEAVE_DEFAULTS[slot]})')
1274 return text.replace(VALUE_SLOT, WEAVE_DEFAULTS[slot])
1277@no_type_check
1278def weave_meta_part_approvals_adjustable_vertical_space(
1279 mapper: dict[str, Union[str, int, bool, None]],
1280 text: str,
1281) -> str:
1282 """Weave in the approvals_adjustable_vertical_space from mapper or default.
1284 Trigger is text.rstrip().endswith('%%_PATCH_%_APPROVALS_%_ADJUSTABLE_%_VERTICAL_%_SPACE_%%')
1285 """
1286 return weave_meta_part_with_default_slot(mapper, text, 'approvals_adjustable_vertical_space')
1289@no_type_check
1290def weave_meta_part_proprietary_information_adjustable_vertical_space(
1291 mapper: dict[str, Union[str, int, bool, None]],
1292 text: str,
1293) -> str:
1294 """Weave in the proprietary_information_adjustable_vertical_space from mapper or default.
1296 Trigger is text.rstrip().endswith('%%_PATCH_%_BLURB_%_ADJUSTABLE_%_VERTICAL_%_SPACE_%%')
1297 """
1298 return weave_meta_part_with_default_slot(mapper, text, 'proprietary_information_adjustable_vertical_space')
1301@no_type_check
1302def weave_meta_part_proprietary_information_tune_header_sep(
1303 mapper: dict[str, Union[str, int, bool, None]],
1304 text: str,
1305) -> str:
1306 """Weave in the proprietary_information_tune_header_sep from mapper or default.
1308 Trigger is text.rstrip().endswith('%%_PATCH_%_BLURB_%_TUNE_%_HEADER_%_SEP_%%')
1309 """
1310 return weave_meta_part_with_default_slot(mapper, text, 'proprietary_information_tune_header_sep')
1313@no_type_check
1314def weave_meta_part_change_log_tune_header_sep(
1315 mapper: dict[str, Union[str, int, bool, None]],
1316 text: str,
1317) -> str:
1318 """Weave in the change_log_tune_header_sep from mapper or default.
1320 Trigger is text.rstrip().endswith('%%_PATCH_%_CHANGE_%_LOG_%_TUNE_%_HEADER_%_SEP_%%')
1321 """
1322 return weave_meta_part_with_default_slot(mapper, text, 'change_log_tune_header_sep')
1325@no_type_check
1326def weave_meta_part_approvals_department_label(
1327 mapper: dict[str, Union[str, int, bool, None]],
1328 text: str,
1329) -> str:
1330 """Weave in the approvals_department_label from mapper or default.
1332 Trigger is text.rstrip().endswith('%%_PATCH_%_APPROVALS_%_DEPARTMENT_%_LABEL_%%')
1333 """
1334 if mapper.get('approvals_department_label'):
1335 return text.replace(VALUE_SLOT, mapper['approvals_department_label'])
1336 else:
1337 log.info('approvals_department_label value not set ... setting default (Department)')
1338 return text.replace(VALUE_SLOT, 'Department')
1341@no_type_check
1342def weave_meta_part_approvals_department_value(
1343 mapper: dict[str, Union[str, int, bool, None]],
1344 text: str,
1345) -> str:
1346 r"""Weave in the approvals_department_value from mapper or default.
1348 Trigger is text.rstrip().endswith('%%_PATCH_%_APPROVALS_%_DEPARTMENT_%_VALUE_%%')
1350 Examples:
1352 >>> mapper = {'approvals_department_value': 'AbC'}
1353 >>> t = r'\newcommand{\theApprovalsDepartmentValue}{VALUE.SLOT}%%_PATCH_%_APPROVALS_%_DEPARTMENT_%_VALUE_%%'
1354 >>> weave_meta_part_approvals_department_value(mapper, t)
1355 '\\newcommand{\\theApprovalsDepartmentValue}{AbC}%%_PATCH_%_APPROVALS_%_DEPARTMENT_%_VALUE_%%'
1357 >>> mapper = {'approvals_department_value': ' '}
1358 >>> t = r'\newcommand{\theApprovalsDepartmentValue}{VALUE.SLOT}%%_PATCH_%_APPROVALS_%_DEPARTMENT_%_VALUE_%%'
1359 >>> weave_meta_part_approvals_department_value(mapper, t)
1360 '\\newcommand{\\theApprovalsDepartmentValue}{ }%%_PATCH_%_APPROVALS_%_DEPARTMENT_%_VALUE_%%'
1362 >>> mapper = {'approvals_department_value': ''}
1363 >>> t = r'\newcommand{\theApprovalsDepartmentValue}{VALUE.SLOT}%%_PATCH_%_APPROVALS_%_DEPARTMENT_%_VALUE_%%'
1364 >>> weave_meta_part_approvals_department_value(mapper, t)
1365 '\\newcommand{\\theApprovalsDepartmentValue}{ }%%_PATCH_%_APPROVALS_%_DEPARTMENT_%_VALUE_%%'
1367 >>> mapper = {'no_approvals_department_value': 'sorry'}
1368 >>> t = r'\newcommand{\theApprovalsDepartmentValue}{VALUE.SLOT}%%_PATCH_%_APPROVALS_%_DEPARTMENT_%_VALUE_%%'
1369 >>> weave_meta_part_approvals_department_value(mapper, t)
1370 '\\newcommand{\\theApprovalsDepartmentValue}{ }%%_PATCH_%_APPROVALS_%_DEPARTMENT_%_VALUE_%%'
1371 """
1372 if mapper.get('approvals_department_value'):
1373 return text.replace(VALUE_SLOT, mapper['approvals_department_value'])
1374 else:
1375 log.info('approvals_department_value value not set ... setting default ( )')
1376 return text.replace(VALUE_SLOT, ' ')
1379@no_type_check
1380def weave_meta_part_approvals_role_label(
1381 mapper: dict[str, Union[str, int, bool, None]],
1382 text: str,
1383) -> str:
1384 """Weave in the approvals_role_label from mapper or default.
1386 Trigger is text.rstrip().endswith('%%_PATCH_%_APPROVALS_%_ROLE_%_LABEL_%%')
1387 """
1388 if mapper.get('approvals_role_label'):
1389 return text.replace(VALUE_SLOT, mapper['approvals_role_label'])
1390 else:
1391 log.info('approvals_role_label value not set ... setting default (Approvals)')
1392 return text.replace(VALUE_SLOT, 'Approvals')
1395@no_type_check
1396def weave_meta_part_approvals_name_label(
1397 mapper: dict[str, Union[str, int, bool, None]],
1398 text: str,
1399) -> str:
1400 """Weave in the approvals_name_label from mapper or default.
1402 Trigger is text.rstrip().endswith('%%_PATCH_%_APPROVALS_%_NAME_%_LABEL_%%')
1403 """
1404 if mapper.get('approvals_name_label'):
1405 return text.replace(VALUE_SLOT, mapper['approvals_name_label'])
1406 else:
1407 log.info('approvals_name_label value not set ... setting default (Name)')
1408 return text.replace(VALUE_SLOT, 'Name')
1411@no_type_check
1412def weave_meta_part_approvals_date_and_signature_label(
1413 mapper: dict[str, Union[str, int, bool, None]],
1414 text: str,
1415) -> str:
1416 """Weave in the approvals_date_and_signature_label from mapper or default.
1418 Trigger is text.rstrip().endswith('%%_PATCH_%_APPROVALS_%_DATE_%_AND_%_SIGNATURE_%_LABEL_%%')
1419 """
1420 if mapper.get('approvals_date_and_signature_label'):
1421 return text.replace(VALUE_SLOT, mapper['approvals_date_and_signature_label'])
1422 else:
1423 log.info('approvals_date_and_signature_label value not set ... setting default (Date and Signature)')
1424 return text.replace(VALUE_SLOT, 'Date and Signature')
1427@no_type_check
1428def weave_meta_part_header_issue_revision_combined_label(
1429 mapper: dict[str, Union[str, int, bool, None]],
1430 text: str,
1431) -> str:
1432 r"""Weave in the header_issue_revision_combined_label from mapper or default.
1434 Trigger is text.rstrip().endswith('%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%_LABEL_%%')
1436 Examples:
1438 >>> mapper = {'header_issue_revision_combined_show': ''}
1439 >>> t = r'\newcommand{\theMetaIssRevLabel}{VALUE.SLOT}%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%_LABEL_%%'
1440 >>> weave_meta_part_header_issue_revision_combined_label(mapper, t)
1441 '\\newcommand{\\theMetaIssRevLabel}{ }%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%_LABEL_%%'
1443 >>> mapper = {
1444 ... 'header_issue_revision_combined_show': ' ',
1445 ... 'header_issue_revision_combined_label': ' ',
1446 ... }
1447 >>> t = r'\newcommand{\theMetaIssRevLabel}{VALUE.SLOT}%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%_LABEL_%%'
1448 >>> weave_meta_part_header_issue_revision_combined_label(mapper, t)
1449 '\\newcommand{\\theMetaIssRevLabel}{ }%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%_LABEL_%%'
1451 >>> mapper = {
1452 ... 'header_issue_revision_combined_show': 'well-well-well',
1453 ... 'header_issue_revision_combined_label': 'visible-fixed-string',
1454 ... }
1455 >>> t = r'\newcommand{\theMetaIssRevLabel}{VALUE.SLOT}%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%_LABEL_%%'
1456 >>> weave_meta_part_header_issue_revision_combined_label(mapper, t)
1457 '\\newcommand{\\theMetaIssRevLabel}{visible-fixed-string}%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%_LABEL_%%'
1459 >>> mapper = {'no_header_issue_revision_combined_show': 'sorry'}
1460 >>> t = r'\newcommand{\theMetaIssRevLabel}{VALUE.SLOT}%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%_LABEL_%%'
1461 >>> weave_meta_part_header_issue_revision_combined_label(mapper, t)
1462 '\\newcommand{\\theMetaIssRevLabel}{Issue, Revision:}%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%_LABEL_%%'
1463 """
1464 do_show_key = 'header_issue_revision_combined_show'
1465 if mapper.get(do_show_key, None) is not None and not mapper[do_show_key]:
1466 log.info(f'{do_show_key} set to false - hiding date slot in header by setting label to a single space(" ")')
1467 return text.replace(VALUE_SLOT, ' ')
1468 log.info(f'{do_show_key} not set - considering header_issue_revision_combined_label ...')
1469 if mapper.get('header_issue_revision_combined_label'):
1470 head_iss_rev_comb_label = mapper['header_issue_revision_combined_label'].strip()
1471 if not head_iss_rev_comb_label:
1472 head_iss_rev_comb_label = ' ' # single space to please the backend parser
1473 return text.replace(VALUE_SLOT, head_iss_rev_comb_label)
1474 else:
1475 log.info('header_issue_revision_combined_label value not set ... setting default(Issue, Revision:)')
1476 return text.replace(VALUE_SLOT, 'Issue, Revision:')
1479@no_type_check
1480def weave_meta_part_header_issue_revision_combined(
1481 mapper: dict[str, Union[str, int, bool, None]],
1482 text: str,
1483) -> str:
1484 r"""Weave in the header_issue_revision_combined from mapper or default.
1486 Trigger is text.rstrip().endswith('%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%%')
1488 Examples:
1490 >>> mapper = {'header_issue_revision_combined_show': ''}
1491 >>> t = r'\newcommand{\theMetaIssRev}{VALUE.SLOT}%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%%'
1492 >>> weave_meta_part_header_issue_revision_combined(mapper, t)
1493 '\\newcommand{\\theMetaIssRev}{ }%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%%'
1495 >>> mapper = {
1496 ... 'header_issue_revision_combined_show': ' ',
1497 ... 'header_issue_revision_combined': ' ',
1498 ... }
1499 >>> t = r'\newcommand{\theMetaIssRev}{VALUE.SLOT}%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%%'
1500 >>> weave_meta_part_header_issue_revision_combined(mapper, t)
1501 '\\newcommand{\\theMetaIssRev}{ }%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%%'
1503 >>> mapper = {
1504 ... 'header_issue_revision_combined_show': 'well-well-well',
1505 ... 'header_issue_revision_combined': 'visible-fixed-string',
1506 ... }
1507 >>> t = r'\newcommand{\theMetaIssRev}{VALUE.SLOT}%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%%'
1508 >>> weave_meta_part_header_issue_revision_combined(mapper, t)
1509 '\\newcommand{\\theMetaIssRev}{visible-fixed-string}%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%%'
1511 >>> mapper = {'no_header_issue_revision_combined_show': 'sorry'}
1512 >>> t = r'\newcommand{\theMetaIssRev}{VALUE.SLOT}%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%%'
1513 >>> weave_meta_part_header_issue_revision_combined(mapper, t)
1514 '\\newcommand{\\theMetaIssRev}{Iss \\theMetaIssCode, Rev \\theMetaRevCode}%%_PATCH_%_..._%_COMBINED_%%'
1515 """
1516 do_show_key = 'header_issue_revision_combined_show'
1517 if mapper.get(do_show_key, None) is not None and not mapper[do_show_key]:
1518 log.info(f'{do_show_key} set to false' ' - hiding date slot in header by setting value to a single space(" ")')
1519 return text.replace(VALUE_SLOT, ' ')
1520 log.info(f'{do_show_key} not set - considering header_issue_revision_combined ...')
1521 if mapper.get('header_issue_revision_combined'):
1522 return text.replace(VALUE_SLOT, mapper['header_issue_revision_combined'])
1523 else:
1524 log.info(
1525 'header_issue_revision_combined value not set ... setting'
1526 ' default (Iss \\theMetaIssCode, Rev \\theMetaRevCode)'
1527 )
1528 return text.replace(VALUE_SLOT, r'Iss \theMetaIssCode, Rev \theMetaRevCode')
1531@no_type_check
1532def weave_meta_part_proprietary_information(
1533 mapper: dict[str, Union[str, int, bool, None]],
1534 text: str,
1535) -> str:
1536 r"""Weave in the proprietary_information from mapper or default.
1538 Trigger is text.rstrip().endswith('%%_PATCH_%_PROPRIETARY_%_INFORMATION_%_LABEL_%%')
1540 Examples:
1542 >>> mapper = {'proprietary_information': ''}
1543 >>> t = r'\newcommand{\theProprietaryInformation}{VALUE.SLOT}%%_PATCH_%_PROPRIETARY_%_INFORMATION_%_LABEL_%%'
1544 >>> weave_meta_part_proprietary_information(mapper, t)
1545 '\\newcommand{\\theProprietaryInformation}{This is a notice.\n}%%_PATCH_%_PROPRIETARY_%_INFORMATION_%_LABEL_%%'
1547 >>> mapper = {'proprietary_information': __file__}
1548 >>> t = r'\newcommand{\theProprietaryInformation}{VALUE.SLOT}%%_PATCH_%_PROPRIETARY_%_INFORMATION_%_LABEL_%%'
1549 >>> weave_meta_part_proprietary_information(mapper, t)
1550 '\\newcommand{\\theProprietaryInformation}{...Weave the content of the meta file(s) of metadata.tex.in...'
1552 >>> mapper = {'proprietary_information': '/path/that/does/not/resolve.txt'}
1553 >>> t = r'\newcommand{\theProprietaryInformation}{VALUE.SLOT}%%_PATCH_%_PROPRIETARY_%_INFORMATION_%_LABEL_%%'
1554 >>> weave_meta_part_proprietary_information(mapper, t)
1555 '\\newcommand{\\theProprietaryInformation}{/path/that/does/not/resolve.txt}%%_PATCH_...INFORMATION_%_LABEL_%%'
1557 >>> really_a_png_file = 'liitos/placeholders/this-resource-is-missing.jpg'
1558 >>> pathlib.Path(really_a_png_file).is_file()
1559 True
1560 >>> mapper = {'proprietary_information': really_a_png_file}
1561 >>> t = r'\newcommand{\theProprietaryInformation}{VALUE.SLOT}%%_PATCH_%_PROPRIETARY_%_INFORMATION_%_LABEL_%%'
1562 >>> weave_meta_part_proprietary_information(mapper, t)
1563 '\\newcommand{\\theProprietaryInformation}{liitos/placeholders/this-resource-is-missing.jpg}%%_PATCH_..._%%'
1565 >>> mapper = {'bo_proprietary_information': 'sorry'}
1566 >>> t = r'\newcommand{\theProprietaryInformation}{VALUE.SLOT}%%_PATCH_%_PROPRIETARY_%_INFORMATION_%_LABEL_%%'
1567 >>> weave_meta_part_proprietary_information(mapper, t)
1568 '\\newcommand{\\theProprietaryInformation}{This is a notice.\n}%%_PATCH_%_PROPRIETARY_%_INFORMATION_%_LABEL_%%'
1570 >>> restore_value = WEAVE_DEFAULTS['proprietary_information']
1571 >>> WEAVE_DEFAULTS['proprietary_information'] = '/path/that/does/not/resolve.txt'
1572 >>> mapper = {'no_proprietary_information': 'sorry'}
1573 >>> t = r'\newcommand{\theProprietaryInformation}{VALUE.SLOT}%%_PATCH_%_PROPRIETARY_%_INFORMATION_%_LABEL_%%'
1574 >>> weave_meta_part_proprietary_information(mapper, t)
1575 '\\newcommand{\\theProprietaryInformation}{/path/that/does/not/resolve.txt}%%_PATCH_...INFORMATION_%_LABEL_%%'
1576 >>> WEAVE_DEFAULTS['proprietary_information'] = restore_value
1578 >>> really_a_png_file = 'liitos/placeholders/this-resource-is-missing.png'
1579 >>> pathlib.Path(really_a_png_file).is_file()
1580 True
1581 >>> restore_value = WEAVE_DEFAULTS['proprietary_information']
1582 >>> WEAVE_DEFAULTS['proprietary_information'] = really_a_png_file
1583 >>> mapper = {'no_proprietary_information': 'sorry'}
1584 >>> t = r'\newcommand{\theProprietaryInformation}{VALUE.SLOT}%%_PATCH_%_PROPRIETARY_%_INFORMATION_%_LABEL_%%'
1585 >>> weave_meta_part_proprietary_information(mapper, t)
1586 '\\newcommand{\\theProprietaryInformation}{liitos/placeholders/this-resource-is-missing.png}%%_PATCH_..._%%'
1587 >>> WEAVE_DEFAULTS['proprietary_information'] = restore_value
1588 """
1589 if mapper.get('proprietary_information'):
1590 prop_info = mapper['proprietary_information']
1591 if pathlib.Path(prop_info).is_file():
1592 try:
1593 prop_info_from_file = pathlib.Path(prop_info).open().read()
1594 prop_info = prop_info_from_file
1595 except (OSError, UnicodeDecodeError) as err:
1596 log.error(f'interpretation of proprietary_information value ({prop_info}) failed with error: {err}')
1597 log.warning(f'using value ({prop_info}) directly for proprietary_information')
1598 else:
1599 log.info(f'using value ({prop_info}) directly for proprietary_information (no file)')
1600 return text.replace(VALUE_SLOT, prop_info)
1601 else:
1602 log.warning('proprietary_information value not set ... setting default from module ...')
1603 prop_info = WEAVE_DEFAULTS['proprietary_information']
1604 if pathlib.Path(prop_info).is_file():
1605 try:
1606 prop_info_from_file = pathlib.Path(prop_info).open().read()
1607 prop_info = prop_info_from_file
1608 except (OSError, UnicodeDecodeError) as err:
1609 log.error(f'interpretation of proprietary_information value ({prop_info}) failed with error: {err}')
1610 log.warning(f'using value ({prop_info}) directly for proprietary_information')
1611 else:
1612 log.info(f'using value ({prop_info}) directly for proprietary_information (no file)')
1613 return text.replace(VALUE_SLOT, prop_info)
1616@no_type_check
1617def weave_meta_part_stretch(
1618 mapper: dict[str, Union[str, int, bool, None]],
1619 text: str,
1620) -> str:
1621 """Weave in the stretch from mapper or default.
1623 Trigger is text.rstrip().endswith('%%_PATCH_%_STRETCH_%%')
1624 """
1625 return weave_meta_part_with_default_slot(mapper, text, 'stretch')
1628@no_type_check
1629def weave_meta_part_lox_indent(
1630 mapper: dict[str, Union[str, int, bool, None]],
1631 text: str,
1632) -> str:
1633 """Weave in the lox_indent from mapper or default.
1635 Trigger is text.rstrip().endswith('%%_PATCH_%_LOX_INDENT_%%')
1636 """
1637 return weave_meta_part_with_default_slot(mapper, text, 'lox_indent')
1640@no_type_check
1641def dispatch_meta_weaver(
1642 mapper: dict[str, Union[str, int, bool, None]],
1643 text: str,
1644) -> str:
1645 """Dispatch the meta weaver by mapping to handled groups per source marker."""
1646 dispatch = {
1647 '%%_PATCH_%_HEADER_%_TITLE_%%': weave_meta_part_header_title,
1648 '%%_PATCH_%_TITLE_%_SLUG_%%': weave_meta_part_title_slug,
1649 '%%_PATCH_%_MAIN_%_TITLE_%%': weave_meta_part_title,
1650 '%%_PATCH_%_SUB_%_TITLE_%%': weave_meta_part_sub_title,
1651 '%%_PATCH_%_TYPE_%%': weave_meta_part_header_type,
1652 '%%_PATCH_%_ID_%_LABEL_%%': weave_meta_part_header_id_label,
1653 '%%_PATCH_%_ID_%%': weave_meta_part_header_id,
1654 '%%_PATCH_%_ISSUE_%%': weave_meta_part_issue,
1655 '%%_PATCH_%_REVISION_%%': weave_meta_part_revision,
1656 '%%_PATCH_%_DATE_%_LABEL_%%': weave_meta_part_header_date_label,
1657 '%%_PATCH_%_DATE_%%': weave_meta_part_header_date,
1658 '%%_PATCH_%_FRAME_%_NOTE_%%': weave_meta_part_footer_frame_note,
1659 '%%_PATCH_%_FOOT_%_PAGE_%_COUNTER_%_LABEL_%%': weave_meta_part_footer_page_number_prefix,
1660 '%%_PATCH_%_CHANGELOG_%_ISSUE_%_LABEL_%%': weave_meta_part_change_log_issue_label,
1661 '%%_PATCH_%_CHANGELOG_%_REVISION_%_LABEL_%%': weave_meta_part_change_log_revision_label,
1662 '%%_PATCH_%_CHANGELOG_%_DATE_%_LABEL_%%': weave_meta_part_change_log_date_label,
1663 '%%_PATCH_%_CHANGELOG_%_AUTHOR_%_LABEL_%%': weave_meta_part_change_log_author_label,
1664 '%%_PATCH_%_CHANGELOG_%_DESCRIPTION_%_LABEL_%%': weave_meta_part_change_log_description_label,
1665 '%%_PATCH_%_APPROVALS_%_ADJUSTABLE_%_VERTICAL_%_SPACE_%%': weave_meta_part_approvals_adjustable_vertical_space,
1666 '%%_PATCH_%_BLURB_%_ADJUSTABLE_%_VERTICAL_%_SPACE_%%': weave_meta_part_proprietary_information_adjustable_vertical_space, # noqa
1667 '%%_PATCH_%_BLURB_%_TUNE_%_HEADER_%_SEP_%%': weave_meta_part_proprietary_information_tune_header_sep,
1668 '%%_PATCH_%_CHANGE_%_LOG_%_TUNE_%_HEADER_%_SEP_%%': weave_meta_part_change_log_tune_header_sep,
1669 '%%_PATCH_%_APPROVALS_%_DEPARTMENT_%_LABEL_%%': weave_meta_part_approvals_department_label,
1670 '%%_PATCH_%_APPROVALS_%_DEPARTMENT_%_VALUE_%%': weave_meta_part_approvals_department_value,
1671 '%%_PATCH_%_APPROVALS_%_ROLE_%_LABEL_%%': weave_meta_part_approvals_role_label,
1672 '%%_PATCH_%_APPROVALS_%_NAME_%_LABEL_%%': weave_meta_part_approvals_name_label,
1673 '%%_PATCH_%_APPROVALS_%_DATE_%_AND_%_SIGNATURE_%_LABEL_%%': weave_meta_part_approvals_date_and_signature_label,
1674 '%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%_LABEL_%%': weave_meta_part_header_issue_revision_combined_label,
1675 '%%_PATCH_%_ISSUE_%_REVISION_%_COMBINED_%%': weave_meta_part_header_issue_revision_combined,
1676 '%%_PATCH_%_PROPRIETARY_%_INFORMATION_%_LABEL_%%': weave_meta_part_proprietary_information,
1677 '%%_PATCH_%_STRETCH_%%': weave_meta_part_stretch,
1678 '%%_PATCH_%_LOX_INDENT_%%': weave_meta_part_lox_indent,
1679 }
1680 for trigger, weaver in dispatch.items():
1681 if text.rstrip().endswith(trigger):
1682 return weaver(mapper, text)
1683 return text
1686@no_type_check
1687def weave_meta_meta(meta_map: gat.Meta, latex: list[str]) -> list[str]:
1688 """TODO."""
1689 log.info('weaving in the meta data per metadata.tex.in into metadata.tex ...')
1690 completed = [dispatch_meta_weaver(meta_map['document']['common'], line) for line in latex]
1691 if completed and completed[-1]:
1692 completed.append('\n')
1693 return completed
1696@no_type_check
1697def weave(
1698 doc_root: Union[str, pathlib.Path],
1699 structure_name: str,
1700 target_key: str,
1701 facet_key: str,
1702 options: dict[str, bool],
1703 externals: ExternalsType,
1704) -> int:
1705 """Weave the metadata received into various targets.
1707 Examples:
1709 >>> restore_cwd = os.getcwd()
1710 >>> dr = '.'
1711 >>> sn = 'foo'
1712 >>> tk = ''
1713 >>> fk = ''
1714 >>> op = {'bar': True}
1715 >>> ex = {'baz': {'quux': 'nowhere-to-be-found'}}
1716 >>> weave(dr, sn, tk, fk, op, ex)
1717 2
1718 >>> os.chdir(restore_cwd)
1720 >>> restore_cwd = os.getcwd()
1721 >>> dr = 'example/tuna'
1722 >>> sn = 'structure.yml'
1723 >>> tk = 'prod_kind'
1724 >>> fk = 'non-existing-facet-key'
1725 >>> op = {'bar': True}
1726 >>> ex = {'baz': {'quux': 'nowhere-to-be-found'}}
1727 >>> weave(dr, sn, tk, fk, op, ex)
1728 1
1729 >>> os.chdir(restore_cwd)
1731 >>> restore_cwd = os.getcwd()
1732 >>> dr = 'test/fixtures/basic/'
1733 >>> sn = 'structure.yml'
1734 >>> tk = 'abc'
1735 >>> fk = 'missing'
1736 >>> op = {'bar': True}
1737 >>> ex = {'baz': {'quux': 'nowhere-to-be-found'}}
1738 >>> weave(dr, sn, tk, fk, op, ex)
1739 1
1740 >>> os.chdir(restore_cwd)
1742 >>> restore_cwd = os.getcwd()
1743 >>> dr = 'example/tuna'
1744 >>> sn = 'structure.yml'
1745 >>> tk = 'prod_kind'
1746 >>> fk = 'tuna'
1747 >>> op = {'bar': True}
1748 >>> ex = {
1749 ... 'bookmatter': {'is_custom': False, 'id': 'templates/bookmatter.tex.in'},
1750 ... 'driver': {'is_custom': False, 'id': 'templates/driver.tex.in'},
1751 ... 'metadata': {'is_custom': False, 'id': 'templates/metadata.tex.in'},
1752 ... 'publisher': {'is_custom': False, 'id': 'templates/publisher.tex.in'},
1753 ... 'setup': {'is_custom': False, 'id': 'templates/setup.tex.in'},
1754 ... }
1755 >>> weave(dr, sn, tk, fk, op, ex)
1756 0
1757 >>> os.chdir(restore_cwd)
1759 >>> restore_cwd = os.getcwd()
1760 >>> dr = 'example/tuna'
1761 >>> sn = 'structure.yml'
1762 >>> tk = 'prod_kind'
1763 >>> fk = 'tuna'
1764 >>> op = {'bar': True}
1765 >>> abs_here = pathlib.Path().resolve()
1766 >>> ex = {
1767 ... 'bookmatter': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/bookmatter.tex.in'},
1768 ... 'driver': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/driver.tex.in'},
1769 ... 'metadata': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/metadata.tex.in'},
1770 ... 'publisher': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/publisher.tex.in'},
1771 ... 'setup': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/setup.tex.in'},
1772 ... }
1773 >>> try:
1774 ... code = weave(dr, sn, tk, fk, op, ex)
1775 ... except FileNotFoundError:
1776 ... code = -1
1777 >>> os.chdir(restore_cwd)
1778 >>> code
1779 0
1781 >>> restore_cwd = os.getcwd()
1782 >>> dr = 'example/ejected-templates'
1783 >>> sn = 'structure.yml'
1784 >>> tk = 'prod_kind'
1785 >>> fk = 'ejected-templates'
1786 >>> op = {'bar': True}
1787 >>> abs_here = pathlib.Path().resolve()
1788 >>> ex = {
1789 ... 'bookmatter': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/bookmatter.tex.in'},
1790 ... 'driver': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/driver.tex.in'},
1791 ... 'metadata': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/metadata.tex.in'},
1792 ... 'publisher': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/publisher.tex.in'},
1793 ... 'setup': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/setup.tex.in'},
1794 ... }
1795 >>> try:
1796 ... code = weave(dr, sn, tk, fk, op, ex)
1797 ... except FileNotFoundError:
1798 ... code = -1
1799 >>> os.chdir(restore_cwd)
1800 >>> code
1801 0
1803 >>> restore_cwd = os.getcwd()
1804 >>> dr = 'example/ejected-templates'
1805 >>> sn = 'structure.yml'
1806 >>> tk = 'prod_kind'
1807 >>> fk = 'ejected-templates-borked'
1808 >>> op = {'bar': True}
1809 >>> abs_here = pathlib.Path().resolve()
1810 >>> ex = {
1811 ... 'bookmatter': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/bookmatter.tex.in'},
1812 ... 'driver': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/driver.tex.in'},
1813 ... 'metadata': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/metadata.tex.in'},
1814 ... 'publisher': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/publisher.tex.in'},
1815 ... 'setup': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/setup.tex.in'},
1816 ... }
1817 >>> try:
1818 ... code = weave(dr, sn, tk, fk, op, ex)
1819 ... except FileNotFoundError:
1820 ... code = -1
1821 >>> os.chdir(restore_cwd)
1822 >>> code
1823 0
1825 >>> restore_cwd = os.getcwd()
1826 >>> dr = 'example/tuna'
1827 >>> sn = 'structure.yml'
1828 >>> tk = 'prod_kind'
1829 >>> fk = 'tuna'
1830 >>> op = {'bar': True}
1831 >>> abs_here = pathlib.Path().resolve()
1832 >>> ex = {
1833 ... 'bookmatter': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/bookmatter.tex.in-no'},
1834 ... 'driver': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/driver.tex.in-no'},
1835 ... 'metadata': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/metadata.tex.in-no'},
1836 ... 'publisher': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/publisher.tex.in-no'},
1837 ... 'setup': {'is_custom': True, 'id': abs_here / 'example/ejected-templates/setup.tex.in-no'},
1838 ... }
1839 >>> try:
1840 ... code = weave(dr, sn, tk, fk, op, ex)
1841 ... except FileNotFoundError:
1842 ... code = -1
1843 >>> os.chdir(restore_cwd)
1844 >>> code
1845 0
1846 """
1847 log.info(LOG_SEPARATOR)
1848 log.info('entered meta weave function ...')
1849 target_code = target_key
1850 facet_code = facet_key
1851 if not facet_code.strip() or not target_code.strip():
1852 log.error(f'meta requires non-empty target ({target_code}) and facet ({facet_code}) codes')
1853 return 2
1855 log.info(f'parsed target ({target_code}) and facet ({facet_code}) from request')
1857 structure, asset_map = gat.prelude(
1858 doc_root=doc_root, structure_name=structure_name, target_key=target_key, facet_key=facet_key, command='meta'
1859 )
1860 log.info(f'prelude teleported processor into the document root at ({os.getcwd()}/)')
1861 rel_concat_folder_path = pathlib.Path('render/pdf/')
1862 rel_concat_folder_path.mkdir(parents=True, exist_ok=True)
1863 os.chdir(rel_concat_folder_path)
1864 log.info(f'meta (this processor) teleported into the render/pdf location ({os.getcwd()}/)')
1866 ok, aspect_map = too.load_target(target_code, facet_code)
1867 if not ok or not aspect_map:
1868 return 0 if ok else 1
1870 metadata = load(aspect_map)
1871 if isinstance(metadata, int):
1872 return 1
1874 meta_doc_common = metadata['document']['common'] # noqa
1875 log.debug(f'in meta.weave {meta_doc_common=}')
1876 log.debug(f'in meta.weave {externals=}')
1877 if externals['bookmatter']['is_custom']:
1878 log.info(
1879 'per environment variable value request to load external bookmatter layout template'
1880 f' from {externals["bookmatter"]["id"]} for title page incl. approvals'
1881 )
1882 log.debug(f'in meta.weave bookmatter_path is "{meta_doc_common.get("bookmatter_path", "NOT-PRESENT")}"')
1883 if 'bookmatter_path' in meta_doc_common:
1884 bookmatter_path_str = meta_doc_common['bookmatter_path']
1885 if bookmatter_path_str and isinstance(bookmatter_path_str, str):
1886 externals['bookmatter'] = {'id': bookmatter_path_str.strip(), 'is_custom': True}
1887 log.info(
1888 f'per configuration variable value request to load external bookmatter layout template'
1889 f' from {externals["bookmatter"]["id"]} title page incl. approvals'
1890 )
1892 if externals['driver']['is_custom']:
1893 log.info(
1894 'per environment variable value request to load external driver layout template'
1895 f' from {externals["driver"]["id"]} for general document structure'
1896 )
1897 log.debug(f'in meta.weave driver_path is "{meta_doc_common.get("driver_path", "NOT-PRESENT")}"')
1898 if 'driver_path' in meta_doc_common:
1899 driver_path_str = meta_doc_common['driver_path']
1900 if driver_path_str and isinstance(driver_path_str, str):
1901 externals['driver'] = {'id': driver_path_str.strip(), 'is_custom': True}
1902 log.info(
1903 f'per configuration variable value request to load external driver layout template'
1904 f' from {externals["driver"]["id"]} for general document structure'
1905 )
1907 if externals['metadata']['is_custom']:
1908 log.info(
1909 'per environment variable value request to load external metadata template'
1910 f' from {externals["metadata"]["id"]} for mapping values to required keys'
1911 )
1912 log.debug(f'in meta.weave metadata_path is "{meta_doc_common.get("metadata_path", "NOT-PRESENT")}"')
1913 if 'metadata_path' in meta_doc_common:
1914 metadata_path_str = meta_doc_common['metadata_path']
1915 if metadata_path_str and isinstance(metadata_path_str, str):
1916 externals['metadata'] = {'id': metadata_path_str.strip(), 'is_custom': True}
1917 log.info(
1918 f'per configuration variable value request to load external metadata template'
1919 f' from {externals["metadata"]["id"]} for mapping values to required keys'
1920 )
1922 if externals['publisher']['is_custom']:
1923 log.info(
1924 'per environment variable value request to load external publisher layout template'
1925 f' from {externals["publisher"]["id"]} for changes and notices'
1926 )
1927 log.debug(f'in meta.weave publisher_path is "{meta_doc_common.get("publisher_path", "NOT-PRESENT")}"')
1928 if 'publisher_path' in meta_doc_common:
1929 publisher_path_str = meta_doc_common['publisher_path']
1930 if publisher_path_str and isinstance(publisher_path_str, str):
1931 externals['publisher'] = {'id': publisher_path_str.strip(), 'is_custom': True}
1932 log.info(
1933 f'per configuration variable value request to load external publisher layout template'
1934 f' from {externals["publisher"]["id"]} for changes and notices'
1935 )
1937 if externals['setup']['is_custom']:
1938 log.info(
1939 'per environment variable value request to load external setup layout template'
1940 f' from {externals["setup"]["id"]} for general document setup'
1941 )
1942 log.debug(f'in meta.weave setup_path is "{meta_doc_common.get("setup_path", "NOT-PRESENT")}"')
1943 if 'setup_path' in meta_doc_common:
1944 setup_path_str = meta_doc_common['setup_path']
1945 if setup_path_str and isinstance(setup_path_str, str):
1946 externals['setup'] = {'id': setup_path_str.strip(), 'is_custom': True}
1947 log.info(
1948 f'per configuration variable value request to load external setup layout template'
1949 f' from {externals["setup"]["id"]} for general document setup'
1950 )
1952 if 'approvals_strategy' in meta_doc_common:
1953 approvals_strategy_str = meta_doc_common['approvals_strategy']
1954 if approvals_strategy_str and approvals_strategy_str in KNOWN_APPROVALS_STRATEGIES:
1955 memo = options.get('approvals_strategy', 'unset')
1956 options['approvals_strategy'] = approvals_strategy_str
1957 log.info(
1958 f'per configuration variable value request for approvals strategy ({approvals_strategy_str})'
1959 f' was set before to ({memo}) from default or command line'
1960 )
1962 if 'table_caption_below' in meta_doc_common:
1963 table_caption_below = bool(meta_doc_common['table_caption_below'])
1964 if table_caption_below:
1965 memo = options.get('table_caption_below', False)
1966 options['table_caption_below'] = table_caption_below
1967 tc_strategy = 'below' if table_caption_below else 'above'
1968 log.info(
1969 f'per configuration variable value request for table captions ({tc_strategy})'
1970 f' was set before to ({memo}) from default or command line'
1971 )
1973 if 'table_uglify' in meta_doc_common:
1974 table_uglify = bool(meta_doc_common['table_uglify'])
1975 if table_uglify:
1976 memo = options.get('table_uglify', False)
1977 options['table_uglify'] = table_uglify
1978 tc_style = 'ugly' if table_uglify else 'readable'
1979 log.info(
1980 f'per configuration variable value request for table style ({tc_style})'
1981 f' was set before to ({memo}) from default or command line'
1982 )
1984 metadata_template_is_custom = externals['metadata']['is_custom']
1985 metadata_template = str(externals['metadata']['id'])
1986 metadata_path = pathlib.Path('metadata.tex')
1988 try:
1989 metadata_template = tpl.load_resource(metadata_template, metadata_template_is_custom)
1990 except FileNotFoundError:
1991 log.error(
1992 f'could not load metadata template in {os.getcwd()} per'
1993 f' tpl.load_resource({metadata_template}, {metadata_template_is_custom})'
1994 )
1995 if metadata_template_is_custom: 1995 ↛ 1998line 1995 didn't jump to line 1998 because the condition on line 1995 was always true
1996 existence = 'does exist' if pathlib.Path(metadata_template).is_file() else 'does not exist'
1997 log.error(f'detail: external metadata template {existence}')
1998 lines = [line.rstrip() for line in metadata_template.split('\n')]
1999 lines = weave_meta_meta(metadata, lines)
2000 with open(metadata_path, 'wt', encoding=ENCODING) as handle:
2001 handle.write('\n'.join(lines))
2003 driver_template_is_custom = externals['driver']['is_custom']
2004 driver_template = str(externals['driver']['id'])
2005 driver_path = pathlib.Path('driver.tex')
2007 try:
2008 driver_template = tpl.load_resource(driver_template, driver_template_is_custom)
2009 except FileNotFoundError:
2010 log.error(
2011 f'could not load driver template in {os.getcwd()} per'
2012 f' tpl.load_resource({driver_template}, {driver_template_is_custom})'
2013 )
2014 if driver_template_is_custom: 2014 ↛ 2017line 2014 didn't jump to line 2017 because the condition on line 2014 was always true
2015 existence = 'does exist' if pathlib.Path(driver_template).is_file() else 'does not exist'
2016 log.error(f'detail: external driver template {existence}')
2017 lines = [line.rstrip() for line in driver_template.split('\n')]
2018 lines = weave_meta_driver(metadata, lines)
2019 with open(driver_path, 'wt', encoding=ENCODING) as handle:
2020 handle.write('\n'.join(lines))
2022 setup_template_is_custom = externals['setup']['is_custom']
2023 setup_template = str(externals['setup']['id'])
2024 setup_path = pathlib.Path('setup.tex')
2026 try:
2027 setup_template = tpl.load_resource(setup_template, setup_template_is_custom)
2028 except FileNotFoundError:
2029 log.error(
2030 f'could not load driver template in {os.getcwd()} per'
2031 f' tpl.load_resource({setup_template}, {setup_template_is_custom})'
2032 )
2033 if setup_template_is_custom: 2033 ↛ 2036line 2033 didn't jump to line 2036 because the condition on line 2033 was always true
2034 existence = 'does exist' if pathlib.Path(setup_template).is_file() else 'does not exist'
2035 log.error(f'detail: external setup template {existence}')
2036 lines = [line.rstrip() for line in setup_template.split('\n')]
2037 lines = weave_meta_setup(metadata, lines)
2038 with open(setup_path, 'wt', encoding=ENCODING) as handle:
2039 handle.write('\n'.join(lines))
2041 return 0