Integrate PlantUML diagrams into Hakyll (Updated)
Hakyll Setup Series
- Setup Mathjax
- Setup PlantUML
- Setup autobuild Hakyll site Git action CI
- Very Simple Hakyll Pandoc Filtering Example
- Add Railroad Syntax to Hakyll
- Table Of Content in Hakyll
- Hakyll Access on LAN server
1 Understand the Process
Goal is to
- write plantuml code in markdown
- pandoc encode our code into some base64 format
- process the base64 encoding into a plantuml image HTML element
- pandoc codeblock will filter codeblocks and translate them into HTML elements
http://www.plantuml.com/plantuml/svg/~h407374617274756d6c0a416c6963652d3e426f62203a204920616d207573696e67206865780a40656e64756d6c
- Converts code into ASCII decimal
- Converts ASCII decimal into hex
- Hex is part of URL of planttext which will generate our image
2 Cabal and Imports
2.1 Cabal file
pandoc,
pandoc-types,
text,
base16-bytestring,
bytestring,
2.2 Imports to site.hs
import qualified Data.ByteString.Char8 --for convert str to bytestr plantuml, requires cabal 'bytestring'
import Data.ByteString.Base16 (encode, decode) -- for encoding plantuml, requires cabal 'base16-bytestring'
import Text.Pandoc.Walk --for post-processing pandoc, requires cabal 'pandoc-types'
3 site.hs
3.1 Encoding and process to img
mhexCode :: Data.Text.Text -> String
= tail $ init ( show ( Data.ByteString.Base16.encode $ Data.ByteString.Char8.pack $ Data.Text.unpack y ))
mhexCode y
planthtml :: Data.Text.Text -> Data.Text.Text
--planthtml y = T.pack ("<figure><img src='http://www.plantuml.com/plantuml/svg/~h" <> (T.unpack $ hexCode y) <>"'></figure>")
= Data.Text.pack ("<figure><img src='http://www.plantuml.com/plantuml/svg/~h" <> (mhexCode $ y) <>"'></figure>") planthtml y
Above is our helper functions that will be used to generate the hex of our code.
example:
INPUT Markdown codeblock content : @startuml
Data.ByteString.Base16.encode
- Convert@startuml
to “407374617274756D6C”- intermediate hex result: “407374617274756D6C”
planthtml
- Use hex result to create a ‘http://www.plantuml.com…’ img src DOM string.
Notice in the plantuml image link above http://www.plantuml.com/plantuml/svg/~h407374617274756d6c…
the string after “~h” begins with “407374617274756D6C” which is our result.
3.2 Pandoc Codeblock filtering + translation
Now we need to modify site.hs so that Hakyll will transform a PlantUML code block into a html img that links to the Planttext generated image.
We can do this with Hakyll’s Pandocs Filtering.
--Pandoc filtering,
addToCodeBlock :: Pandoc -> Pandoc
= walk ftranslate
addToCodeBlock where ftranslate :: Block -> Block
CodeBlock ("",["plantuml"],[]) txt ) = RawBlock (Format "html") (planthtml txt)
ftranslate (= x ftranslate x
ftranslate (CodeBlock ("",["plantuml"],[]) txt )
pattern matches CodeBlock objects in pandoc and finds “plantuml” annotations denoted by the Attr object ("",["plantuml"],[])
The Content of our CodeBlock is pattern matched as txt
.
After pattern matching it converts it into a raw html block, and applies our “Code to Img DOM” transformation function planthtml
on the content.
INPUT Markdown codeblock :
'''plantuml
@startuml
Alice->Bob : I am using hex
@enduml
'''
Output DOM element :
4 Compiler modification
- If you’ve followed my mathjax hakyll tutorial, simply add the code below:
mathJaxAddedCompiler :: Compiler (Item String)
= pandocCompilerWithTransform readMathjaxOptions writeMathjaxOptions addToCodeBlock mathJaxAddedCompiler
- If you didn’t follow my mathjax hakyll tutorial, then add the code below:
simpleCompiler :: Compiler (Item String)
= pandocCompilerWithTransform defaultHakyllReaderOptions defaultHakyllWriterOptions addToCodeBlock simpleCompiler