Integrate PlantUML diagrams into Hakyll (Updated)

Posted on October 2, 2012
Tags: hacksoft

Hakyll Setup Series

  1. Setup Mathjax
  2. Setup PlantUML
  3. Setup autobuild Hakyll site Git action CI
  4. Very Simple Hakyll Pandoc Filtering Example
  5. Add Railroad Syntax to Hakyll
  6. Table Of Content in Hakyll
  7. Hakyll Access on LAN server

1 Understand the Process

Goal is to

  1. write plantuml code in markdown
  2. pandoc encode our code into some base64 format
  3. process the base64 encoding into a plantuml image HTML element
  4. pandoc codeblock will filter codeblocks and translate them into HTML elements
http://www.plantuml.com/plantuml/svg/~h407374617274756d6c0a416c6963652d3e426f62203a204920616d207573696e67206865780a40656e64756d6c
  1. Converts code into ASCII decimal
  2. Converts ASCII decimal into hex
  3. 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
mhexCode y = tail $ init ( show ( Data.ByteString.Base16.encode $ Data.ByteString.Char8.pack $ Data.Text.unpack 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>") 
planthtml y = Data.Text.pack ("<figure><img src='http://www.plantuml.com/plantuml/svg/~h" <> (mhexCode $ y) <>"'></figure>") 

Above is our helper functions that will be used to generate the hex of our code.

example:
INPUT Markdown codeblock content : @startuml

  1. Data.ByteString.Base16.encode - Convert @startuml to “407374617274756D6C”
  2. intermediate hex result: “407374617274756D6C”
  3. 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 
addToCodeBlock  = walk ftranslate 
  where ftranslate :: Block -> Block
        ftranslate (CodeBlock ("",["plantuml"],[]) txt ) = RawBlock (Format "html") (planthtml txt)
        ftranslate x = 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

mathJaxAddedCompiler :: Compiler (Item String)
mathJaxAddedCompiler = pandocCompilerWithTransform readMathjaxOptions writeMathjaxOptions addToCodeBlock
simpleCompiler :: Compiler (Item String)
simpleCompiler = pandocCompilerWithTransform defaultHakyllReaderOptions defaultHakyllWriterOptions addToCodeBlock