initial
This commit is contained in:
commit
78aeb6637d
30
LICENSE
Normal file
30
LICENSE
Normal file
@ -0,0 +1,30 @@
|
||||
Copyright Stefan Dresselhaus (c) 2017
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* Neither the name of Author name here nor the names of other
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
91
app/Media.hs
Normal file
91
app/Media.hs
Normal file
@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env runhaskell
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
|
||||
import Text.Pandoc.JSON
|
||||
import Control.Exception
|
||||
import Data.Monoid ((<>))
|
||||
import Data.List (partition)
|
||||
|
||||
main :: IO ()
|
||||
main = toJSONFilter media
|
||||
|
||||
media :: Inline -> IO [Inline]
|
||||
media (Image ("audio",att,att') [] (filename,_)) = return $ [toHtml $ "<audio " <> unwords direct <> " src=\"" <> filename <> "\"" <> attToString ("",css,att') <> ">"]
|
||||
++ [toHtml"</audio>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
media (Image ("audio",att,att') alt (filename,_)) = return $ [toHtml $ "<figure><audio " <> unwords direct <> " src=\"" <> filename <> "\"" <> attToString ("",css,att') <> "></audio>"]
|
||||
++ [toHtml $ "<figcaption>"]
|
||||
++ alt
|
||||
++ [toHtml $ "</figcaption></figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
--no description of video
|
||||
media (Image ("video", att, att') [] (filename,_)) = return $ [toHtml $ "<video " <> unwords direct <> " src=\"" <> filename <> "\"" <> attToString ("",css,att') <> "></video>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
--with description of video
|
||||
media (Image ("video", att, att') alt (filename,_)) = return $ [toHtml $ "<figure>"]
|
||||
++ [toHtml $ "<video " <> unwords direct <> " src=\"" <> filename <> "\"" <> attToString ("",css,att') <> "></video>"]
|
||||
++ [toHtml $ "<figcaption>"]
|
||||
++ alt
|
||||
++ [toHtml $ "</figcaption></figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
--no description of image
|
||||
media (Image ("img", att, att') [] (filename,_)) = return $ [toHtml $ "<figure>"]
|
||||
++ [toHtml $ "<img " <> unwords direct <> " src=\"" <> filename <> "\"" <> attToString ("",css,att') <> "></img>"]
|
||||
++ [toHtml $ "</figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
--with description of image
|
||||
media (Image ("img", att, att') alt (filename,_)) = return $ [toHtml $ "<figure>"]
|
||||
++ [toHtml $ "<img " <> unwords direct <> " src=\"" <> filename <> "\"" <> attToString ("",css,att') <> "></img>"]
|
||||
++ [toHtml $ "<figcaption>"]
|
||||
++ alt
|
||||
++ [toHtml $ "</figcaption></figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
media (Image ("svg", att, att') [] (filename,_)) = handle (\(fileerror :: IOException) -> return [toHtml $ "Could not read file: " <> filename <> "<br />" <> show fileerror]) $
|
||||
do
|
||||
svg <- readFile filename
|
||||
return $ [toHtml $ "<figure " <> unwords direct <> " " <> attToString ("", css, att') <> ">"] -- use attributes on figure, as svg gets dumped in..
|
||||
++ [toHtml $ svg]
|
||||
++ [toHtml $ "</figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
media (Image ("svg", att, att') alt (filename,_)) = handle (\(fileerror :: IOException) -> return $ [toHtml $ "Could not read file: " <> filename <> "<br />" <> show filename]) $
|
||||
do
|
||||
svg <- readFile filename
|
||||
return $ [toHtml $ "<figure " <> unwords direct <> " " <> attToString ("", css, att') <> ">"] -- use attributes on figure, as svg gets dumped in..
|
||||
++ [toHtml $ svg]
|
||||
++ [toHtml $ "<figcaption>"]
|
||||
++ alt
|
||||
++ [toHtml $ "</figcaption></figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
media (Image ("demo", att, att') [] (filename,_)) = return $ [toHtml $ "<iframe " <> unwords direct <> " src=\"" <> filename <> "?plugin\"" <> attToString ("", css, att') <> "></iframe>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
media (Image ("demo", att, att') alt (filename,_)) = return $ [toHtml $ "<figure>"]
|
||||
++ [toHtml $ "<iframe " <> unwords direct <> " src=\"" <> filename <> "?plugin\"" <> attToString ("", css, att') <> "></iframe>"]
|
||||
++ [toHtml $ "<figcaption>"]
|
||||
++ alt
|
||||
++ [toHtml $ "</figcaption></figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
|
||||
media x = return [x]
|
||||
|
||||
|
||||
attToString :: Attr -> String
|
||||
attToString (ident, classes, kvpairs) = ident <> " class=\"" <> unwords classes <> "\" " <> unwords ((\(k,v) -> k <> "=\"" <> v <> "\"") <$> kvpairs)
|
||||
|
||||
classToPlain :: [String] -> ([String],[String])
|
||||
classToPlain = partition (`elem` [ "data-autoplay"
|
||||
, "controls"
|
||||
]
|
||||
)
|
||||
|
||||
toHtml :: String -> Inline
|
||||
toHtml = RawInline (Format "html")
|
91
app/Quiz.hs
Normal file
91
app/Quiz.hs
Normal file
@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env runhaskell
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
|
||||
import Text.Pandoc.JSON
|
||||
import Control.Exception
|
||||
import Data.Monoid ((<>))
|
||||
import Data.List (partition)
|
||||
|
||||
main :: IO ()
|
||||
main = toJSONFilter media
|
||||
|
||||
media :: Inline -> IO [Inline]
|
||||
media (Image ("audio",att,att') [] (filename,_)) = return $ [toHtml $ "<audio " <> unwords direct <> " src=\"" <> filename <> "\"" <> attToString ("",css,att') <> ">"]
|
||||
++ [toHtml"</audio>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
media (Image ("audio",att,att') alt (filename,_)) = return $ [toHtml $ "<figure><audio " <> unwords direct <> " src=\"" <> filename <> "\"" <> attToString ("",css,att') <> "></audio>"]
|
||||
++ [toHtml $ "<figcaption>"]
|
||||
++ alt
|
||||
++ [toHtml $ "</figcaption></figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
--no description of video
|
||||
media (Image ("video", att, att') [] (filename,_)) = return $ [toHtml $ "<video " <> unwords direct <> " src=\"" <> filename <> "\"" <> attToString ("",css,att') <> "></video>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
--with description of video
|
||||
media (Image ("video", att, att') alt (filename,_)) = return $ [toHtml $ "<figure>"]
|
||||
++ [toHtml $ "<video " <> unwords direct <> " src=\"" <> filename <> "\"" <> attToString ("",css,att') <> "></video>"]
|
||||
++ [toHtml $ "<figcaption>"]
|
||||
++ alt
|
||||
++ [toHtml $ "</figcaption></figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
--no description of image
|
||||
media (Image ("img", att, att') [] (filename,_)) = return $ [toHtml $ "<figure>"]
|
||||
++ [toHtml $ "<img " <> unwords direct <> " src=\"" <> filename <> "\"" <> attToString ("",css,att') <> "></img>"]
|
||||
++ [toHtml $ "</figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
--with description of image
|
||||
media (Image ("img", att, att') alt (filename,_)) = return $ [toHtml $ "<figure>"]
|
||||
++ [toHtml $ "<img " <> unwords direct <> " src=\"" <> filename <> "\"" <> attToString ("",css,att') <> "></img>"]
|
||||
++ [toHtml $ "<figcaption>"]
|
||||
++ alt
|
||||
++ [toHtml $ "</figcaption></figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
media (Image ("svg", att, att') [] (filename,_)) = handle (\(fileerror :: IOException) -> return [toHtml $ "Could not read file: " <> filename <> "<br />" <> show fileerror]) $
|
||||
do
|
||||
svg <- readFile filename
|
||||
return $ [toHtml $ "<figure " <> unwords direct <> " " <> attToString ("", css, att') <> ">"] -- use attributes on figure, as svg gets dumped in..
|
||||
++ [toHtml $ svg]
|
||||
++ [toHtml $ "</figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
media (Image ("svg", att, att') alt (filename,_)) = handle (\(fileerror :: IOException) -> return $ [toHtml $ "Could not read file: " <> filename <> "<br />" <> show filename]) $
|
||||
do
|
||||
svg <- readFile filename
|
||||
return $ [toHtml $ "<figure " <> unwords direct <> " " <> attToString ("", css, att') <> ">"] -- use attributes on figure, as svg gets dumped in..
|
||||
++ [toHtml $ svg]
|
||||
++ [toHtml $ "<figcaption>"]
|
||||
++ alt
|
||||
++ [toHtml $ "</figcaption></figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
media (Image ("demo", att, att') [] (filename,_)) = return $ [toHtml $ "<iframe " <> unwords direct <> " src=\"" <> filename <> "?plugin\"" <> attToString ("", css, att') <> "></iframe>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
media (Image ("demo", att, att') alt (filename,_)) = return $ [toHtml $ "<figure>"]
|
||||
++ [toHtml $ "<iframe " <> unwords direct <> " src=\"" <> filename <> "?plugin\"" <> attToString ("", css, att') <> "></iframe>"]
|
||||
++ [toHtml $ "<figcaption>"]
|
||||
++ alt
|
||||
++ [toHtml $ "</figcaption></figure>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
|
||||
media x = return [x]
|
||||
|
||||
|
||||
attToString :: Attr -> String
|
||||
attToString (ident, classes, kvpairs) = ident <> " class=\"" <> unwords classes <> "\" " <> unwords ((\(k,v) -> k <> "=\"" <> v <> "\"") <$> kvpairs)
|
||||
|
||||
classToPlain :: [String] -> ([String],[String])
|
||||
classToPlain = partition (`elem` [ "data-autoplay"
|
||||
, "controls"
|
||||
]
|
||||
)
|
||||
|
||||
toHtml :: String -> Inline
|
||||
toHtml = RawInline (Format "html")
|
77
app/Styling.hs
Normal file
77
app/Styling.hs
Normal file
@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env runhaskell
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
|
||||
import Text.Pandoc.JSON
|
||||
import Text.Pandoc.Walk
|
||||
import Control.Exception
|
||||
import Data.Monoid ((<>))
|
||||
import Data.List (partition, isInfixOf)
|
||||
|
||||
main :: IO ()
|
||||
main = toJSONFilter $ styling . walk inlineStyling
|
||||
|
||||
styling :: Block -> IO [Block]
|
||||
styling (Div ("col",att,att') inner) = return $ [toHtml $ "<div style=\"float:left; margin-bottom:10px;\"" <> unwords direct <> attToString ("",css,att') <> ">"]
|
||||
++ inner
|
||||
++ [toHtml"</div>"]
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
styling (CodeBlock (id,att,att') inner) = return $ [CodeBlock (id, addToAtt "data-trim"
|
||||
. addToAtt "data-noescape"
|
||||
$ att
|
||||
, att') inner]
|
||||
styling div@(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]
|
||||
styling x = return [x]
|
||||
|
||||
|
||||
inlineStyling :: Inline -> Inline
|
||||
inlineStyling span@(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" = toInlineHtml $ "<div style=\"clear:both;\"" <> unwords direct <> attToString ("",css,att') <> "></div>"
|
||||
| id == "hspace" = toInlineHtml $ "<span " <> unwords direct <> attToString ("",css,att') <> "></span>"
|
||||
| otherwise = span
|
||||
where
|
||||
(direct, css) = classToPlain att
|
||||
inlineStyling x = x
|
||||
|
||||
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)]
|
||||
|
||||
addToAtt :: String -> [String] -> [String]
|
||||
addToAtt toAdd (a:as)
|
||||
| a == toAdd = toAdd:as
|
||||
| otherwise = a:addToAtt toAdd as
|
||||
addToAtt toAdd [] = [toAdd]
|
||||
|
||||
attToString :: Attr -> String
|
||||
attToString (ident, [], kvpairs) = ident <> " " <> unwords ((\(k,v) -> k <> "=\"" <> v <> "\"") <$> kvpairs)
|
||||
attToString (ident, classes, kvpairs) = ident <> " class=\"" <> unwords classes <> "\" " <> unwords ((\(k,v) -> k <> "=\"" <> v <> "\"") <$> kvpairs)
|
||||
|
||||
classToPlain :: [String] -> ([String],[String])
|
||||
classToPlain = partition (`elem` [ "data-autoplay"
|
||||
, "controls"
|
||||
]
|
||||
)
|
||||
|
||||
toHtml :: String -> Block
|
||||
toHtml = RawBlock (Format "html")
|
||||
|
||||
toInlineHtml :: String -> Inline
|
||||
toInlineHtml = RawInline (Format "html")
|
42
pandoc-slide-filter.cabal
Normal file
42
pandoc-slide-filter.cabal
Normal file
@ -0,0 +1,42 @@
|
||||
name: pandoc-slide-filter
|
||||
version: 0.1.0.0
|
||||
-- synopsis:
|
||||
-- description:
|
||||
homepage: https://github.com/Drezil/pandoc-slide-filter#readme
|
||||
license: BSD3
|
||||
license-file: LICENSE
|
||||
author: Stefan Dresselhaus
|
||||
maintainer: sdressel@techfak.uni-bielefeld.de
|
||||
copyright: 2017 Stefan Dresselhaus
|
||||
category: CLI
|
||||
build-type: Simple
|
||||
extra-source-files: README.md
|
||||
cabal-version: >=1.10
|
||||
|
||||
executable media
|
||||
hs-source-dirs: app
|
||||
main-is: Media.hs
|
||||
ghc-options: -threaded -rtsopts -with-rtsopts=-N
|
||||
build-depends: base
|
||||
, pandoc
|
||||
default-language: Haskell2010
|
||||
|
||||
executable styling
|
||||
hs-source-dirs: app
|
||||
main-is: Styling.hs
|
||||
ghc-options: -threaded -rtsopts -with-rtsopts=-N
|
||||
build-depends: base
|
||||
, pandoc
|
||||
default-language: Haskell2010
|
||||
|
||||
executable quiz
|
||||
hs-source-dirs: app
|
||||
main-is: Quiz.hs
|
||||
ghc-options: -threaded -rtsopts -with-rtsopts=-N
|
||||
build-depends: base
|
||||
, pandoc
|
||||
default-language: Haskell2010
|
||||
|
||||
source-repository head
|
||||
type: git
|
||||
location: https://github.com/Drezil/pandoc-slide-filter
|
66
stack.yaml
Normal file
66
stack.yaml
Normal file
@ -0,0 +1,66 @@
|
||||
# This file was automatically generated by 'stack init'
|
||||
#
|
||||
# Some commonly used options have been documented as comments in this file.
|
||||
# For advanced use and comprehensive documentation of the format, please see:
|
||||
# http://docs.haskellstack.org/en/stable/yaml_configuration/
|
||||
|
||||
# Resolver to choose a 'specific' stackage snapshot or a compiler version.
|
||||
# A snapshot resolver dictates the compiler version and the set of packages
|
||||
# to be used for project dependencies. For example:
|
||||
#
|
||||
# resolver: lts-3.5
|
||||
# resolver: nightly-2015-09-21
|
||||
# resolver: ghc-7.10.2
|
||||
# resolver: ghcjs-0.1.0_ghc-7.10.2
|
||||
# resolver:
|
||||
# name: custom-snapshot
|
||||
# location: "./custom-snapshot.yaml"
|
||||
resolver: lts-8.23
|
||||
|
||||
# User packages to be built.
|
||||
# Various formats can be used as shown in the example below.
|
||||
#
|
||||
# packages:
|
||||
# - some-directory
|
||||
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
|
||||
# - location:
|
||||
# git: https://github.com/commercialhaskell/stack.git
|
||||
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
|
||||
# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
|
||||
# extra-dep: true
|
||||
# subdirs:
|
||||
# - auto-update
|
||||
# - wai
|
||||
#
|
||||
# A package marked 'extra-dep: true' will only be built if demanded by a
|
||||
# non-dependency (i.e. a user package), and its test suites and benchmarks
|
||||
# will not be run. This is useful for tweaking upstream packages.
|
||||
packages:
|
||||
- '.'
|
||||
# Dependency packages to be pulled from upstream that are not in the resolver
|
||||
# (e.g., acme-missiles-0.3)
|
||||
extra-deps: []
|
||||
|
||||
# Override default flag values for local packages and extra-deps
|
||||
flags: {}
|
||||
|
||||
# Extra package databases containing global packages
|
||||
extra-package-dbs: []
|
||||
|
||||
# Control whether we use the GHC we find on the path
|
||||
# system-ghc: true
|
||||
#
|
||||
# Require a specific version of stack, using version ranges
|
||||
# require-stack-version: -any # Default
|
||||
# require-stack-version: ">=1.4"
|
||||
#
|
||||
# Override the architecture used by stack, especially useful on Windows
|
||||
# arch: i386
|
||||
# arch: x86_64
|
||||
#
|
||||
# Extra directories used by stack for building
|
||||
# extra-include-dirs: [/path/to/dir]
|
||||
# extra-lib-dirs: [/path/to/dir]
|
||||
#
|
||||
# Allow a newer minor version of GHC than the snapshot specifies
|
||||
# compiler-check: newer-minor
|
Loading…
Reference in New Issue
Block a user