mbutterick / pollen-users

please use https://forums.matthewbutterick.com/c/typesetting/ instead
https://forums.matthewbutterick.com/c/typesetting/
52 stars 0 forks source link

Generating links for a table of contents using code from pollen-tfl #67

Closed matiasz closed 4 years ago

matiasz commented 4 years ago

I’m trying to use the code below — from toc.html.pm in the pollen-tfl repository — to create page links in a table of contents.

◊(let () (current-pagetree (load-pagetree "index.ptree")) "")

◊(define (node->link node #:capitalize [caps? #f])
    (define node-string (->string node))
    (define link-name
       (let* ([name (if (dev-mode?) 
                       node-string
                       (select-from-metas 'title node))]
             [name (if caps? (capitalize-first-letter name) name)])
         name))
   ◊link[node-string]{◊link-name})

◊(define (make-toc-subsection pagenode)
  (define node-children (children pagenode))
  ◊div{
    ◊h3{◊(node->link pagenode #:capitalize #t)}
    ◊(if node-children
      (apply ul (map (compose1 li node->link) node-children))
      "")})

◊(apply div #:class "toc" 
  (map make-toc-subsection 
     '( introduction.html
        conclusion.html
        references.html
      )))

The code is successfully creating links for each file in index.ptree, in the sense that the hrefs are correct: clicking the link brings you to the correct page. But the displayed text of each link is in the format “introduction.html” instead of simply “introduction”.

I’d appreciate any guidance on how to set the text of each link to be the title property from each page’s metas.

mbutterick commented 4 years ago

I believe that’s because of the dev-mode? check in the node->link function. Fetching all the titles out of the pages can be slow, so it is meant to save some time while you’re in, you know, dev mode.

matiasz commented 4 years ago

Thank you, Matthew. When I’m in dev mode, it successfully loads node-string as the link-name. But when I’m not in dev mode, it attempts (select-from-metas 'title node) and fails with this error:

txexpr: contract violation
  expected: txexpr-elements?
  given: '((capitalize-first-letter #f))

Do I need to add a function call to make other pages’ metas available in the file with this TOC-building code? I haven’t found a way to do this; the require statement mentioned in “12.3.1.5 Retrieving metas” seems to apply only to .rkt files and not .html.pm files, which is where I’m trying to get metas from.

matiasz commented 4 years ago

I resolved the problem by adding a get-metas call to the node->link function:

◊(define (node->link node #:capitalize [caps? #f])
    (define node-string (->string node))
    (define link-name
       (let* ([name (if (dev-mode?)
                       node-string
                       (select-from-metas 'title (get-metas node)))]
             [name (if caps? (capitalize-first-letter name) name)])
         name))
   ◊link[node-string]{◊link-name})

select-from-metas was trying to use node as the metas and was thus returning #f instead of the node’s actual title. I don’t know that this method is the best, but it works.

mbutterick commented 4 years ago

That’s a little strange — select-from-metas can accept a node name, so (get-metas node) should be the same as node in that position. In researching this issue, I did find a small bug in pollen itself that was causing a difficulty with pollen-tfl. I pushed a fix for that. But I don’t know if it’s related.