robotframework-libtoc 1.5.0__tar.gz → 1.7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robotframework-libtoc
3
- Version: 1.5.0
3
+ Version: 1.7.0
4
4
  Summary: Docs and TOC generator for Robot Framework resources and libs
5
5
  Home-page: https://github.com/amochin/robotframework-libtoc
6
6
  License: Apache-2.0
@@ -21,7 +21,7 @@ Description-Content-Type: text/markdown
21
21
  ## Robot Framework LibTOC
22
22
 
23
23
  ## What it does
24
- This tool generates docs using Robot Framework [Libdoc](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#libdoc) for an entire folder (or multiple folders) with Robot Framework resources/libs and creates a TOC (table of contents) file for them
24
+ This tool generates docs using Robot Framework [Libdoc](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#libdoc) for an entire folder (or multiple folders) with Robot Framework resources/libs and creates a TOC (table of contents) file for them.
25
25
 
26
26
  ## Why use it
27
27
  The Robot Framework Libdoc tool normally generates a HTML file for a single keyword library or a resource file.
@@ -40,7 +40,7 @@ in the intranet or uploaded as CI artifact - so everybody can easily access the
40
40
  - It looks for the **config files** named `.libtoc` which contain items you would like to create docs for:
41
41
  1. Paths to resource/lib files in [glob format](https://en.wikipedia.org/wiki/Glob_(programming))
42
42
  2. RF libraries, installed or available in PYTHONPATH using the provided fully qualified name
43
- > Librariy import params (if necessary) like described in [libdoc user guide](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#general-usage)
43
+ > Library import params (if necessary) like described in [libdoc user guide](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#general-usage)
44
44
  > Other libdoc CLI options (e.g. version or name of the output file) are not supported
45
45
  3. Paths to resource/lib files in [glob format](https://en.wikipedia.org/wiki/Glob_(programming)) inside Python packages, loaded from the PYTHONPATH
46
46
  > See more about bundling RF resources in Python packages in [RF User Guide](http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#taking-resource-files-into-use)
@@ -84,11 +84,13 @@ pip install robotframework-libtoc
84
84
  - Create the `.libtoc` config files in the *root of the resources folder* and/or in *direct subfolders* where you need docs to be created.
85
85
  - Run `libtoc`. The last `resources_dirs` parameter is mandatory, it takes any number of paths. Other params are optional:
86
86
  - `-d, --output_dir`
87
+ - `-P, --pythonpath`
87
88
  - `--config_file`
88
89
  - `--toc_file`
89
90
  - `--toc_template`
90
91
  - `--homepage_template`
91
- - `-P, --pythonpath`
92
+ - `--no_timestamp`
93
+ - `--tree-label`
92
94
 
93
95
  Examples:
94
96
  ```shell
@@ -97,6 +99,7 @@ pip install robotframework-libtoc
97
99
  libtoc --output_dir docs example_resources
98
100
  libtoc --output_dir docs --toc_file MY_SPECIAL_NAME_FOR_DOCS.html example_resources
99
101
  libtoc --toc_template MY_CUSTOM_TOC.html --homepage_template MY_CUSTOM_HOMEPAGE.html example_resources
102
+ libtoc --tree-label "my_folder=My Display Name" --tree-label "my_lib=My Lib Label" example_resources
100
103
  ```
101
104
 
102
105
  - Open the created file, e.g. `docs/keyword_docs.html`
@@ -112,3 +115,13 @@ There are two ways to extend the list of paths where the libraries are searched
112
115
 
113
116
  See more in [Robot Framework User Guide](http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#pythonpath).
114
117
 
118
+ ## How to customize TOC tree item labels
119
+ By default the TOC navigation tree uses the original folder, file and library names.
120
+ Use `--tree-label KEY=VALUE` to replace any folder, library or file name (without extension) with a custom display label — without affecting the actual file paths.
121
+
122
+ The option can be repeated any number of times:
123
+ ```shell
124
+ libtoc --tree-label "sut_x=SUT X (Production)" --tree-label "common=Common Keywords" example_resources
125
+ ```
126
+ > - Only the visible label in the tree is changed. Folder structure and file paths remain untouched.
127
+ > - If the item name is found multiple times in the TOC, all occurrences would be replaced.
@@ -1,7 +1,7 @@
1
1
  ## Robot Framework LibTOC
2
2
 
3
3
  ## What it does
4
- This tool generates docs using Robot Framework [Libdoc](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#libdoc) for an entire folder (or multiple folders) with Robot Framework resources/libs and creates a TOC (table of contents) file for them
4
+ This tool generates docs using Robot Framework [Libdoc](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#libdoc) for an entire folder (or multiple folders) with Robot Framework resources/libs and creates a TOC (table of contents) file for them.
5
5
 
6
6
  ## Why use it
7
7
  The Robot Framework Libdoc tool normally generates a HTML file for a single keyword library or a resource file.
@@ -20,7 +20,7 @@ in the intranet or uploaded as CI artifact - so everybody can easily access the
20
20
  - It looks for the **config files** named `.libtoc` which contain items you would like to create docs for:
21
21
  1. Paths to resource/lib files in [glob format](https://en.wikipedia.org/wiki/Glob_(programming))
22
22
  2. RF libraries, installed or available in PYTHONPATH using the provided fully qualified name
23
- > Librariy import params (if necessary) like described in [libdoc user guide](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#general-usage)
23
+ > Library import params (if necessary) like described in [libdoc user guide](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#general-usage)
24
24
  > Other libdoc CLI options (e.g. version or name of the output file) are not supported
25
25
  3. Paths to resource/lib files in [glob format](https://en.wikipedia.org/wiki/Glob_(programming)) inside Python packages, loaded from the PYTHONPATH
26
26
  > See more about bundling RF resources in Python packages in [RF User Guide](http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#taking-resource-files-into-use)
@@ -64,11 +64,13 @@ pip install robotframework-libtoc
64
64
  - Create the `.libtoc` config files in the *root of the resources folder* and/or in *direct subfolders* where you need docs to be created.
65
65
  - Run `libtoc`. The last `resources_dirs` parameter is mandatory, it takes any number of paths. Other params are optional:
66
66
  - `-d, --output_dir`
67
+ - `-P, --pythonpath`
67
68
  - `--config_file`
68
69
  - `--toc_file`
69
70
  - `--toc_template`
70
71
  - `--homepage_template`
71
- - `-P, --pythonpath`
72
+ - `--no_timestamp`
73
+ - `--tree-label`
72
74
 
73
75
  Examples:
74
76
  ```shell
@@ -77,6 +79,7 @@ pip install robotframework-libtoc
77
79
  libtoc --output_dir docs example_resources
78
80
  libtoc --output_dir docs --toc_file MY_SPECIAL_NAME_FOR_DOCS.html example_resources
79
81
  libtoc --toc_template MY_CUSTOM_TOC.html --homepage_template MY_CUSTOM_HOMEPAGE.html example_resources
82
+ libtoc --tree-label "my_folder=My Display Name" --tree-label "my_lib=My Lib Label" example_resources
80
83
  ```
81
84
 
82
85
  - Open the created file, e.g. `docs/keyword_docs.html`
@@ -91,3 +94,14 @@ There are two ways to extend the list of paths where the libraries are searched
91
94
  2. Set the **PYTHONPATH** environment variable
92
95
 
93
96
  See more in [Robot Framework User Guide](http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#pythonpath).
97
+
98
+ ## How to customize TOC tree item labels
99
+ By default the TOC navigation tree uses the original folder, file and library names.
100
+ Use `--tree-label KEY=VALUE` to replace any folder, library or file name (without extension) with a custom display label — without affecting the actual file paths.
101
+
102
+ The option can be repeated any number of times:
103
+ ```shell
104
+ libtoc --tree-label "sut_x=SUT X (Production)" --tree-label "common=Common Keywords" example_resources
105
+ ```
106
+ > - Only the visible label in the tree is changed. Folder structure and file paths remain untouched.
107
+ > - If the item name is found multiple times in the TOC, all occurrences would be replaced.
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "robotframework-libtoc"
3
- version = "1.5.0"
3
+ version = "1.7.0"
4
4
  description = "Docs and TOC generator for Robot Framework resources and libs"
5
5
  authors = ["Andre Mochinin"]
6
6
  license = "Apache-2.0"
@@ -29,7 +29,10 @@ def toc(links, timestamp, home_page_path, template_file="", search_index=None):
29
29
 
30
30
  result = html_template.replace("{}", home_page_path, 1)
31
31
  result = result.replace("{}", links, 1)
32
- result = result.replace("{}", timestamp, 1)
32
+ if timestamp:
33
+ result = result.replace("{}", timestamp, 1)
34
+ else:
35
+ result = result.replace("Created: {}", "", 1)
33
36
 
34
37
  # inject search index data (done after format() to avoid brace escaping issues)
35
38
  if search_index is not None:
@@ -121,16 +124,16 @@ def extract_libdoc_data(html_file_path):
121
124
  return None
122
125
 
123
126
 
124
- def build_search_index(src_dir, base_dir):
127
+ def build_search_index(src_dir, base_dir, homepage_file):
125
128
  """
126
- Builds a search index from all libdoc HTML files in src_dir.
129
+ Builds a search index from all libdoc HTML files in src_dir (except ``homepage_file``).
127
130
  Returns a list of library/resource entries with their keywords.
128
131
  """
129
132
  index = []
130
133
  for dirpath, dirnames, filenames in os.walk(src_dir):
131
134
  dirnames.sort()
132
135
  for file_name in sorted(filenames):
133
- if file_name.endswith(".html") and file_name != "homepage.html":
136
+ if file_name.endswith(".html") and file_name != homepage_file:
134
137
  file_path = os.path.join(dirpath, file_name)
135
138
  data = extract_libdoc_data(file_path)
136
139
  if data:
@@ -170,9 +173,31 @@ def build_search_index(src_dir, base_dir):
170
173
  return index
171
174
 
172
175
 
173
- def inject_libtoc_script(src_dir):
176
+ def strip_libdoc_timestamps(src_dir, homepage_file):
177
+ """
178
+ Removes the 'generated' timestamp from the libdoc JSON data embedded in each
179
+ libdoc HTML file in src_dir (except ``homepage_file``), replacing it with an empty string.
180
+ """
181
+ for dirpath, dirnames, filenames in os.walk(src_dir):
182
+ dirnames.sort()
183
+ for file_name in sorted(filenames):
184
+ if file_name.endswith(".html") and file_name != homepage_file:
185
+ file_path = os.path.join(dirpath, file_name)
186
+ with open(file_path, "r", encoding="utf-8") as f:
187
+ content = f.read()
188
+ new_content = re.sub(
189
+ r'"generated":\s*"[^"]*"',
190
+ '"generated": ""',
191
+ content,
192
+ )
193
+ if new_content != content:
194
+ with open(file_path, "w", encoding="utf-8") as f:
195
+ f.write(new_content)
196
+
197
+
198
+ def inject_libtoc_script(src_dir, homepage_file):
174
199
  """
175
- Injects a small <script> into each libdoc HTML file in src_dir that:
200
+ Injects a small <script> into each libdoc HTML file in src_dir (except ``homepage_file``) that:
176
201
  - Reads the theme from localStorage and applies data-theme on <html> so the
177
202
  page respects the libtoc theme choice even when file:// cross-origin prevents
178
203
  parent frame DOM access.
@@ -201,7 +226,7 @@ def inject_libtoc_script(src_dir):
201
226
  for dirpath, dirnames, filenames in os.walk(src_dir):
202
227
  dirnames.sort()
203
228
  for file_name in sorted(filenames):
204
- if file_name.endswith(".html") and file_name != "homepage.html":
229
+ if file_name.endswith(".html") and file_name != homepage_file:
205
230
  file_path = os.path.join(dirpath, file_name)
206
231
  with open(file_path, "r", encoding="utf-8") as f:
207
232
  content = f.read()
@@ -213,18 +238,30 @@ def inject_libtoc_script(src_dir):
213
238
  f.write(content)
214
239
 
215
240
 
216
- def add_files_from_folder(folder, base_dir_path, root=True):
241
+ def add_files_from_folder(folder, base_dir_path, root=True, folder_and_file_labels=None):
217
242
  """
218
243
  Creates a HTML source code with links to all HTML files in the `folder` and all it's subfolders.
219
244
  The links contain file paths relative to the `base_dir_path`.
220
245
 
221
246
  The `root` parameter is needed for internal usage only - it's set to False during deeper recursive calls.
222
247
  """
248
+
249
+ def get_label_for_file_or_folder(item_name, labels):
250
+ if item_name in labels:
251
+ item_display_name = labels[item_name]
252
+ print(f">> Modified label of tree item: '{item_name}' -> '{item_display_name}'")
253
+ else:
254
+ item_display_name = item_name
255
+ return item_display_name
256
+
257
+ if folder_and_file_labels is None:
258
+ folder_and_file_labels = {}
223
259
  result_str = ""
224
260
  if not root: # means we're in the root - no collapsible need in this case
261
+ folder_display_name = get_label_for_file_or_folder(os.path.basename(folder), folder_and_file_labels)
225
262
  result_str += """<button class="collapsible">{}</button>
226
263
  """.format(
227
- os.path.basename(folder)
264
+ folder_display_name
228
265
  )
229
266
 
230
267
  result_str += """<div class="collapsible_content">
@@ -234,14 +271,15 @@ def add_files_from_folder(folder, base_dir_path, root=True):
234
271
  item_path = os.path.abspath(os.path.join(folder, item))
235
272
  if item.endswith(".html"):
236
273
  name_without_ext = os.path.splitext(item)[0]
274
+ display_name = get_label_for_file_or_folder(name_without_ext, folder_and_file_labels)
237
275
  result_str += """<a class="link_not_selected" href="{}" target="targetFrame">{}</a>
238
276
  """.format(
239
- os.path.relpath(item_path, base_dir_path), name_without_ext
277
+ os.path.relpath(item_path, base_dir_path), display_name
240
278
  )
241
279
  else:
242
280
  if os.path.isdir(item_path):
243
281
  result_str += add_files_from_folder(
244
- item_path, base_dir_path, root=False
282
+ item_path, base_dir_path, root=False, folder_and_file_labels=folder_and_file_labels
245
283
  )
246
284
 
247
285
  if not root:
@@ -353,6 +391,8 @@ def create_toc(
353
391
  homepage_file="homepage.html",
354
392
  toc_template="",
355
393
  homepage_template="",
394
+ no_timestamp=False,
395
+ folder_labels=None,
356
396
  ):
357
397
  """
358
398
  Generates a `toc_file` (Table of Contents) HTML page with links to all HTML files inside the `html_docs_dir` and all it's subfolders.
@@ -376,16 +416,20 @@ def create_toc(
376
416
 
377
417
  # create homepage in "src"
378
418
  homepage_path = os.path.join(src_subdir, homepage_file)
379
- current_date_time = datetime.now().strftime("%d.%m.%Y %H:%M:%S")
380
- doc_files_links = add_files_from_folder(src_subdir, os.path.abspath(html_docs_dir))
419
+ current_date_time = "" if no_timestamp else datetime.now().strftime("%d.%m.%Y %H:%M:%S")
420
+ doc_files_links = add_files_from_folder(src_subdir, os.path.abspath(html_docs_dir), folder_and_file_labels=folder_labels)
381
421
  with open(homepage_path, "w", encoding="utf8") as f:
382
422
  f.write(homepage(homepage_template))
383
423
 
384
424
  # build search index from generated docs
385
- search_index = build_search_index(src_subdir, os.path.abspath(html_docs_dir))
425
+ search_index = build_search_index(src_subdir, os.path.abspath(html_docs_dir), homepage_file)
426
+
427
+ # strip timestamps from libdoc HTML files if requested
428
+ if no_timestamp:
429
+ strip_libdoc_timestamps(src_subdir, homepage_file)
386
430
 
387
431
  # inject libtoc script into all libdoc HTML files
388
- inject_libtoc_script(src_subdir)
432
+ inject_libtoc_script(src_subdir, homepage_file)
389
433
 
390
434
  # create TOC
391
435
  toc_file_path = os.path.join(html_docs_dir, toc_file)
@@ -430,18 +474,38 @@ def main():
430
474
  default="",
431
475
  help="Custom HTML template for the homepage file",
432
476
  )
477
+ parser.add_argument(
478
+ "--no_timestamp",
479
+ action="store_true",
480
+ default=False,
481
+ help="Do not include timestamps in the generated TOC and libdoc HTML files",
482
+ )
433
483
  parser.add_argument(
434
484
  "-P",
435
485
  "--pythonpath",
436
486
  default="",
437
487
  help="Additional locations where to search for libraries and resources similarly as when running tests",
438
488
  )
489
+ parser.add_argument(
490
+ "--tree-label",
491
+ dest="folder_labels",
492
+ action="append",
493
+ metavar="KEY=VALUE",
494
+ default=[],
495
+ help="Replace folder, file or lib name KEY with VALUE in the TOC tree. Can be specified multiple times, e.g. --tree-label 'SUT X=My Project'",
496
+ )
439
497
 
440
498
  args = parser.parse_args()
441
499
 
442
500
  if args.pythonpath:
443
501
  sys.path.insert(0, args.pythonpath)
444
502
 
503
+ folder_labels = {}
504
+ for kv in args.folder_labels:
505
+ if "=" in kv:
506
+ key, _, value = kv.partition("=")
507
+ folder_labels[key] = value
508
+
445
509
  if os.path.isdir(args.output_dir):
446
510
  print(f"Output dir already exists, deleting it: {args.output_dir}")
447
511
  shutil.rmtree(args.output_dir)
@@ -513,6 +577,8 @@ def main():
513
577
  args.toc_file,
514
578
  toc_template=args.toc_template,
515
579
  homepage_template=args.homepage_template,
580
+ no_timestamp=args.no_timestamp,
581
+ folder_labels=folder_labels,
516
582
  )
517
583
  else:
518
584
  print("No docs were created!")