mbutterick / pollen-users

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

what (internal) template is used for rendering .txt ? #93

Open reuleaux opened 3 years ago

reuleaux commented 3 years ago

Hi,

I am relatively new to pollen, so bear with me, please.

I have a small example project, that I will present (completely) here, to illustrate my issue:

cv2.poly.pm therein is some small sample text in pollen markup, that I want to be rendered in different output formats: It makes use of a paragraph tag (p), and one for emphasis (em), among others, that I am introducing.

cv2.poly.pm

#lang pollen  ◊; -*- mode: pollen -*-

◊section{

◊title{Sample}

◊p{Some  nice text.}

◊p{and some   ◊em{very nice}  text.}

}

◊; section

Now, in my pollen.rkt file (given completely below), I specify those output format:

(module setup racket/base
  (provide (all-defined-out))
  (define poly-targets '(dbk html txt tg)))

dbk - for docbook, html txt tg - aka "tag"

And I render my small sample file to these output formats:

I understand that my sample file is handled internally as a tagged xexpr (txexpr).

And for the commonly used output formats (html, txt) pollen knows how to convert them

txexpr -> html txexpr -> txt

(i.e. I dont have to provide templates: template.html.p, template.txt.p myself)

whereas for the new/exoctic output formats that I am introducing: dbk, tg, I have to provide such templates: template.dbk.p, template.tg.p

I give the template.dbk.p template here just for completeness (in case someone is interested):

template.dbk.p

◊; -*- mode: pollen -*-
<?xml version="1.0" encoding="utf-8" ?>

<article
    xmlns="http://docbook.org/ns/docbook"
    xmlns:xml="http://www.w3.org/XML/1998/namespace"
    xmlns:xl="http://www.w3.org/1999/xlink"
    version="5.0"
    xml:lang="en"
    >

<title/>

◊(require racket/list)
◊(apply string-append (filter string? (flatten doc)))
</article>
◊; <!-- Local Variables: -->
◊; <!-- mode:nxml -->
◊; <!-- End: -->

and my sample document gets rendered to

cv2.dbk

<article
    xmlns="http://docbook.org/ns/docbook"
    xmlns:xml="http://www.w3.org/XML/1998/namespace"
    xmlns:xl="http://www.w3.org/1999/xlink"
    version="5.0"
    xml:lang="en"
    >

<title/>

<section>
<title>Sample</title>

<para>Some  nice text.</para>

<para>and some   <emphasis>very nice</emphasis>  text.</para>

</section>

</article>

Likewise I can view cv2.html in the browser with

http://softland:8080/cv2.html

(and the magic of rendering my cv2 txepr to html happens automatically behind the scenes):

cv2.html

<html><head><meta charset="UTF-8"/></head><body><body>  

<h2>Sample</h2>

<p>Some  nice text.</p>

<p>and some   <em>very nice</em>  text.</p>

</body></body></html>

Now my question is concerning the simpler step of rendering to .tg (aka "tag"): I want this to be rendered in the same way as rendering to .txt is done currently:

I find rendering of cv2.txt very useful, as I get to see the structure of my sample document as a txexpr

http://softland:8080/cv2.txt

(body    

 (h2 Sample) 

 (p Some  nice text.) 

 (p and some    (em very nice)   text.) 

)

Now I would want my template.tg.p to produce this very output: showing the structure of my txexpr document!

But any attempt of mine: ◊(cdr doc), ◊(apply string-append (filter string? (flatten doc))) etc. - several lines in my template.tg.p can be uncommented / commented out - fails in this respect:

template.tg.p - none of those attempts are working for me:

◊; ◊(cdr doc) in main template

◊(require racket/list)
◊; ◊(require txexpr)

◊; ◊(xexpr->html doc)

◊; ◊(xexpr->string doc)

◊; ◊(apply render (flatten doc))
◊; ◊(render doc)

◊; ◊(apply string-append (filter string? (flatten doc)))

◊; # ◊(flatten doc)
◊(cdr doc)

In the case of ◊(cdr doc) as above, (the best) I get to see is this:

http://softland:8080/cv2.tg

h2Sample

pSome  nice text.

pand some   emvery nice  text.

well that is not exactly what I want: note that there is no space between the p tag and its contents, or the em tag and its contents, and would want to see parentheses, too

So, how do I write a template.tg.p, that renders my document in exactly the same manner as my cv2.txt above:

this is what I want to see when viewing http://softland:8080/cv2.tg

(body    

 (h2 Sample) 

 (p Some  nice text.) 

 (p and some    (em very nice)   text.) 

)

Maybe this is not really a pollen question, but one for racket / tgexpr (tagged xexprs did exist in Racket before Pollen, as I understand), but nevertheless I hope to get an answer here.

Note, that in my pollen.rkt file given below, which has several case expressions (for my different output formats), the cases (tg) and (else), the latter one responsible for creating my .txt file, are all treated exactly the same manner:

(I could have removed those (tg) cases here, and have just relied on the behaviour of rendering the else cases, but this is not what I want in the long run: instead I intend to change the rendering of .txt files to just output ascii text - and have succeed to do so already in another small pollen project of mine).

OK, many thanks in advance, Andreas

Now my pollen.rkt -- needs some cleanup, but I hope to get my point across: (tg) is treated like (else), and thus like (txt)

(There is also a bunch of txt- functions in there txt-decode etc. - not to be confused with the .txt output format, however.)


#lang racket/base
(require racket/date 
         ;; non-empty-string?
         racket/string
         txexpr 
         pollen/setup
         pollen/decode
         )
(provide (all-defined-out))

(module setup racket/base
  (provide (all-defined-out))
  (define poly-targets '(dbk html txt tg)))

#|
`txt` is called by root when targeting LaTeX/PDF. It converts all elements inside
a ◊txt tag into a single concatenated string. ◊txt is not intended to be used in
normal markup; its sole purpose is to allow other tag functions to return LaTeX
code as a valid X-expression rather than as a string.
|#
(define (txt-decode xs)
    (if (member (get-tag xs) '(txt txt-noescape))
        (get-elements xs)
        xs))

(define (pair-decode xs)
    (if (member (get-tag xs) '(pair))
        (get-elements xs)
        xs))

(define (rm-decode xs)
    (if (member (get-tag xs) '(rm))
        (get-elements xs)
        xs))

(define (my-string-encode xs)

  (string-replace xs "&" "&amp;")

  )

(define (root . elements)
  (case (current-poly-target)
    [(dbk)
     (define first-pass (decode-elements elements
                                         #:inline-txexpr-proc  txt-decode

                                         ;; #:string-proc (compose1 my-string-encode smart-quotes smart-dashes)
                                         ;; #:string-proc (compose1 my-string-encode smart-dashes)
                                         #:string-proc my-string-encode

                                         #:exclude-tags '(script style figure txt-noescape)))

     (make-txexpr 'body null (decode-elements first-pass #:inline-txexpr-proc txt-decode))]

    [(tg)

     `(body ,@(decode-elements elements 
                               #:inline-txexpr-proc (compose1 rm-decode pair-decode)
                               ;; #:exclude-tags '(short)
                               ))

     ]

    [else

     `(body ,@(decode-elements elements 
                               #:inline-txexpr-proc (compose1 rm-decode pair-decode)
                               ;; #:exclude-tags '(short)
                               ))

     ]

    ))

(define (section . elements)
  (case (current-poly-target)
    [(dbk) `(txt "<section>" ,@elements "</section>")]

    [(tg) `(rm ,@elements)]

    ;; omit-tag??
    [else `(rm ,@elements)]

    ))

(define (title . elements)
  (case (current-poly-target)
    [(dbk) `(txt "<title>" ,@elements "</title>")]

    [(tg) `(h2 ,@elements)]

    ;; omit-tag??
    [else `(h2 ,@elements)]

    ))

(define (em #:role [role ""] . elements)
  ;; (txexpr 'strong empty elements))
  (case (current-poly-target)

    ;; [(dbk) `("<emphasis>" ,@elements "</emphasis>")]
    [(dbk) (if (non-empty-string? role)
               `(txt ,(format "<emphasis role=~s>" role) ,@elements "</emphasis>")
               `(txt "<emphasis>" ,@elements "</emphasis>"))
               ]

    ;; [(txt) (map string-upcase elements)]
    ;; [else (txexpr 'span '((style "italic")) elements)]))

    [(tg) (if (non-empty-string? role) 
              ;; `(em [[role ,role]] ,@elements)
              ;; should check for role =? "strong" here
              `(strong ,@elements)
              `(em ,@elements))
              ]

    ;; ;; ;; ;; [else (txexpr 'em empty elements)]
    [else (if (non-empty-string? role) 
              ;; `(em [[role ,role]] ,@elements)
              ;; should check for role =? "strong" here
              `(strong ,@elements)
              `(em ,@elements))
              ]
          ))

(define (strong . elements)
  ;; (txexpr 'strong empty elements))
  (case (current-poly-target)
    ;; [(dbk) (apply string-append `("<emphasis role=\"strong\">" ,@elements "</emphasis>"))]
    [(dbk) `(txt "<emphasis role=\"strong\">" ,@elements "</emphasis>")]
    ;; [(html) (apply string-append `("<strong>" ,@elements "</strong>"))]
    ;; [(html) (apply string-append `("<span style=\"strong;\">" ,@elements "</span>"))]
    ;; [(txt) (map string-upcase elements)]

    [(tg) (txexpr 'strong empty elements)]

    [else (txexpr 'strong empty elements)]

    ))

(define (p #:role [role ""] . elements)
  (case (current-poly-target)

    ;; [(dbk) `("<para>" ,@elements "</para>")]

    [(dbk) (if (non-empty-string? role)
               `(txt ,(format "<para role=~s>" role) ,@elements "</para>")
               `(txt "<para>" ,@elements "</para>"))
               ]

    ;; [(txt) (map string-upcase elements)]
    [(tg) (txexpr 'p empty elements)]

    [else (txexpr 'p empty elements)]

    ))
mbutterick commented 3 years ago

So, how do I write a template.tg.p, that renders my document in exactly the same manner as my cv2.txt above:

Pollen’s default template is called fallback.txt and you can see it here.

reuleaux commented 3 years ago

Ah, OK, I see - many thanks - and works like a charme.

-A

Matthew Butterick @.***> writes:

So, how do I write a template.tg.p, that renders my document in exactly the same manner as my cv2.txt above:

Pollen’s default template is called fallback.txt and you can see it here.