Hi All,
I am working on pyffi
a way to use Python libraries from Racket.
As an example I want to use Pygments as a showcase.
Pygments is a generic syntax highlighter and more than 500 languages are supported.
It would be great to use Pygments from within Scribble.
Currently, I can send a string of program text code
to Pygments and get a
string containing html back. With the noclasses
option the css styles are inline.
(pystring->string
(highlight code (PythonLexer) (HtmlFormatter #:noclasses #t)))
My problem is getting this string of html untouched through the html renderer of Scribble.
Looking around for solutions I found out I asked by the same think back in 2010 [1].
Matthew added cond-element
to produce different output for different renderers as a result.
I also discovered that that Shririam uses sxml->element
(by Danny Yoo) which converts html represented as sxml into a Scribble element. He uses it to embed YouTube videos and Google Forms in Scribble generated documents. The sxml here is written by hand.
There is an html to sxml parser in sxml
, so I tried this:
(define (html->element x)
(map sxml->element
(cdr (ssax:xml->sxml (open-input-string x) '()))))
It almost works. The problem is that the sxml
eats spaces here and there.
The example below shows that the space between def
and partition
is missing.
This "solution" is fragile and even if it could be made to work -- I can't help thinking that I am crossing the river to fetch water [2].
Am I misssing a simple solution?
[1]
https://groups.google.com/g/racket-users/c/Ogp5tWcTCF4/m/kt8adVADCigJ
[2]
Danish idiom.
3 Likes
In case someone knows how to get the ssax:xml->sxml
to preserve the spaces.
The issue is that a space between two span
s is eaten.
<span style=\"color: #008000; font-weight: bold\">def</span> <span style=\"color: #0000FF\">partition</span>
Here is all the html generated by Pygments.
"<div class=\"highlight\" style=\"background: #f8f8f8\"><pre style=\"line-height: 125%;\"><span></span><span style=\"color: #008000; font-weight: bold\">def</span> <span style=\"color: #0000FF\">partition</span>(l, r, nums):\n<span style=\"color: #3D7B7B; font-style: italic\"># Last element will be the pivot and the first element the pointer</span>\npivot, ptr <span style=\"color: #666666\">=</span> nums[r], l\n<span style=\"color: #008000; font-weight: bold\">for</span> i <span style=\"color: #AA22FF; font-weight: bold\">in</span> <span style=\"color: #008000\">range</span>(l, r):\n <span style=\"color: #008000; font-weight: bold\">if</span> nums[i] <span style=\"color: #666666\"><=</span> pivot:\n <span style=\"color: #3D7B7B; font-style: italic\"># Swapping values smaller than the pivot to the front</span>\n nums[i], nums[ptr] <span style=\"color: #666666\">=</span> nums[ptr], nums[i]\n ptr <span style=\"color: #666666\">+=</span> <span style=\"color: #666666\">1</span>\n<span style=\"color: #3D7B7B; font-style: italic\"># Finally swapping the last element with the pointer indexed number</span>\nnums[ptr], nums[r] <span style=\"color: #666666\">=</span> nums[r], nums[ptr]\n<span style=\"color: #008000; font-weight: bold\">return</span> ptr\n</pre></div>\n"
And here is the output from the parser:
'((div
(@ (style "background: #f8f8f8") (class "highlight"))
(pre
(@ (style "line-height: 125%;"))
(span)
(span (@ (style "color: #008000; font-weight: bold")) "def")
(span (@ (style "color: #0000FF")) "partition")
"(l, r, nums):\n"
(span
(@ (style "color: #3D7B7B; font-style: italic"))
"# Last element will be the pivot and the first element the pointer")
"\npivot, ptr "
(span (@ (style "color: #666666")) "=")
" nums[r], l\n"
(span (@ (style "color: #008000; font-weight: bold")) "for")
" i "
(span (@ (style "color: #AA22FF; font-weight: bold")) "in")
(span (@ (style "color: #008000")) "range")
"(l, r):\n "
(span (@ (style "color: #008000; font-weight: bold")) "if")
" nums[i] "
(span (@ (style "color: #666666")) "<=")
" pivot:\n "
(span
(@ (style "color: #3D7B7B; font-style: italic"))
"# Swapping values smaller than the pivot to the front")
"\n nums[i], nums[ptr] "
(span (@ (style "color: #666666")) "=")
" nums[ptr], nums[i]\n ptr "
(span (@ (style "color: #666666")) "+=")
(span (@ (style "color: #666666")) "1")
(span
(@ (style "color: #3D7B7B; font-style: italic"))
"# Finally swapping the last element with the pointer indexed number")
"\nnums[ptr], nums[r] "
(span (@ (style "color: #666666")) "=")
" nums[r], nums[ptr]\n"
(span (@ (style "color: #008000; font-weight: bold")) "return")
" ptr\n")))```
Using html-parsing
instead of sxml
does the trick.
(define (html->element x)
(define top (cdr (html->xexp (open-input-string x))))
(map sxml->element top))
Thanks to sorawee for the tip.
2 Likes
I use the scribble-minted library by William Bowman.
The compile fails here because pygmentize has not been installed.
1 Like
Thanks for the tip. I have looked at the code, but can't figure out how it converts the output from html to Scribble.
joeld
August 18, 2022, 7:51pm
6
Looks like it just gets the raw HTML and shunts it into CDATA
(define (minted-element s contents)
(cond-element
[html
(let* ([style (make-style
(style-name s)
(cons
(make-minted-style-file-addition 'html s)
(style-properties s)))]
[output (render-pygmentize "html" style contents)])
(element
(make-style
#f
(list*
#;(list (string->xexpr ...))
(make-minted-style-file-addition 'html s)
(xexpr-property
(cdata #f #f (if (equal? (style-name style) "ScrbMintInline")
;; NB: Inline is not wrapped from pygments to avoid extra paragraphs.
;; Instead, wrap it code manually.
;; Would prefer to use <pre>, but this seems
This file has been truncated. show original
2 Likes