about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorArun Isaac2023-08-26 14:56:41 +0100
committerArun Isaac2023-08-29 17:08:41 +0100
commit53a8b73f259e291e144c783a57ebf8347a01c541 (patch)
treed9f2611f907988631c4554a9d39de6492a2de105 /src
parentdae5a0dcbbc8920c9642c4f10c8e400db871d7e3 (diff)
downloadskribilo-53a8b73f259e291e144c783a57ebf8347a01c541.tar.gz
skribilo-53a8b73f259e291e144c783a57ebf8347a01c541.tar.lz
skribilo-53a8b73f259e291e144c783a57ebf8347a01c541.zip
html: Render table of contents as nested ordered lists.
* src/guile/skribilo/engine/html.scm (&html-header-style): Add CSS to
set markers for list items in the table of contents.
(toc): Render table of contents as nested ordered lists, not as a
table.
Diffstat (limited to 'src')
-rw-r--r--src/guile/skribilo/engine/html.scm141
1 files changed, 61 insertions, 80 deletions
diff --git a/src/guile/skribilo/engine/html.scm b/src/guile/skribilo/engine/html.scm
index 6b33f51..f63d475 100644
--- a/src/guile/skribilo/engine/html.scm
+++ b/src/guile/skribilo/engine/html.scm
@@ -874,6 +874,7 @@ unspecified or #f values are ignored."
 		 (display "  span.sc { font-variant: small-caps }\n")
 		 (display "  span.sf { font-family: sans-serif }\n")
 		 (display "  span.skribetitle { font-family: sans-serif; font-weight: bolder; font-size: x-large; }\n")
+                 (display "  li.skribilo-toc-item::marker { content: attr(skribilo-toc-item-marker) }\n")
 		 (when (pair? icss)
 		    (for-each (lambda (css)
 				 (let ((p (open-input-file css)))
@@ -1178,89 +1179,69 @@ unspecified or #f values are ignored."
 (markup-writer 'toc
    :options 'all
    :action (lambda (node engine)
-	      (define (col n)
-		 (let loop ((i 0))
-		      (if (< i n)
-			  (begin
-                            (html-open 'td)
-                            (html-close 'td)
-                            (loop (+ i 1))))))
-	      (define (toc-entry fe level)
-                (match fe
-                  ((c ch ...)
-		   (let ((id (markup-ident c))
-		         (f (html-file c engine)))
-		     (unless (string? id)
-		       (skribe-error 'toc
-				     (format #f "invalid identifier '~a'" id)
-				     c))
-                     (html-open 'tr)
-		     ;; blank columns
-		     (col level)
-		     ;; number
-                     (html-open 'td
-                                '((valign . "top")
-                                  (align . "left")))
-                     (display (html-container-number c engine))
-                     (html-close 'td)
-		     ;; title
-                     (html-open 'td
-                                `((colspan . ,(- 4 level))
-                                  (width . "100%")))
-                     (html-open 'a
-                                `((href . ,(string-append
-                                            (if (and (*destination-file*)
-				                     (string=? f (*destination-file*)))
-			                        ""
-			                        (strip-ref-base (or f (*destination-file*) "")))
-                                            (string-canonicalize id)))))
-		     (output (markup-option c :title) engine)
-                     (html-close 'a)
-                     (html-close 'td)
-                     (html-close 'tr)
-		     ;; the children
-		     (for-each (lambda (node)
-                                 (toc-entry node (+ 1 level)))
-                               ch)))))
-
-	      (let* ((c (markup-option node :chapter))
-		     (s (markup-option node :section))
-		     (ss (markup-option node :subsection))
-		     (sss (markup-option node :subsubsection))
-		     (b (markup-body node))
-		     (bb (if (handle? b)
-			     (handle-ast b)
-			     b)))
-		 (if (not (container? bb))
+	     (define (toc-entries entries)
+               ;; Do not produce an empty table.
+               (unless (null? entries)
+                 (html-open 'ol)
+                 (for-each (match-lambda
+                             ((parent children ...)
+                              (let ((id (markup-ident parent))
+		                    (file (html-file parent engine)))
+		                (unless (string? id)
+		                  (skribe-error 'toc
+				                (format #f "invalid identifier '~a'" id)
+				                parent))
+		                ;; title
+                                (html-open 'li
+                                           `((class . "skribilo-toc-item")
+                                             (skribilo-toc-item-marker
+                                              . ,(string-append (html-container-number parent engine)
+                                                                " "))))
+                                (html-open 'a
+                                           `((href . ,(string-append
+                                                       (if (and (*destination-file*)
+				                                (string=? file (*destination-file*)))
+			                                   ""
+			                                   (strip-ref-base (or file (*destination-file*) "")))
+                                                       (string-canonicalize id)))))
+		                (output (markup-option parent :title)
+                                        engine)
+                                (html-close 'a)
+		                ;; the children
+                                (toc-entries children)
+                                (html-close 'li))))
+                           entries)
+                 (html-close 'ol)))
+
+	      (let ((chapter (markup-option node :chapter))
+		    (section (markup-option node :section))
+		    (subsection (markup-option node :subsection))
+		    (subsubsection (markup-option node :subsubsection))
+		    (body (if (handle? (markup-body node))
+                              (handle-ast (markup-body node))
+                              (markup-body node))))
+		 (if (not (container? body))
 		     (error 'toc
 			    "Invalid body (container expected)"
-			    (if (markup? bb)
-				(markup-markup bb)
+			    (if (markup? body)
+				(markup-markup body)
 				"???"))
-		     (let ((lst (find-down (lambda (x)
-					     (and (markup? x)
-						  (markup-option x :toc)
-						  (or (and sss (is-markup? x 'subsubsection))
-						      (and ss (is-markup? x 'subsection))
-						      (and s (is-markup? x 'section))
-						      (and c (is-markup? x 'chapter))
-						      (markup-option node
-                                                                     (symbol->keyword
-								      (markup-markup x))))))
-					   (container-body bb))))
-		       ;; avoid to produce an empty table
-		       (unless (null? lst)
-                         (html-open 'table
-                                    `((class . ,(markup-class node))
-                                      (cellspacing . "1")
-                                      (cellpadding . "1")
-                                      (width . "100%")))
-                         (html-open 'tbody)
-			 (for-each (lambda (node)
-                                     (toc-entry node 0))
-                                   lst)
-                         (html-close 'tbody)
-                         (html-close 'table)))))))
+                     (toc-entries
+                      (find-down (lambda (x)
+				   (and (markup? x)
+					(markup-option x :toc)
+					(or (and subsubsection
+                                                 (is-markup? x 'subsubsection))
+					    (and subsection
+                                                 (is-markup? x 'subsection))
+					    (and section
+                                                 (is-markup? x 'section))
+					    (and chapter
+                                                 (is-markup? x 'chapter))
+					    (markup-option node
+                                                           (symbol->keyword
+							    (markup-markup x))))))
+				 (container-body body)))))))
 
 (define (sections-in-same-file? node1 node2 engine)
   ;; Return #t when NODE1 and NODE2 are to be output in the same file