diff --git a/TODO.md b/TODO.md
new file mode 100644
index 0000000..c701049
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,6 @@
+
+- fragments in figure-Umgebung
+- svg per default als img
+ - done
+- reveal hat speziell html-attribute => herausfinden und in direct-controls rein
+ - in utils ~> müssen noch überall angepasst werden.
diff --git a/app/Clean.hs b/app/Clean.hs
index fcb5f71..1801343 100644
--- a/app/Clean.hs
+++ b/app/Clean.hs
@@ -2,9 +2,6 @@
{-# LANGUAGE ScopedTypeVariables #-}
import Text.Pandoc.JSON
-import Control.Exception
-import Data.Monoid ((<>))
-import Data.List (partition, isInfixOf)
main :: IO ()
main = toJSONFilter clean
diff --git a/app/Cols.hs b/app/Cols.hs
index d44db55..b9628b9 100644
--- a/app/Cols.hs
+++ b/app/Cols.hs
@@ -1,82 +1,9 @@
#!/usr/bin/env runhaskell
-{-# LANGUAGE ScopedTypeVariables #-}
import Text.Pandoc.JSON
-import Text.Pandoc.Definition
import Text.Pandoc.Generic (topDown)
-import Control.Exception
-import Data.Monoid ((<>))
-import Data.List (partition, elem)
-import System.FilePath
-import Debug.Trace (trace)
-import Text.Read (readMaybe)
-import Data.Maybe (fromMaybe)
+
+import Text.Pandoc.Util.Filter.Cols
main :: IO ()
main = toJSONFilter (topDown cols :: Pandoc -> Pandoc)
-
-
--- | This filter makes multi-column-layouts out of lvl-x-headings
---
--- Syntax is
---
--- ## a b
---
--- yielding a 2-column-layout with aspects a:b i.e. 1:1 for 50/50-layout
--- or 8:2 for 80/20 layout
---
--- currently works for 2 and 3-columns, but extension is straight-forward.
---
--- If you need multiple Block-Elements inside one column, just wrap them
--- with a
This filter makes multi-column-layouts out of lvl-x-headings
Syntax is
## a b
+
yielding a 2-column-layout with aspects a:b i.e. 1:1 for 50/50-layout
+ or 8:2 for 80/20 layout
currently works for 2 and 3-columns, but extension is straight-forward.
If you need multiple Block-Elements inside one column, just wrap them
+ with a <div>:
## 2 5
+
+ <div>
+ multiple things
+ ```
+ foo
+ ```
+
+ </div>
+
+ second column here with only 1 element.
+
\ No newline at end of file
diff --git a/doc/Text-Pandoc-Util-Filter-Media.html b/doc/Text-Pandoc-Util-Filter-Media.html
new file mode 100644
index 0000000..0d20d9d
--- /dev/null
+++ b/doc/Text-Pandoc-Util-Filter-Media.html
@@ -0,0 +1,10 @@
+Text.Pandoc.Util.Filter.Media
HTML-id's maybe ommitted if the file-extension is in whitelist.
If a type is detected by extension a custom id (not matching the extension)
+ will be preserved.
\ No newline at end of file
diff --git a/doc/Text-Pandoc-Util-Filter-Quiz.html b/doc/Text-Pandoc-Util-Filter-Quiz.html
new file mode 100644
index 0000000..6f9d728
--- /dev/null
+++ b/doc/Text-Pandoc-Util-Filter-Quiz.html
@@ -0,0 +1,4 @@
+Text.Pandoc.Util.Filter.Quiz
\ No newline at end of file
diff --git a/doc/Text-Pandoc-Util-Filter-Styling.html b/doc/Text-Pandoc-Util-Filter-Styling.html
new file mode 100644
index 0000000..b1b5bf4
--- /dev/null
+++ b/doc/Text-Pandoc-Util-Filter-Styling.html
@@ -0,0 +1,5 @@
+Text.Pandoc.Util.Filter.Styling
.vspace inside span adds a vertical space with height=xxx
.hspace inside span adds a horizontal space with width=xxx
\ No newline at end of file
diff --git a/doc/Text-Pandoc-Util-Filter.html b/doc/Text-Pandoc-Util-Filter.html
new file mode 100644
index 0000000..a01e33c
--- /dev/null
+++ b/doc/Text-Pandoc-Util-Filter.html
@@ -0,0 +1,19 @@
+Text.Pandoc.Util.Filter
revealjs has some special attributes that has to be
+ passed to the html, but Pandoc only allows
+ key=value-attributes, so we have to abuse
+ .class to rewrite them.
The classes that get rewritten are listed here.
You probably want classToRevealAttr, as that
+ is a wrapper for splitting the class-attribute
revealjs has some special attributes that has to be
+ passed to the html, but Pandoc only allows
+ key=value-attributes, so we have to abuse
+ .class to rewrite them.
This is a wrapper-function which just splits the list
+ into real classes and revealjsSpecialAttrs
adds given String to List of key-value-pairs (like in Attr)
+ in the "style"-Key.
Useful when trying to add CSS-styles directly to (generated) elements
\ No newline at end of file
diff --git a/doc/doc-index.html b/doc/doc-index.html
new file mode 100644
index 0000000..6cee2ff
--- /dev/null
+++ b/doc/doc-index.html
@@ -0,0 +1,4 @@
+pandoc-slide-filter-0.1.0.0 (Index)
\ No newline at end of file
diff --git a/doc/mini_Text-Pandoc-Util-Filter-Cols.html b/doc/mini_Text-Pandoc-Util-Filter-Cols.html
new file mode 100644
index 0000000..82a9518
--- /dev/null
+++ b/doc/mini_Text-Pandoc-Util-Filter-Cols.html
@@ -0,0 +1,4 @@
+Text.Pandoc.Util.Filter.Cols
\ No newline at end of file
diff --git a/doc/mini_Text-Pandoc-Util-Filter-Media.html b/doc/mini_Text-Pandoc-Util-Filter-Media.html
new file mode 100644
index 0000000..a594026
--- /dev/null
+++ b/doc/mini_Text-Pandoc-Util-Filter-Media.html
@@ -0,0 +1,4 @@
+Text.Pandoc.Util.Filter.Media
\ No newline at end of file
diff --git a/doc/mini_Text-Pandoc-Util-Filter-Quiz.html b/doc/mini_Text-Pandoc-Util-Filter-Quiz.html
new file mode 100644
index 0000000..ce16022
--- /dev/null
+++ b/doc/mini_Text-Pandoc-Util-Filter-Quiz.html
@@ -0,0 +1,4 @@
+Text.Pandoc.Util.Filter.Quiz
\ No newline at end of file
diff --git a/doc/mini_Text-Pandoc-Util-Filter-Styling.html b/doc/mini_Text-Pandoc-Util-Filter-Styling.html
new file mode 100644
index 0000000..8871214
--- /dev/null
+++ b/doc/mini_Text-Pandoc-Util-Filter-Styling.html
@@ -0,0 +1,4 @@
+Text.Pandoc.Util.Filter.Styling
\ No newline at end of file
diff --git a/doc/mini_Text-Pandoc-Util-Filter.html b/doc/mini_Text-Pandoc-Util-Filter.html
new file mode 100644
index 0000000..e26eafe
--- /dev/null
+++ b/doc/mini_Text-Pandoc-Util-Filter.html
@@ -0,0 +1,4 @@
+Text.Pandoc.Util.Filter
{-# LANGUAGE ScopedTypeVariables #-}
+
+-- | Conversion of lvl-x-headings to x-column-layouts in HTML
+-- especially for use in revealjs-slides
+moduleText.Pandoc.Util.Filter.Cols
+(cols)
+where
+
+importText.Pandoc.JSON
+importData.Monoid((<>))
+importText.Read(readMaybe)
+importData.Maybe(fromMaybe)
+importText.Pandoc.Util.Filter
+
+-- | This filter makes multi-column-layouts out of lvl-x-headings
+--
+-- Syntax is
+--
+-- @
+-- ## a b
+-- @
+--
+-- yielding a 2-column-layout with aspects a:b i.e. 1:1 for 50/50-layout
+-- or 8:2 for 80/20 layout
+--
+-- currently works for 2 and 3-columns, but extension is straight-forward.
+--
+-- If you need multiple Block-Elements inside one column, just wrap them
+-- with a @\<div\>@:
+--
+-- @
+-- ## 2 5
+--
+-- \<div\>
+-- multiple things
+-- ```
+-- foo
+-- ```
+-- ![image](...)
+-- \</div\>
+--
+-- second column here with only 1 element.
+-- @
+cols::[Block]->[Block]
+cols(Header2attr[Strwa,Space,Strwb]:a:b:rest)=
+outerDiv:rest
+where
+wa'=fromMaybe1(readMaybewa)::Int
+wb'=fromMaybe1(readMaybewb)::Int
+total=wa'+wb'
+pa=(100*wa')`div`total
+pb=(100*wb')`div`total
+outerDiv=Divattr[makeDivpaa
+,makeDivpbb
+,clearDiv
+]
+cols(Header3attr[Strwa,Space,Strwb,Space,Strwc]:a:b:c:rest)=
+outerDiv:rest
+where
+wa'=fromMaybe1(readMaybewa)::Int
+wb'=fromMaybe1(readMaybewb)::Int
+wc'=fromMaybe1(readMaybewc)::Int
+total=wa'+wb'+wc'
+pa=(100*wa')`div`total
+pb=(100*wb')`div`total
+pc=(100*wc')`div`total
+outerDiv=Divattr[makeDivpaa
+,makeDivpbb
+,makeDivpcc
+,clearDiv
+]
+colsx=x
+
+makeDiv::Int->Block->Block
+makeDivwidthcontent=Div("",[],[("style","width:"<>showwidth<>"%;float:left")])[content]
+
+clearDiv::Block
+clearDiv=Div("",[],[("style","clear: both")])[Plain[toHtml" "]]
+
\ No newline at end of file
diff --git a/doc/src/Text.Pandoc.Util.Filter.Media.html b/doc/src/Text.Pandoc.Util.Filter.Media.html
new file mode 100644
index 0000000..8869272
--- /dev/null
+++ b/doc/src/Text.Pandoc.Util.Filter.Media.html
@@ -0,0 +1,159 @@
+
\ No newline at end of file
diff --git a/doc/src/Text.Pandoc.Util.Filter.Quiz.html b/doc/src/Text.Pandoc.Util.Filter.Quiz.html
new file mode 100644
index 0000000..173a581
--- /dev/null
+++ b/doc/src/Text.Pandoc.Util.Filter.Quiz.html
@@ -0,0 +1,40 @@
+
{-# LANGUAGE ScopedTypeVariables #-}
+
+moduleText.Pandoc.Util.Filter.Quiz
+(quiz)
+where
+
+importText.Pandoc.JSON
+importText.Pandoc.Walk
+importData.Monoid((<>))
+importData.Maybe(isNothing,mapMaybe,listToMaybe)
+
+-- Move bottom-Up through the structure, find quiz-answers and remove the
+-- incorrect formattet ones from the Block they came from.
+quiz::Block->[Block]
+quizpb@(Plainb)=fmapmakeQuiz(queryfindQuizpb)<>[Plain(filter((==)[].findQuiz)b)]
+quizpb@(Parab)=fmapmakeQuiz(queryfindQuizpb)<>[Plain(filter((==)[].findQuiz)b)]
+quizx=[x]
+
+-- If we have []{.answer} then we have a quiz-answer
+-- maybe with a tooltip
+findQuiz::Inline->[(Attr,[Inline],Maybe([Inline],Attr))]
+findQuiz(Spanattributes@(_,att,_)answerText)
+|"answer"`elem`att=[(attributes,answerText',tooltip)]
+where
+answerText'=filter(isNothing.findTooltip)answerText--filter everything that is a tooltip
+tooltip=listToMaybe$mapMaybefindTooltipanswerText--get the first span that is labled tooltip
+findQuiz_=[]
+
+-- If we have []{.tooltip} we have a tooltip ;)
+-- we save the text and the attributes in a tuple
+findTooltip::Inline->Maybe([Inline],Attr)
+findTooltip(Spanattr@(_,att,_)tooltipText)
+|"tooltip"`elem`att=Just(tooltipText,attr)
+findTooltip_=Nothing
+
+-- Generate Divs for the quiz
+makeQuiz::(Attr,[Inline],Maybe([Inline],Attr))->Block
+makeQuiz(att,answer,Nothing)=Divatt[Plainanswer]
+makeQuiz(att,answer,Just(tooltip,a))=Divatt[Plainanswer,Diva[Plaintooltip]]
+
\ No newline at end of file
diff --git a/doc/src/Text.Pandoc.Util.Filter.Styling.html b/doc/src/Text.Pandoc.Util.Filter.Styling.html
new file mode 100644
index 0000000..cb97efb
--- /dev/null
+++ b/doc/src/Text.Pandoc.Util.Filter.Styling.html
@@ -0,0 +1,65 @@
+
{-# LANGUAGE ScopedTypeVariables #-}
+
+moduleText.Pandoc.Util.Filter.Styling
+(styling,inlineStyling)
+where
+
+importText.Pandoc.JSON
+importData.Monoid((<>))
+importText.Pandoc.Util.Filter
+importPreludehiding(div,span)
+
+-- | Block-Styling
+--
+-- Special cases captured:
+--
+-- - #col turns a div into a floating-div for multiple columns
+-- - CodeBlock gets attributes @data-trim@ and @data-noescape@
+-- automatically
+-- - .fragment and .frame work properly on divs
+styling::Block->IO[Block]
+styling(Div("col",att,att')inner)=return$[toBlockHtml$"<div style=\"float:left; margin-bottom:10px;\""<>unwordsdirect<>attToString("",css,att')<>">"]
+++inner
+++[toBlockHtml"</div>"]
+where
+(direct,css)=classToRevealAttratt
+styling(CodeBlock(id',att,att')inner)=return
+[CodeBlock(id',addToAtt"data-trim"
+.addToAtt"data-noescape"
+$att
+,att')
+inner]
+stylingdiv@(Div(id',att,att')inner)
+|"fragment"`elem`att=return[Div(id',att,addToStyle"display: block;"att')inner]
+|"frame"`elem`att=return[Div(id',addToAtt"fragment"--insert fragment
+.addToAtt"current-visible"--insert current-visible
+.filter(/="frame")--remove frame
+$att
+,addToStyle"display: block;"att')inner]
+|otherwise=return[div]
+stylingx=return[x]
+
+
+-- | Inline-Styling
+--
+-- Special cases captured:
+--
+-- - .fragment and .frame work properly on spans
+-- - .vspace inside span adds a vertical space with @height=xxx@
+-- - .hspace inside span adds a horizontal space with @width=xxx@
+inlineStyling::Inline->Inline
+inlineStylingspan@(Span(id',att,att')inner)
+|"fragment"`elem`att=Span(id',att,addToStyle"display: inline-block;"att')inner
+|"frame"`elem`att=Span(id',addToAtt"fragment"--insert fragment
+.addToAtt"current-visible"--insert current-visible
+.filter(/="frame")--remove frame
+$att
+,addToStyle"display: inline-block;"att')inner
+|id'=="vspace"=toHtml$"<div style=\"clear:both;\""<>unwordsdirect<>attToString("",css,att')<>"></div>"
+|id'=="hspace"=toHtml$"<span "<>unwordsdirect<>attToString("",css,att')<>"></span>"
+|otherwise=span
+where
+(direct,css)=classToRevealAttratt
+inlineStylingx=x
+
+
\ No newline at end of file
diff --git a/doc/src/Text.Pandoc.Util.Filter.html b/doc/src/Text.Pandoc.Util.Filter.html
new file mode 100644
index 0000000..30aa29d
--- /dev/null
+++ b/doc/src/Text.Pandoc.Util.Filter.html
@@ -0,0 +1,103 @@
+
moduleText.Pandoc.Util.Filter
+(attToString
+,revealjsSpecialAttrs
+,classToRevealAttr
+,toHtml
+,toBlockHtml
+,addToAtt
+,addToStyle
+)
+where
+
+importText.Pandoc.Definition
+importData.Monoid
+importData.List(partition,isInfixOf)
+
+-- | adds a given String to the list if not in there; Does nothing if the
+-- given String is already present.
+addToAtt::Eqa=>a->[a]->[a]
+addToAtttoAdd(a:as)
+|a==toAdd=toAdd:as
+|otherwise=a:addToAtttoAddas
+addToAtttoAdd[]=[toAdd]
+
+-- | adds given String to List of key-value-pairs (like in 'Attr')
+-- in the \"style\"-Key.
+--
+-- Useful when trying to add CSS-styles directly to (generated) elements
+addToStyle::String->[(String,String)]->[(String,String)]
+-- we are looking for style and inject
+addToStyletoAdd(("style",val):as)=("style",iftoAdd`isInfixOf`valthenvalelseval<>" "<>toAdd):as
+-- if we land here the current one is not style -> skip
+addToStyletoAdd(a:as)=a:addToStyletoAddas
+-- if we land here we have no more to skip -> add
+addToStyletoAdd[]=[("style",toAdd)]
+
+-- | converts Attributes to String for usage in HTML
+--
+-- Also converts @width=xxx@ and @height=xxx@ to the
+-- corresponding style-attributes
+attToString::Attr->String
+attToString("",classes,kvpairs)="class=\""<>unwordsclasses<>"\" "<>unwords((\(k,v)->k<>"=\""<>v<>"\"")<$>kvpairs')
+where
+kvpairs'=convertToStyle["width","height","transform"]kvpairs
+attToString(id',classes,kvpairs)="id=\""<>id'<>"\" class=\""<>unwordsclasses<>"\" "<>unwords((\(k,v)->k<>"=\""<>v<>"\"")<$>kvpairs')
+where
+kvpairs'=convertToStyle["width","height","transform"]kvpairs
+
+convertToStyle::[String]->[(String,String)]->[(String,String)]
+convertToStylekeyskvpairs=("style",newstyle):rest
+where
+oldstyle=casefilter(\(k,_)->k=="style")kvpairsof
+[(_,st)]->st
+_->""
+stylesToAdd=filter(\(k,_)->k`elem`keys)kvpairs
+rest=filter(\(k,_)->k`notElem`keys)kvpairs
+newstyle=concat((\(k,v)->k<>":"<>v<>";")<$>stylesToAdd)<>oldstyle
+
+-- | revealjs has some special attributes that has to be
+-- passed to the html, but Pandoc only allows
+-- @key=value@-attributes, so we have to abuse
+-- @.class@ to rewrite them.
+--
+-- The classes that get rewritten are listed here.
+--
+-- You probably want 'classToRevealAttr', as that
+-- is a wrapper for splitting the class-attribute
+revealjsSpecialAttrs::[String]
+revealjsSpecialAttrs=
+["data-markdown"
+,"data-timing"
+,"data-template"
+,"data-autoplay"
+,"data-prevent-swipe"
+,"data-background-interactive"
+,"data-trim"
+,"data-noescape"
+,"data-ignore"
+,"controls"
+]
+
+-- | revealjs has some special attributes that has to be
+-- passed to the html, but Pandoc only allows
+-- @key=value@-attributes, so we have to abuse
+-- @.class@ to rewrite them.
+--
+-- This is a wrapper-function which just splits the list
+-- into real classes and 'revealjsSpecialAttrs'
+classToRevealAttr::[String]->([String],[String])
+classToRevealAttr=partition(`elem`revealjsSpecialAttrs)
+
+-- | small wrapper around @RawInline (Format "html")@
+-- as this is less line-noise in the filters and the
+-- intent is more clear.
+toHtml::String->Inline
+toHtml=RawInline(Format"html")
+
+
+-- | small wrapper around @Raw (Format "html")@
+-- as this is less line-noise in the filters and the
+-- intent is more clear.
+toBlockHtml::String->Block
+toBlockHtml=RawBlock(Format"html")
+
\ No newline at end of file
diff --git a/doc/src/highlight.js b/doc/src/highlight.js
new file mode 100644
index 0000000..1e903bd
--- /dev/null
+++ b/doc/src/highlight.js
@@ -0,0 +1,27 @@
+
+var highlight = function (on) {
+ return function () {
+ var links = document.getElementsByTagName('a');
+ for (var i = 0; i < links.length; i++) {
+ var that = links[i];
+
+ if (this.href != that.href) {
+ continue;
+ }
+
+ if (on) {
+ that.classList.add("hover-highlight");
+ } else {
+ that.classList.remove("hover-highlight");
+ }
+ }
+ }
+};
+
+window.onload = function () {
+ var links = document.getElementsByTagName('a');
+ for (var i = 0; i < links.length; i++) {
+ links[i].onmouseover = highlight(true);
+ links[i].onmouseout = highlight(false);
+ }
+};
diff --git a/doc/src/style.css b/doc/src/style.css
new file mode 100644
index 0000000..e83dc5e
--- /dev/null
+++ b/doc/src/style.css
@@ -0,0 +1,55 @@
+body {
+ background-color: #fdf6e3;
+}
+
+.hs-identifier {
+ color: #073642;
+}
+
+.hs-identifier.hs-var {
+}
+
+.hs-identifier.hs-type {
+ color: #5f5faf;
+}
+
+.hs-keyword {
+ color: #af005f;
+}
+
+.hs-string, .hs-char {
+ color: #cb4b16;
+}
+
+.hs-number {
+ color: #268bd2;
+}
+
+.hs-operator {
+ color: #d33682;
+}
+
+.hs-glyph, .hs-special {
+ color: #dc322f;
+}
+
+.hs-comment {
+ color: #8a8a8a;
+}
+
+.hs-pragma {
+ color: #2aa198;
+}
+
+.hs-cpp {
+ color: #859900;
+}
+
+a:link, a:visited {
+ text-decoration: none;
+ border-bottom: 1px solid #eee8d5;
+}
+
+a:hover, a.hover-highlight {
+ background-color: #eee8d5;
+}
diff --git a/doc/synopsis.png b/doc/synopsis.png
new file mode 100644
index 0000000..85fb86e
Binary files /dev/null and b/doc/synopsis.png differ
diff --git a/pandoc-slide-filter.cabal b/pandoc-slide-filter.cabal
index 0167c56..5fe8bb6 100644
--- a/pandoc-slide-filter.cabal
+++ b/pandoc-slide-filter.cabal
@@ -19,7 +19,7 @@ executable media
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, pandoc-types
- , filepath
+ , pandoc-slide-filter
default-language: Haskell2010
executable cols
@@ -28,7 +28,7 @@ executable cols
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, pandoc-types
- , filepath
+ , pandoc-slide-filter
default-language: Haskell2010
executable styling
@@ -37,6 +37,7 @@ executable styling
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, pandoc-types
+ , pandoc-slide-filter
default-language: Haskell2010
executable quiz
@@ -45,6 +46,7 @@ executable quiz
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, pandoc-types
+ , pandoc-slide-filter
default-language: Haskell2010
executable clean
@@ -53,8 +55,21 @@ executable clean
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, pandoc-types
+ , pandoc-slide-filter
default-language: Haskell2010
+library
+ hs-source-dirs: src
+ build-depends: base
+ , pandoc-types
+ , filepath
+ default-language: Haskell2010
+ exposed-modules: Text.Pandoc.Util.Filter
+ , Text.Pandoc.Util.Filter.Cols
+ , Text.Pandoc.Util.Filter.Media
+ , Text.Pandoc.Util.Filter.Styling
+ , Text.Pandoc.Util.Filter.Quiz
+
source-repository head
type: git
location: https://github.com/Drezil/pandoc-slide-filter
diff --git a/src/Text/Pandoc/Util/Filter.hs b/src/Text/Pandoc/Util/Filter.hs
new file mode 100644
index 0000000..5d8275b
--- /dev/null
+++ b/src/Text/Pandoc/Util/Filter.hs
@@ -0,0 +1,102 @@
+module Text.Pandoc.Util.Filter
+ ( attToString
+ , revealjsSpecialAttrs
+ , classToRevealAttr
+ , toHtml
+ , toBlockHtml
+ , addToAtt
+ , addToStyle
+ )
+ where
+
+import Text.Pandoc.Definition
+import Data.Monoid
+import Data.List (partition, isInfixOf)
+
+-- | adds a given String to the list if not in there; Does nothing if the
+-- given String is already present.
+addToAtt :: Eq a => a -> [a] -> [a]
+addToAtt toAdd (a:as)
+ | a == toAdd = toAdd:as
+ | otherwise = a:addToAtt toAdd as
+addToAtt toAdd [] = [toAdd]
+
+-- | adds given String to List of key-value-pairs (like in 'Attr')
+-- in the \"style\"-Key.
+--
+-- Useful when trying to add CSS-styles directly to (generated) elements
+addToStyle :: String -> [(String, String)] -> [(String, String)]
+-- we are looking for style and inject
+addToStyle toAdd (("style",val):as) = ("style", if toAdd `isInfixOf` val then val else val <> " " <> toAdd):as
+-- if we land here the current one is not style -> skip
+addToStyle toAdd (a:as) = a:addToStyle toAdd as
+-- if we land here we have no more to skip -> add
+addToStyle toAdd [] = [("style", toAdd)]
+
+-- | converts Attributes to String for usage in HTML
+--
+-- Also converts @width=xxx@ and @height=xxx@ to the
+-- corresponding style-attributes
+attToString :: Attr -> String
+attToString ("", classes, kvpairs) = "class=\"" <> unwords classes <> "\" " <> unwords ((\(k,v) -> k <> "=\"" <> v <> "\"") <$> kvpairs')
+ where
+ kvpairs' = convertToStyle ["width","height","transform"] kvpairs
+attToString (id', classes, kvpairs) = "id=\"" <> id' <> "\" class=\"" <> unwords classes <> "\" " <> unwords ((\(k,v) -> k <> "=\"" <> v <> "\"") <$> kvpairs')
+ where
+ kvpairs' = convertToStyle ["width","height","transform"] kvpairs
+
+convertToStyle :: [String] -> [(String,String)] -> [(String,String)]
+convertToStyle keys kvpairs = ("style", newstyle):rest
+ where
+ oldstyle = case filter (\(k,_) -> k == "style") kvpairs of
+ [(_,st)] -> st
+ _ -> ""
+ stylesToAdd = filter (\(k,_) -> k `elem` keys) kvpairs
+ rest = filter (\(k,_) -> k `notElem` keys) kvpairs
+ newstyle = concat ((\(k,v) -> k <> ":" <> v <> ";") <$> stylesToAdd) <> oldstyle
+
+-- | revealjs has some special attributes that has to be
+-- passed to the html, but Pandoc only allows
+-- @key=value@-attributes, so we have to abuse
+-- @.class@ to rewrite them.
+--
+-- The classes that get rewritten are listed here.
+--
+-- You probably want 'classToRevealAttr', as that
+-- is a wrapper for splitting the class-attribute
+revealjsSpecialAttrs :: [String]
+revealjsSpecialAttrs =
+ [ "data-markdown"
+ , "data-timing"
+ , "data-template"
+ , "data-autoplay"
+ , "data-prevent-swipe"
+ , "data-background-interactive"
+ , "data-trim"
+ , "data-noescape"
+ , "data-ignore"
+ , "controls"
+ ]
+
+-- | revealjs has some special attributes that has to be
+-- passed to the html, but Pandoc only allows
+-- @key=value@-attributes, so we have to abuse
+-- @.class@ to rewrite them.
+--
+-- This is a wrapper-function which just splits the list
+-- into real classes and 'revealjsSpecialAttrs'
+classToRevealAttr :: [String] -> ([String],[String])
+classToRevealAttr = partition (`elem` revealjsSpecialAttrs)
+
+-- | small wrapper around @RawInline (Format "html")@
+-- as this is less line-noise in the filters and the
+-- intent is more clear.
+toHtml :: String -> Inline
+toHtml = RawInline (Format "html")
+
+
+-- | small wrapper around @Raw (Format "html")@
+-- as this is less line-noise in the filters and the
+-- intent is more clear.
+toBlockHtml :: String -> Block
+toBlockHtml = RawBlock (Format "html")
diff --git a/src/Text/Pandoc/Util/Filter/Cols.hs b/src/Text/Pandoc/Util/Filter/Cols.hs
new file mode 100644
index 0000000..7f5e2b5
--- /dev/null
+++ b/src/Text/Pandoc/Util/Filter/Cols.hs
@@ -0,0 +1,78 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+-- | Conversion of lvl-x-headings to x-column-layouts in HTML
+-- especially for use in revealjs-slides
+module Text.Pandoc.Util.Filter.Cols
+ (cols)
+ where
+
+import Text.Pandoc.JSON
+import Data.Monoid ((<>))
+import Text.Read (readMaybe)
+import Data.Maybe (fromMaybe)
+import Text.Pandoc.Util.Filter
+
+-- | This filter makes multi-column-layouts out of lvl-x-headings
+--
+-- Syntax is
+--
+-- @
+-- ## a b
+-- @
+--
+-- yielding a 2-column-layout with aspects a:b i.e. 1:1 for 50/50-layout
+-- or 8:2 for 80/20 layout
+--
+-- currently works for 2 and 3-columns, but extension is straight-forward.
+--
+-- If you need multiple Block-Elements inside one column, just wrap them
+-- with a @\