branch: externals/org
commit 332695e8501dfffc02a2a78811f2969e566772f2
Author: Yue Yi <include...@qq.com>
Commit: Ihor Radchenko <yanta...@posteo.net>

    ox-html: Fix TOC generation for non-toplevel headlines
    
    * lisp/ox-html.el (org-html--toc-text): Correctly set initial level
    based on scope argument and improve docstring.
    * lisp/ox-html.el (org-html-toc): Pass scope argument to helper function.
    * testing/lisp/test-ox-html.el (org-html/test-toc-text): New tests
    for TOC generation.
    
    When exporting a document that starts with a headline of level > 1
    (e.g., no top-level headline), the HTML table of contents was
    rendered incorrectly.  This was caused by `org-html--toc-text'
    calculating the initial nesting level based on the first headline's
    level, which is incorrect for a global TOC that should always start
    from a base level of 0.
    
    This commit adjusts `org-html--toc-text' to correctly handle this by
    checking its optional `scope' argument.
---
 lisp/ox-html.el              | 11 +++++++----
 testing/lisp/test-ox-html.el | 17 +++++++++++++++++
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 818bb127cd..2f014de915 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -2519,7 +2519,7 @@ of contents as a string, or nil if it is empty."
       (let* ((toc-id-counter (plist-get info :org-html--toc-counter))
              (toc (concat (format "<div id=\"text-table-of-contents%s\" 
role=\"doc-toc\">"
                                   (if toc-id-counter (format "-%d" 
toc-id-counter) ""))
-                         (org-html--toc-text toc-entries)
+                         (org-html--toc-text toc-entries scope)
                          "</div>\n")))
         (plist-put info :org-html--toc-counter (1+ (or toc-id-counter 0)))
        (if scope toc
@@ -2537,11 +2537,14 @@ of contents as a string, or nil if it is empty."
                    toc
                    (format "</%s>\n" outer-tag))))))))
 
-(defun org-html--toc-text (toc-entries)
+(defun org-html--toc-text (toc-entries &optional scope)
   "Return innards of a table of contents, as a string.
+
 TOC-ENTRIES is an alist where key is an entry title, as a string,
-and value is its relative level, as an integer."
-  (let* ((prev-level (1- (cdar toc-entries)))
+and value is its relative level, as an integer. Optional SCOPE,
+when non-nil, indicates a TOC for a subtree, which affects the
+initial nesting level."
+  (let* ((prev-level (if scope (1- (cdar toc-entries)) 0))
         (start-level prev-level))
     (concat
      (mapconcat
diff --git a/testing/lisp/test-ox-html.el b/testing/lisp/test-ox-html.el
index fdd40ae982..679d89d22b 100644
--- a/testing/lisp/test-ox-html.el
+++ b/testing/lisp/test-ox-html.el
@@ -1089,5 +1089,22 @@ entirely."
                    "abcdefg\n"))
   (should (= (org-html-normalize-string-or-function 123 nil) 123)))
 
+
+;;; Rendering Table of Contents list
+
+(ert-deftest org-html/test-toc-text ()
+  "Test the generation of HTML TOC lists by `org-html--toc-text'."
+  ;; Test 1: Standard TOC (scope is nil)
+  (let ((toc-entries '(("1" . 1) ("1.1" . 2) ("2" . 1)))
+        (expected 
"\n<ul>\n<li>1\n<ul>\n<li>1.1</li>\n</ul>\n</li>\n<li>2</li>\n</ul>\n"))
+    (should (string= (org-html--toc-text toc-entries nil) expected)))
+  ;; Test 2: TOC starting with a non-toplevel headline.
+  ;; This case, specific to a global TOC (scope is nil), checks
+  ;; if the function correctly wraps the output in outer lists
+  ;; to represent the skipped headline levels.
+  (let ((toc-entries '(("1" . 2) ("1.1" . 3) ("2" . 1)))
+        (expected 
"\n<ul>\n<li>\n<ul>\n<li>1\n<ul>\n<li>1.1</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>2</li>\n</ul>\n"))
+    (should (string= (org-html--toc-text toc-entries nil) expected))))
+
 (provide 'test-ox-html)
 ;;; test-ox-html.el ends here

Reply via email to