rda-python-miscs 3.0.3__py3-none-any.whl → 3.0.4__py3-none-any.whl
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.
- rda_python_miscs/pg_rst.py +128 -25
- rda_python_miscs/rst_templates/appendix.rst.temp +19 -0
- {rda_python_miscs-3.0.3.dist-info → rda_python_miscs-3.0.4.dist-info}/METADATA +1 -1
- {rda_python_miscs-3.0.3.dist-info → rda_python_miscs-3.0.4.dist-info}/RECORD +8 -7
- {rda_python_miscs-3.0.3.dist-info → rda_python_miscs-3.0.4.dist-info}/WHEEL +0 -0
- {rda_python_miscs-3.0.3.dist-info → rda_python_miscs-3.0.4.dist-info}/entry_points.txt +0 -0
- {rda_python_miscs-3.0.3.dist-info → rda_python_miscs-3.0.4.dist-info}/licenses/LICENSE +0 -0
- {rda_python_miscs-3.0.3.dist-info → rda_python_miscs-3.0.4.dist-info}/top_level.txt +0 -0
rda_python_miscs/pg_rst.py
CHANGED
|
@@ -140,10 +140,10 @@ class PgRST(PgFile, PgUtil):
|
|
|
140
140
|
"""
|
|
141
141
|
self.OPTS = opts
|
|
142
142
|
self.ALIAS = alias
|
|
143
|
+
self.DOCS['DOCNAM'] = docname
|
|
143
144
|
|
|
144
145
|
self.parse_docs(docname)
|
|
145
146
|
if not self.sections: self.pglog(docname + ": empty document", self.LGWNEX)
|
|
146
|
-
self.DOCS['DOCNAM'] = docname
|
|
147
147
|
if docname in self.LINKS: self.LINKS.remove(docname)
|
|
148
148
|
self.DOCS['DOCLNK'] = r"({})".format('|'.join(self.LINKS))
|
|
149
149
|
self.DOCS['DOCTIT'] = docname.upper()
|
|
@@ -152,6 +152,7 @@ class PgRST(PgFile, PgUtil):
|
|
|
152
152
|
self.write_index(self.sections[0])
|
|
153
153
|
for section in self.sections:
|
|
154
154
|
self.write_section(section)
|
|
155
|
+
self.write_appendix()
|
|
155
156
|
|
|
156
157
|
#
|
|
157
158
|
# parse the original document and return a array of sections,
|
|
@@ -172,7 +173,9 @@ class PgRST(PgFile, PgUtil):
|
|
|
172
173
|
with open(docfile, 'r') as fh:
|
|
173
174
|
line = fh.readline()
|
|
174
175
|
while line:
|
|
175
|
-
|
|
176
|
+
# Skip full-line authoring comments, but keep '#!' shebang lines so
|
|
177
|
+
# shell scripts shown in example content blocks stay intact.
|
|
178
|
+
if re.match(r'\s*#(?!!)', line):
|
|
176
179
|
line = fh.readline()
|
|
177
180
|
continue # skip comment lines
|
|
178
181
|
ms = re.match(r'^(.*\S)\s+#', line)
|
|
@@ -191,13 +194,21 @@ class PgRST(PgFile, PgUtil):
|
|
|
191
194
|
option = self.record_option(section, option, example, ms.group(1), ms.group(2))
|
|
192
195
|
example = None
|
|
193
196
|
elif option:
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
example['desc'] += line + "\n"
|
|
197
|
+
if option.get('inexm'):
|
|
198
|
+
# inside an 'Examples:' block: collect raw lines verbatim
|
|
199
|
+
# (split into individual examples later in split_examples)
|
|
200
|
+
option['exmraw'] += line + "\n"
|
|
199
201
|
else:
|
|
200
|
-
|
|
202
|
+
ms = re.match(r'^ (?:For(?: | another )example,|Example[ ]*[,\-])\s*(.*)$', line)
|
|
203
|
+
if ms: # found a single labeled example
|
|
204
|
+
example = self.record_example(option, example, ms.group(1))
|
|
205
|
+
elif re.match(r'^ Examples:\s*$', line):
|
|
206
|
+
option['inexm'] = True # start of a multi-example block
|
|
207
|
+
option['exmraw'] = ""
|
|
208
|
+
elif example:
|
|
209
|
+
example['desc'] += line + "\n"
|
|
210
|
+
else:
|
|
211
|
+
option['desc'] += line + "\n"
|
|
201
212
|
else:
|
|
202
213
|
section['desc'] += line + "\n"
|
|
203
214
|
|
|
@@ -261,11 +272,62 @@ class PgRST(PgFile, PgUtil):
|
|
|
261
272
|
"""
|
|
262
273
|
if option:
|
|
263
274
|
if example: self.record_example(option, example)
|
|
275
|
+
self.split_examples(option)
|
|
264
276
|
self.options[option['opt']] = option # record option globally
|
|
265
277
|
section['opts'].append(option['opt']) # record option short name in section
|
|
266
278
|
|
|
267
279
|
if nopt: return self.init_option(section['secid'], nopt, ndesc)
|
|
268
280
|
|
|
281
|
+
def split_examples(self, option):
|
|
282
|
+
"""Split an option's pending ``Examples:`` block into individual examples.
|
|
283
|
+
|
|
284
|
+
The raw text collected after an ``Examples:`` header is segmented into
|
|
285
|
+
blank-line-separated blocks. A block whose last line ends with ``:`` and
|
|
286
|
+
whose first line is descriptive prose (not a command, option flag, or a
|
|
287
|
+
``<<Content ...>>`` header) starts a new example; following blocks
|
|
288
|
+
(command synopsis, script content, trailing notes) belong to that
|
|
289
|
+
example until the next title block.
|
|
290
|
+
|
|
291
|
+
Args:
|
|
292
|
+
option (dict): The option whose ``exmraw`` buffer is parsed; the
|
|
293
|
+
buffer is removed and one example is recorded per
|
|
294
|
+
title block found.
|
|
295
|
+
"""
|
|
296
|
+
buf = option.pop('exmraw', None)
|
|
297
|
+
option.pop('inexm', None)
|
|
298
|
+
if not buf: return
|
|
299
|
+
|
|
300
|
+
blocks = []
|
|
301
|
+
cur = []
|
|
302
|
+
for ln in buf.split('\n'):
|
|
303
|
+
if ln.strip() == '':
|
|
304
|
+
if cur: blocks.append(cur); cur = []
|
|
305
|
+
else:
|
|
306
|
+
cur.append(ln)
|
|
307
|
+
if cur: blocks.append(cur)
|
|
308
|
+
|
|
309
|
+
def is_title(block):
|
|
310
|
+
if not block[-1].rstrip().endswith(':'): return False
|
|
311
|
+
first = block[0].strip()
|
|
312
|
+
if first.startswith('<<'): return False
|
|
313
|
+
if re.match(r'[-*(]', first): return False
|
|
314
|
+
if re.match(r'{}\b'.format(self.DOCS['DOCNAM']), first): return False
|
|
315
|
+
return True
|
|
316
|
+
|
|
317
|
+
exmtext = None
|
|
318
|
+
for block in blocks:
|
|
319
|
+
btext = '\n'.join(block)
|
|
320
|
+
if is_title(block):
|
|
321
|
+
if exmtext is not None:
|
|
322
|
+
self.record_example(option, self.init_example(option['opt'], exmtext))
|
|
323
|
+
exmtext = btext + "\n"
|
|
324
|
+
elif exmtext is not None:
|
|
325
|
+
exmtext += "\n" + btext + "\n"
|
|
326
|
+
else:
|
|
327
|
+
option['desc'] += btext + "\n" # stray text before the first example
|
|
328
|
+
if exmtext is not None:
|
|
329
|
+
self.record_example(option, self.init_example(option['opt'], exmtext))
|
|
330
|
+
|
|
269
331
|
def record_example(self, option, example, ndesc=None):
|
|
270
332
|
"""Append the completed *example* to ``self.examples`` and optionally start a new one.
|
|
271
333
|
|
|
@@ -478,18 +540,21 @@ class PgRST(PgFile, PgUtil):
|
|
|
478
540
|
"""Build and return the RST table-of-contents string of a given section.
|
|
479
541
|
|
|
480
542
|
Produces a nested bullet list of section links (indented by section
|
|
481
|
-
level)
|
|
543
|
+
level). For the index (``csection is None``) the example appendix is a
|
|
544
|
+
standalone page (``appendixA``) added to the toctree; for a section the
|
|
545
|
+
examples in its subtree are listed inline as a local Appendix A.
|
|
482
546
|
|
|
483
547
|
Returns:
|
|
484
548
|
str: RST-formatted TOC content ready for ``__TOC__`` substitution.
|
|
485
549
|
"""
|
|
486
|
-
|
|
550
|
+
|
|
487
551
|
content = ""
|
|
488
552
|
clevel = csection['level'] if csection else 0
|
|
489
553
|
csecid = csection['secid'] if csection else ""
|
|
490
554
|
depth = self.TLEVEL - clevel
|
|
491
555
|
level = clevel+1
|
|
492
556
|
preid = csecid+'.'
|
|
557
|
+
is_index = csection is None
|
|
493
558
|
|
|
494
559
|
# nested bullet list for all sections
|
|
495
560
|
for section in self.sections:
|
|
@@ -497,9 +562,14 @@ class PgRST(PgFile, PgUtil):
|
|
|
497
562
|
if csecid and not secid.startswith(preid): continue
|
|
498
563
|
if section['level'] == level: content += " section{}\n".format(secid)
|
|
499
564
|
|
|
565
|
+
# The full list of examples lives on its own appendix page in the index.
|
|
566
|
+
if is_index and self.examples: content += " appendixA\n"
|
|
567
|
+
|
|
500
568
|
if not content: return ""
|
|
501
569
|
|
|
502
570
|
content = f".. toctree::\n :maxdepth: {depth}\n :caption: Table of Contents\n\n{content}\n"
|
|
571
|
+
if is_index: return content
|
|
572
|
+
|
|
503
573
|
# appendix A: list of examples for the parent section and its subsections
|
|
504
574
|
appendix = ""
|
|
505
575
|
idx = 1 # used as example index
|
|
@@ -507,7 +577,7 @@ class PgRST(PgFile, PgUtil):
|
|
|
507
577
|
opt = exm['opt']
|
|
508
578
|
option = self.options[opt]
|
|
509
579
|
secid = option['secid']
|
|
510
|
-
if
|
|
580
|
+
if secid == csecid or secid.startswith(preid):
|
|
511
581
|
appendix += "- :ref:`A.{}. {} Option -{} (-{}) <{}_e{}>`\n".format(
|
|
512
582
|
idx, option['type'], opt, option['name'], secid, idx)
|
|
513
583
|
idx += 1
|
|
@@ -516,6 +586,28 @@ class PgRST(PgFile, PgUtil):
|
|
|
516
586
|
|
|
517
587
|
return content
|
|
518
588
|
|
|
589
|
+
#
|
|
590
|
+
# write the appendix page listing all examples in the document
|
|
591
|
+
#
|
|
592
|
+
def write_appendix(self):
|
|
593
|
+
"""Write ``appendixA.rst`` listing every example with a link.
|
|
594
|
+
|
|
595
|
+
Each entry links to the example anchor on its section page. Does nothing
|
|
596
|
+
when the document has no examples.
|
|
597
|
+
"""
|
|
598
|
+
if not self.examples: return
|
|
599
|
+
content = ""
|
|
600
|
+
idx = 1
|
|
601
|
+
for exm in self.examples:
|
|
602
|
+
option = self.options[exm['opt']]
|
|
603
|
+
secid = option['secid']
|
|
604
|
+
title = exm['title'].strip().rstrip(':')
|
|
605
|
+
content += "- :ref:`A.{}. {} Option -{} (-{}): {} <{}_e{}>`\n".format(
|
|
606
|
+
idx, option['type'], exm['opt'], option['name'], title, secid, idx)
|
|
607
|
+
idx += 1
|
|
608
|
+
|
|
609
|
+
self.template_to_rst("appendix", {'CONTENT': content}, "A")
|
|
610
|
+
|
|
519
611
|
#
|
|
520
612
|
# create a section rst content
|
|
521
613
|
#
|
|
@@ -672,7 +764,8 @@ class PgRST(PgFile, PgUtil):
|
|
|
672
764
|
|
|
673
765
|
for optary in opts:
|
|
674
766
|
opt = self.get_short_option(optary[1])
|
|
675
|
-
|
|
767
|
+
if opt is None: continue # not an option of this document; leave as-is
|
|
768
|
+
|
|
676
769
|
pre = optary[0]
|
|
677
770
|
after = optary[2]
|
|
678
771
|
secid = self.options[opt]['secid']
|
|
@@ -826,7 +919,7 @@ class PgRST(PgFile, PgUtil):
|
|
|
826
919
|
line0 = lines[0]
|
|
827
920
|
normal = 1
|
|
828
921
|
if dtype == 2:
|
|
829
|
-
ms = re.match(r'
|
|
922
|
+
ms = re.match(r'^\s*<<(Content .*)>>$', line0)
|
|
830
923
|
if ms: # input files for examples
|
|
831
924
|
content += ms.group(1) + ":\n\n.. code-block:: none\n\n"
|
|
832
925
|
normal = 0
|
|
@@ -928,13 +1021,23 @@ class PgRST(PgFile, PgUtil):
|
|
|
928
1021
|
rows.append(tuple(prev_vals))
|
|
929
1022
|
content = self.build_rst_list_table(rows)
|
|
930
1023
|
else:
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
for
|
|
934
|
-
line
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
1024
|
+
raw = [lines[i].strip() for i in range(cnt)]
|
|
1025
|
+
cmdpat = r'(?:[*\d][\d* ]*\s+)?{}(\s|$)'.format(re.escape(self.DOCS['DOCNAM']))
|
|
1026
|
+
if raw and all(re.match(cmdpat, r) for r in raw):
|
|
1027
|
+
# Command line(s) following a label (e.g. a Quick Start entry):
|
|
1028
|
+
# render as a literal block instead of a (degenerate) table.
|
|
1029
|
+
content = ".. code-block:: none\n\n"
|
|
1030
|
+
for r in raw:
|
|
1031
|
+
content += " " + r + "\n"
|
|
1032
|
+
content += "\n"
|
|
1033
|
+
else:
|
|
1034
|
+
# multi-column table split on 2+ spaces
|
|
1035
|
+
rows = []
|
|
1036
|
+
for i in range(cnt):
|
|
1037
|
+
line = lines[i].strip()
|
|
1038
|
+
vals = re.split(r'\s{2,}', self.replace_option_link(line, secid, 1))
|
|
1039
|
+
rows.append(vals)
|
|
1040
|
+
content = self.build_rst_simple_table(rows) + "\n"
|
|
938
1041
|
|
|
939
1042
|
return content
|
|
940
1043
|
|
|
@@ -1046,10 +1149,10 @@ class PgRST(PgFile, PgUtil):
|
|
|
1046
1149
|
p (str): Option name to look up (short, long, or alias).
|
|
1047
1150
|
|
|
1048
1151
|
Returns:
|
|
1049
|
-
str: Canonical two-letter option short name
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1152
|
+
str | None: Canonical two-letter option short name, or ``None`` when
|
|
1153
|
+
*p* does not name an option of this document (e.g. an option of a
|
|
1154
|
+
different program referenced in prose). Callers skip such tokens
|
|
1155
|
+
so unrelated option-like text is left untouched.
|
|
1053
1156
|
"""
|
|
1054
1157
|
plen = len(p)
|
|
1055
1158
|
if plen == 2 and p in self.options: return p
|
|
@@ -1061,7 +1164,7 @@ class PgRST(PgFile, PgUtil):
|
|
|
1061
1164
|
for alias in self.ALIAS[opt]:
|
|
1062
1165
|
if re.match(r'^{}$'.format(alias), p, re.I): return opt
|
|
1063
1166
|
|
|
1064
|
-
|
|
1167
|
+
return None
|
|
1065
1168
|
|
|
1066
1169
|
#
|
|
1067
1170
|
# replace with rst link for a given section title
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
################################################################################
|
|
2
|
+
#
|
|
3
|
+
# Title : appendix_rst.temp
|
|
4
|
+
# Author : Zaihua Ji, zji@ucar.edu
|
|
5
|
+
# Date : 03/17/2026
|
|
6
|
+
# Purpose : template file for help document appendixA.rst (reStructuredText)
|
|
7
|
+
# Github : https://github.com/NCAR/rda-python-mics.git
|
|
8
|
+
#
|
|
9
|
+
################################################################################
|
|
10
|
+
|
|
11
|
+
.. _appendixA:
|
|
12
|
+
|
|
13
|
+
============================
|
|
14
|
+
Appendix A: List of Examples
|
|
15
|
+
============================
|
|
16
|
+
|
|
17
|
+
__CONTENT__
|
|
18
|
+
|
|
19
|
+
| :ref:`Back to Table of Contents <index>`
|
|
@@ -21,7 +21,7 @@ rda_python_miscs/gdexsub.usg,sha256=SChXnDzo6larOdpR9eZ2CMu8ExJYQUdfFHUzxcGoqJ0,
|
|
|
21
21
|
rda_python_miscs/gdexzip.py,sha256=wzMVTqeahXAUHsKAtqYG6wrM4J2EahnncrpliCqFyNQ,3252
|
|
22
22
|
rda_python_miscs/gdexzip.usg,sha256=cG1Uwa8WZ3KQNSaSkr29edUEaaLb_4cHTU3GRoZSQ84,1918
|
|
23
23
|
rda_python_miscs/pg_docs.py,sha256=_AoqrWroUu7FQMVWaTSTZBQMwi1BH1-RjKb1nDHgxOI,25369
|
|
24
|
-
rda_python_miscs/pg_rst.py,sha256=
|
|
24
|
+
rda_python_miscs/pg_rst.py,sha256=Wd4qfeetQYvRio9P2YE2x4kUCDI6ZEcX8CQiI0Xqmyk,53063
|
|
25
25
|
rda_python_miscs/pg_rst.usg,sha256=oYvVEqzHeVmDntN7hfpM8vc6eoYRyQTruQQg2mPfOo4,2484
|
|
26
26
|
rda_python_miscs/pg_wget.py,sha256=YK8EJQtTwGXxHav_SveXOwE_oA9KZ9l12lGSf77JQnE,7571
|
|
27
27
|
rda_python_miscs/pgwget.py,sha256=TFHyquKT0tyz-r-RUAV_wpdwktpVRwyZGrHnZF2B3Vk,8115
|
|
@@ -38,11 +38,12 @@ rda_python_miscs/rdals.usg,sha256=ChF-nn3Qb2pds3wMXIWubB_tjwZslxHfSha0dTDqOiY,29
|
|
|
38
38
|
rda_python_miscs/tcsh_qsub.py,sha256=P4Obzbp5Dvy-N0eRR5F51R9yj3ttWJo6g1NqyVDO6-Y,6670
|
|
39
39
|
rda_python_miscs/tcshqsub.py,sha256=QxBq9MdVIUs9t2d6vHhkxM1nrcLwRNqcq1lJiWhXKUM,10124
|
|
40
40
|
rda_python_miscs/tcshqsub.usg,sha256=JYfhrK7cqme-Sij_JfquONOs3HMu-d5dDGI9K_RdudU,2180
|
|
41
|
+
rda_python_miscs/rst_templates/appendix.rst.temp,sha256=HCujxbj-R4_8FgOrLSlMZcBQHUu8f6kfBMWVRygl7jc,560
|
|
41
42
|
rda_python_miscs/rst_templates/index.rst.temp,sha256=YSa1JM6X9x2SC6UiqJu_9xRrVYGLKwNI43DBJEGDX08,523
|
|
42
43
|
rda_python_miscs/rst_templates/section.rst.temp,sha256=-CUtutvctG2tIdkqrkFxVEzmNN3atRJXBDQaTnMJ6Gw,572
|
|
43
|
-
rda_python_miscs-3.0.
|
|
44
|
-
rda_python_miscs-3.0.
|
|
45
|
-
rda_python_miscs-3.0.
|
|
46
|
-
rda_python_miscs-3.0.
|
|
47
|
-
rda_python_miscs-3.0.
|
|
48
|
-
rda_python_miscs-3.0.
|
|
44
|
+
rda_python_miscs-3.0.4.dist-info/licenses/LICENSE,sha256=1dck4EAQwv8QweDWCXDx-4Or0S8YwiCstaso_H57Pno,1097
|
|
45
|
+
rda_python_miscs-3.0.4.dist-info/METADATA,sha256=nxRaTHxAU0aTXLaNZj9RChQZ70oCj0qHdWtZLVAnOOc,5803
|
|
46
|
+
rda_python_miscs-3.0.4.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
47
|
+
rda_python_miscs-3.0.4.dist-info/entry_points.txt,sha256=pBgb-_g4yZhm6YynwDHtNTAzxVrb8SoDMd7Eiys8gv4,806
|
|
48
|
+
rda_python_miscs-3.0.4.dist-info/top_level.txt,sha256=W5rz7DrWb7hXABUbGgWcwe6D644X338LR8_zdgmtLhg,17
|
|
49
|
+
rda_python_miscs-3.0.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|