From 03078fddaeff6c4fa8d43a919b77b4f24d2d250a Mon Sep 17 00:00:00 2001 From: zaihuaji Date: Thu, 26 Mar 2026 10:49:00 -0500 Subject: [PATCH 1/4] Use RST named anchor references in replace_option_link() Same-file links now use `name`_ / `text `_ syntax targeting existing .. _name: anchors instead of URL fragments (#name). Cross-file links retain URL-style anonymous hyperlinks. Co-Authored-By: Claude Sonnet 4.6 --- src/rda_python_miscs/pg_rst.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/rda_python_miscs/pg_rst.py b/src/rda_python_miscs/pg_rst.py index eeabce3..54eeef2 100755 --- a/src/rda_python_miscs/pg_rst.py +++ b/src/rda_python_miscs/pg_rst.py @@ -651,8 +651,9 @@ def replace_option_link(self, line, csecid, ptype=None, dtype=None): """Scan *line* for option references, section-category keywords, URLs, and quoted program names, and replace each with an RST hyperlink. - Link targets are formatted as RST anonymous hyperlinks: - `` `text `_ ``. + Same-file links use RST named anchor references (`` `name`_ `` or + `` `text `_ ``) targeting anchors of the form ``.. _name:``. + Cross-file links use anonymous hyperlinks: `` `text `_ ``. Args: line (str): Source text line to process. @@ -687,14 +688,16 @@ def replace_option_link(self, line, csecid, ptype=None, dtype=None): pre = optary[0] after = optary[2] secid = self.options[opt]['secid'] + anchor = None # RST anchor name for same-file links (.. _NAME:) + url = None # URL for cross-file links if secid == csecid: - link = "#{}".format(opt) + anchor = opt elif self.options[opt]['type'] == "Action": - link = "section{}.rst".format(secid) + url = "section{}.rst".format(secid) elif ptype == 2 and opt == "FN": - link = "#field" + anchor = "field" else: - link = "section{}.rst#{}".format(secid, opt) + url = "section{}.rst#{}".format(secid, opt) ms = re.search(r'-\(({}\|\w+)\)'.format(opt), line) if ms: @@ -703,7 +706,13 @@ def replace_option_link(self, line, csecid, ptype=None, dtype=None): after = ')' replace = pre + opt + after - link = "{}`{} <{}>`_{}".format(pre, opt, link, after) + if anchor is not None: + if opt == anchor: + link = "{}`{}`_{}".format(pre, opt, after) + else: + link = "{}`{} <{}_>`_{}".format(pre, opt, anchor, after) + else: + link = "{}`{} <{}>`_{}".format(pre, opt, url, after) line = line.replace(replace, link) opts = re.findall(r'(^|\W){}( Options*\W|\W|$)'.format(self.SEARCH), line) @@ -720,7 +729,7 @@ def replace_option_link(self, line, csecid, ptype=None, dtype=None): opt += ms.group(1) after = after.replace(ms.group(1), '') if ptype == 2 and re.search(r'Mode Options*', opt) and dtype == 3: - link = "{}`{} <#mode>`_{}".format(pre, opt, after) + link = "{}`{} `_{}".format(pre, opt, after) else: link = "{}`{} `_{}".format(pre, opt, secid, after) line = line.replace(replace, link) From 0de76381ecd133f1d262f6de3bf5242943b76a54 Mon Sep 17 00:00:00 2001 From: zaihuaji Date: Thu, 26 Mar 2026 10:54:34 -0500 Subject: [PATCH 2/4] Extend RST anchor refs to cross-file links in replace_option_link() Cross-file option and category links now use `text `_ RST anchor references instead of URL-style section.rst hrefs. Co-Authored-By: Claude Sonnet 4.6 --- src/rda_python_miscs/pg_rst.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/rda_python_miscs/pg_rst.py b/src/rda_python_miscs/pg_rst.py index 54eeef2..7bd35dc 100755 --- a/src/rda_python_miscs/pg_rst.py +++ b/src/rda_python_miscs/pg_rst.py @@ -651,9 +651,9 @@ def replace_option_link(self, line, csecid, ptype=None, dtype=None): """Scan *line* for option references, section-category keywords, URLs, and quoted program names, and replace each with an RST hyperlink. - Same-file links use RST named anchor references (`` `name`_ `` or + All links use RST named anchor references (`` `name`_ `` or `` `text `_ ``) targeting anchors of the form ``.. _name:``. - Cross-file links use anonymous hyperlinks: `` `text `_ ``. + Cross-file option links target ``.. _section{secid}:`` anchors. Args: line (str): Source text line to process. @@ -688,16 +688,15 @@ def replace_option_link(self, line, csecid, ptype=None, dtype=None): pre = optary[0] after = optary[2] secid = self.options[opt]['secid'] - anchor = None # RST anchor name for same-file links (.. _NAME:) - url = None # URL for cross-file links + anchor = None # RST anchor name for same-file or cross-file links (.. _NAME:) if secid == csecid: anchor = opt elif self.options[opt]['type'] == "Action": - url = "section{}.rst".format(secid) + anchor = "section{}".format(secid) elif ptype == 2 and opt == "FN": anchor = "field" else: - url = "section{}.rst#{}".format(secid, opt) + anchor = "section{}".format(secid) ms = re.search(r'-\(({}\|\w+)\)'.format(opt), line) if ms: @@ -706,13 +705,10 @@ def replace_option_link(self, line, csecid, ptype=None, dtype=None): after = ')' replace = pre + opt + after - if anchor is not None: - if opt == anchor: - link = "{}`{}`_{}".format(pre, opt, after) - else: - link = "{}`{} <{}_>`_{}".format(pre, opt, anchor, after) + if opt == anchor: + link = "{}`{}`_{}".format(pre, opt, after) else: - link = "{}`{} <{}>`_{}".format(pre, opt, url, after) + link = "{}`{} <{}_>`_{}".format(pre, opt, anchor, after) line = line.replace(replace, link) opts = re.findall(r'(^|\W){}( Options*\W|\W|$)'.format(self.SEARCH), line) @@ -731,7 +727,7 @@ def replace_option_link(self, line, csecid, ptype=None, dtype=None): if ptype == 2 and re.search(r'Mode Options*', opt) and dtype == 3: link = "{}`{} `_{}".format(pre, opt, after) else: - link = "{}`{} `_{}".format(pre, opt, secid, after) + link = "{}`{} `_{}".format(pre, opt, secid, after) line = line.replace(replace, link) ms = re.search(r'(https*://\S+)(\.|\,)', line) From ae38ca46758494d43b1115d4ff9d94f8fe3bd4a5 Mon Sep 17 00:00:00 2001 From: zaihuaji Date: Thu, 26 Mar 2026 11:01:33 -0500 Subject: [PATCH 3/4] Merge write_toc() into write_index(); embed TOC in index.rst.temp TOC is now generated directly into index.rst via the __TOC__ placeholder in index.rst.temp. write_toc() and its toc.rst.temp dependency are removed. Co-Authored-By: Claude Sonnet 4.6 --- src/rda_python_miscs/pg_rst.py | 24 ++++--------------- .../rst_templates/index.rst.temp | 11 +++------ 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/src/rda_python_miscs/pg_rst.py b/src/rda_python_miscs/pg_rst.py index 7bd35dc..c683ead 100755 --- a/src/rda_python_miscs/pg_rst.py +++ b/src/rda_python_miscs/pg_rst.py @@ -129,7 +129,7 @@ def process_docs(self, docname, opts, alias): This is the main entry point. It populates ``self.sections``, ``self.options``, and ``self.examples`` by calling ``parse_docs``, then - writes ``index.rst``, ``toc.rst``, and one ``section.rst`` per + writes ``index.rst`` and one ``section.rst`` per section into ``DOCDIR``. Args: @@ -155,8 +155,6 @@ def process_docs(self, docname, opts, alias): else: self.write_index(self.sections[0]) - self.write_toc() - for section in self.sections: self.write_section(section) @@ -404,29 +402,17 @@ def init_example(self, opt, desc): def write_index(self, section): """Write ``index.rst`` from the ``index.rst.temp`` template. - Passes ``TITLE`` (document title) and ``SECID`` (first section id) - as substitution variables. + Passes ``TITLE`` (document title), ``SECID`` (first section id), + and the generated ``TOC`` RST content as substitution variables. Args: section (dict): The first section dict, used to supply ``SECID``. """ - hash = {'TITLE' : self.DOCS['DOCTIT'], 'SECID' : section['secid']} + hash = {'TITLE' : self.DOCS['DOCTIT'], 'SECID' : section['secid'], + 'TOC' : self.create_toc()} self.template_to_rst("index", hash) - # - # write the table of contents: toc.rst - # - def write_toc(self): - """Write ``toc.rst`` from the ``toc.rst.temp`` template. - - Passes ``TITLE`` and the generated ``TOC`` RST content as substitution - variables. - """ - hash = {'TITLE' : self.DOCS['DOCTIT'], 'TOC' : self.create_toc()} - - self.template_to_rst("toc", hash) - # # write a section rst file # diff --git a/src/rda_python_miscs/rst_templates/index.rst.temp b/src/rda_python_miscs/rst_templates/index.rst.temp index be167ed..9f6bcc2 100644 --- a/src/rda_python_miscs/rst_templates/index.rst.temp +++ b/src/rda_python_miscs/rst_templates/index.rst.temp @@ -15,15 +15,10 @@ A GUIDE TO __TITLE__ ============================ -.. contents:: Table of Contents - :depth: 2 - :local: - -See the :doc:`toc` for the full table of contents. - .. toctree:: :maxdepth: 2 :caption: Contents - toc - section__SECID__ \ No newline at end of file + section__SECID__ + +__TOC__ \ No newline at end of file From 916c0bb8c5fcb097459884786aca1ebec9115463 Mon Sep 17 00:00:00 2001 From: zaihuaji Date: Thu, 26 Mar 2026 11:12:38 -0500 Subject: [PATCH 4/4] commit changes --- pyproject.toml | 2 +- src/rda_python_miscs/rst_templates/section.rst.temp | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5da10ba..be749ca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" [project] name = "rda_python_miscs" -version = "2.0.4" +version = "2.0.5" authors = [ { name="Zaihua Ji", email="zji@ucar.edu" }, ] diff --git a/src/rda_python_miscs/rst_templates/section.rst.temp b/src/rda_python_miscs/rst_templates/section.rst.temp index 063facf..c80b7dd 100644 --- a/src/rda_python_miscs/rst_templates/section.rst.temp +++ b/src/rda_python_miscs/rst_templates/section.rst.temp @@ -16,8 +16,5 @@ __SECID__ - __TITLE__ __SECTION__ -.. raw:: html - -
:ref:`Back to Top ` \ No newline at end of file