snippetMinor
Pandoc filter to allow embedding arbitary HTML in latex documents
Viewed 0 times
latexallowfilterembeddingarbitarypandocdocumentshtml
Problem
I wrote a Pandoc filter that allows me to embed arbitrary HTML snippets in LaTeX documents, which are then printed out as-is when the document is converted to HTML. It is slightly more generic than it needs to be right now, in case I want to embed other types of things in the future.
It can be used like:
In particular, I think the chain of
```
import Data.Char ( isSpace )
import Data.List ( dropWhileEnd )
import Data.Maybe ( fromMaybe )
import Text.Pandoc.JSON ( Block(CodeBlock, RawBlock), Format(Format), toJSONFilter )
main = toJSONFilter convertCodeBlocks
type Reader = String -> Maybe [Block]
convertCodeBlocks :: Block -> [Block]
convertCodeBlocks b = case b of
(CodeBlock _ code) -> fromMaybe [b] $ convertCode code
_ -> [b]
-- Given a string of code, try to convert it into something nicer
convertCode :: String -> Maybe [Block]
convertCode code =
codeBlockType codeHead >>= codeBlockReader >>= runReader codeTail
where (codeHead, codeTail) = splitWhen (== '\n') $ strip code
-- Get the reader name from the magic header
codeBlockType :: String -> Maybe String
codeBlockType line = if percent == "%%% "
then Just $ strip typeName
else Nothing
where (percent, typeName) = splitAt 4 $ strip line
-- All the known readers and their name from the magic header
codeBlockReader :: String -> Maybe Reader
codeBlockReader "html" = Just rawHtml
codeBlockReader _ = Nothing
-- Make a raw HTML block from some string
rawHtml html = Just [RawBlock (Format "html") html]
-- A mostly useless function, only here because I can't make Applicatives work
runReader :: String -> Reader -> Maybe [Block]
runReader code reader = reader code
-- Strip whitespace from the start and end of a string
strip = dropWhileEnd isSpace .
It can be used like:
\begin{verbatim}
%%% html
\end{verbatim}In particular, I think the chain of
>>= in convertCode could be improved some how, possibly using Applicatives. runReader basically does nothing except rearrange its arguments and call a thing.```
import Data.Char ( isSpace )
import Data.List ( dropWhileEnd )
import Data.Maybe ( fromMaybe )
import Text.Pandoc.JSON ( Block(CodeBlock, RawBlock), Format(Format), toJSONFilter )
main = toJSONFilter convertCodeBlocks
type Reader = String -> Maybe [Block]
convertCodeBlocks :: Block -> [Block]
convertCodeBlocks b = case b of
(CodeBlock _ code) -> fromMaybe [b] $ convertCode code
_ -> [b]
-- Given a string of code, try to convert it into something nicer
convertCode :: String -> Maybe [Block]
convertCode code =
codeBlockType codeHead >>= codeBlockReader >>= runReader codeTail
where (codeHead, codeTail) = splitWhen (== '\n') $ strip code
-- Get the reader name from the magic header
codeBlockType :: String -> Maybe String
codeBlockType line = if percent == "%%% "
then Just $ strip typeName
else Nothing
where (percent, typeName) = splitAt 4 $ strip line
-- All the known readers and their name from the magic header
codeBlockReader :: String -> Maybe Reader
codeBlockReader "html" = Just rawHtml
codeBlockReader _ = Nothing
-- Make a raw HTML block from some string
rawHtml html = Just [RawBlock (Format "html") html]
-- A mostly useless function, only here because I can't make Applicatives work
runReader :: String -> Reader -> Maybe [Block]
runReader code reader = reader code
-- Strip whitespace from the start and end of a string
strip = dropWhileEnd isSpace .
Solution
I think it's clearer to just merge all those functions into one since you only really care about one case:
Does this do the same thing? I cant test it without too much effort on my part.
convertCode :: String -> Maybe [Block]
convertCode code =
case strip codeHead of
('%':'%':'%':' ':typeName) -> matchType $ strip typeName
_ -> Nothing
where
(codeHead, codeTail) = splitWhen (== '\n') $ strip code
matchType "html" = Just [RawBlock (Format "html") codeTail]
matchType _ = Nothing
Does this do the same thing? I cant test it without too much effort on my part.
Context
StackExchange Code Review Q#149713, answer score: 4
Revisions (0)
No revisions yet.