From 8a8b94872b95ffdc55c199f44ff1cc0f5d04dfb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Sz=C3=A1rnyas?= Date: Tue, 8 Dec 2015 15:27:19 +0100 Subject: [PATCH 1/9] Update README.md --- README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 222c668..034f535 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,11 @@ The Code Blocks like the following will include every file in a new line. The reference paths should be either absolute or relative to the folder where the pandoc command will be executed. -```markdown -```include -/absolute/file/path.md -relative/to/the/command/root.md -#do/not/include/this.md -``` -``` + ```include + /absolute/file/path.md + relative/to/the/command/root.md + #do/not/include/this.md + ``` If the file does not exist, it will be skipped completely. No warnings, no residue, nothing. Putting an `#` as the first character in the line will make the From 6f834e0eff7d188973780dabeb3e9b538b959ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=BCrkop?= Date: Sun, 21 Aug 2016 11:36:02 +0200 Subject: [PATCH 2/9] Added hint for include together with citeproc --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 034f535..9d75730 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,12 @@ All this does in the background is pipelining the output of Pandoc and the last pandoc --from markdown --to json input.md | runhaskell IncludeFilter.hs | pandoc --from json --to latex ``` +If using *pandoc-include* together with [*pandoc-citeproc*](https://github.com/jgm/pandoc-citeproc) one has to pay attention to the order of the filters: 1. *pandoc-include*, 2. *pandoc-citeproc*. + +``` +pandoc -o output.md --filter pandoc-include --filter pandoc-citeproc input.md +``` + ## License Copyright ©2015 [Dániel Stein](https://twitter.com/steindani) From 2cd5a7a51b3dafae40d02a64e6522bcc835fbc78 Mon Sep 17 00:00:00 2001 From: David Baynard Date: Thu, 11 Aug 2016 14:25:20 +0100 Subject: [PATCH 3/9] Add stack.yaml --- stack.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 stack.yaml diff --git a/stack.yaml b/stack.yaml new file mode 100644 index 0000000..6100053 --- /dev/null +++ b/stack.yaml @@ -0,0 +1,5 @@ +flags: {} +resolver: lts-6.4 +packages: +- '.' +extra-deps: [] From cbbca4676da9a9d60c379ba7146b243767349b53 Mon Sep 17 00:00:00 2001 From: David Baynard Date: Thu, 11 Aug 2016 14:57:17 +0100 Subject: [PATCH 4/9] Add option to increase header level for includes * Increase the header level of included files by 1, by using `include-indented` rather than just `include`. * Add example to test/input.md --- IncludeFilter.hs | 30 +++++++++++++++++++++++------- README.md | 5 +++++ test/input.md | 4 ++++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/IncludeFilter.hs b/IncludeFilter.hs index 6aa3387..8cdf9c7 100644 --- a/IncludeFilter.hs +++ b/IncludeFilter.hs @@ -42,6 +42,11 @@ pandoc command will be executed. > #do/not/include/this.md > ``` +Alternatively, use the following to increase all the header numbers by one in +the included file. + +> ```include-indented + If the file does not exist, it will be skipped completely. No warnings, no residue, nothing. Putting an # as the first character in the line will make the filter skip that file. @@ -60,6 +65,7 @@ import System.Directory import Text.Pandoc import Text.Pandoc.Error import Text.Pandoc.JSON +import Text.Pandoc.Walk stripPandoc :: Either PandocError Pandoc -> [Block] stripPandoc p = @@ -70,11 +76,11 @@ stripPandoc p = ioReadMarkdown :: String -> IO(Either PandocError Pandoc) ioReadMarkdown content = return $! readMarkdown def content -getContent :: String -> IO [Block] -getContent file = do +getContent :: Int -> String -> IO [Block] +getContent changeInHeaderLevel file = do c <- readFile file p <- ioReadMarkdown c - return $! stripPandoc p + return $! stripPandoc (modifyHeaderLevelWith changeInHeaderLevel <$> p) getProcessableFileList :: String -> IO [String] getProcessableFileList list = do @@ -82,16 +88,26 @@ getProcessableFileList list = do let files = filter (\x -> not $ "#" `isPrefixOf` x) f filterM doesFileExist files -processFiles :: [String] -> IO [Block] -processFiles toProcess = - fmap concat (mapM getContent toProcess) +processFiles :: Int -> [String] -> IO [Block] +processFiles changeInHeaderLevel toProcess = + fmap concat (getContent changeInHeaderLevel `mapM` toProcess) doInclude :: Block -> IO [Block] doInclude (CodeBlock (_, classes, _) list) | "include" `elem` classes = do let toProcess = getProcessableFileList list - processFiles =<< toProcess + processFiles 0 =<< toProcess + | "include-indented" `elem` classes = do + let toProcess = getProcessableFileList list + processFiles 1 =<< toProcess doInclude x = return [x] +modifyHeaderLevelBlock :: Int -> Block -> Block +modifyHeaderLevelBlock n (Header int att inls) = Header (int + n) att inls +modifyHeaderLevelBlock _ x = x + +modifyHeaderLevelWith :: Int -> Pandoc -> Pandoc +modifyHeaderLevelWith n = walk (modifyHeaderLevelBlock n) + main :: IO () main = toJSONFilter doInclude diff --git a/README.md b/README.md index 9d75730..af1fed0 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,11 @@ pandoc command will be executed. #do/not/include/this.md ``` +Alternatively, use the following to increase all the header numbers by one in +the included file. + + ```include-indented + If the file does not exist, it will be skipped completely. No warnings, no residue, nothing. Putting an `#` as the first character in the line will make the filter skip that file. diff --git a/test/input.md b/test/input.md index 000f668..e11c9ee 100644 --- a/test/input.md +++ b/test/input.md @@ -11,4 +11,8 @@ gamma.md beta.md ``` +```include-indented +alpha.md +``` + text From d60629813b94cc1028838162169749c1ff95015d Mon Sep 17 00:00:00 2001 From: David Baynard Date: Thu, 11 Aug 2016 15:32:49 +0100 Subject: [PATCH 5/9] Change header level by arbitrary number. --- IncludeFilter.hs | 21 ++++++++++++++------- README.md | 7 +++++-- pandoc-include.cabal | 2 ++ test/input.md | 4 ++++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/IncludeFilter.hs b/IncludeFilter.hs index 8cdf9c7..b7aad85 100644 --- a/IncludeFilter.hs +++ b/IncludeFilter.hs @@ -42,11 +42,14 @@ pandoc command will be executed. > #do/not/include/this.md > ``` -Alternatively, use the following to increase all the header numbers by one in -the included file. +Alternatively, use one of the following to increase all the header levels in the +included file. The first option is a shortcut for incrementing the level by 1. +The second demonstrates an increase of 2. > ```include-indented +> ```{ .include header-change=2 } + If the file does not exist, it will be skipped completely. No warnings, no residue, nothing. Putting an # as the first character in the line will make the filter skip that file. @@ -60,6 +63,7 @@ Note: the metadata from the included source files are discarded. import Control.Monad import Data.List +import Control.Error (readMay, fromMaybe) import System.Directory import Text.Pandoc @@ -93,13 +97,16 @@ processFiles changeInHeaderLevel toProcess = fmap concat (getContent changeInHeaderLevel `mapM` toProcess) doInclude :: Block -> IO [Block] -doInclude (CodeBlock (_, classes, _) list) +doInclude (CodeBlock (_, classes, options) list) | "include" `elem` classes = do let toProcess = getProcessableFileList list - processFiles 0 =<< toProcess - | "include-indented" `elem` classes = do - let toProcess = getProcessableFileList list - processFiles 1 =<< toProcess + changeInHeaderLevel = fromMaybe 0 $ readMay =<< "header-change" `lookup` options + processFiles changeInHeaderLevel =<< toProcess + | "include-indented" `elem` classes = + doInclude $ CodeBlock ("", newClasses, newOptions) list + where + newClasses = ("include" :) . delete "include-indented" $ classes + newOptions = ("header-change","1") : options doInclude x = return [x] modifyHeaderLevelBlock :: Int -> Block -> Block diff --git a/README.md b/README.md index af1fed0..bc789d6 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,14 @@ pandoc command will be executed. #do/not/include/this.md ``` -Alternatively, use the following to increase all the header numbers by one in -the included file. +Alternatively, use one of the following to increase all the header levels in the +included file. The first option is a shortcut for incrementing the level by 1. +The second demonstrates an increase of 2. ```include-indented + ```{ .include header-change=2 } + If the file does not exist, it will be skipped completely. No warnings, no residue, nothing. Putting an `#` as the first character in the line will make the filter skip that file. diff --git a/pandoc-include.cabal b/pandoc-include.cabal index 3469ae6..169f3b3 100644 --- a/pandoc-include.cabal +++ b/pandoc-include.cabal @@ -23,6 +23,7 @@ Source-repository head Library Build-Depends: base >= 4.6 && < 5, + errors >= 2.0.0, text >= 0.11, pandoc >= 1.13.0.0, pandoc-types >= 1.12.0.0, @@ -35,6 +36,7 @@ Library Executable pandoc-include Build-Depends: base >= 4.6, + errors >= 2.0.0, text >= 0.11, pandoc >= 1.13.0.0, pandoc-types >= 1.12.0.0, diff --git a/test/input.md b/test/input.md index e11c9ee..cb8c99a 100644 --- a/test/input.md +++ b/test/input.md @@ -15,4 +15,8 @@ beta.md alpha.md ``` +```{ .include header-change=2 } +alpha.md +``` + text From 294b009b58ad23f9a5154e5a6db867a4f9fa28bd Mon Sep 17 00:00:00 2001 From: David Baynard Date: Thu, 11 Aug 2016 17:03:27 +0100 Subject: [PATCH 6/9] Include title as header for included files --- IncludeFilter.hs | 53 ++++++++++++++++++++++++++------------------ README.md | 18 +++++++++------ pandoc-include.cabal | 2 ++ test/alpha.md | 4 ++++ 4 files changed, 49 insertions(+), 28 deletions(-) diff --git a/IncludeFilter.hs b/IncludeFilter.hs index b7aad85..fa0c8ad 100644 --- a/IncludeFilter.hs +++ b/IncludeFilter.hs @@ -1,5 +1,7 @@ #!/usr/bin/env runhaskell +{-# LANGUAGE ViewPatterns #-} + {- The MIT License (MIT) @@ -42,14 +44,6 @@ pandoc command will be executed. > #do/not/include/this.md > ``` -Alternatively, use one of the following to increase all the header levels in the -included file. The first option is a shortcut for incrementing the level by 1. -The second demonstrates an increase of 2. - -> ```include-indented - -> ```{ .include header-change=2 } - If the file does not exist, it will be skipped completely. No warnings, no residue, nothing. Putting an # as the first character in the line will make the filter skip that file. @@ -59,10 +53,23 @@ will be inserted and not parsed. Note: the metadata from the included source files are discarded. +Alternatively, use one of the following to increase all the header levels in the +included file. The first option is a shortcut for incrementing the level by 1. +The second demonstrates an increase of 2. + +> ```include-indented + +> ```{ .include header-change=2 } + +If the header level is increased, the title from the included file is inserted at the +beginning of the included file as a header, at the level of the header level change. For +example, if the header is incremented by 1, the title is inserted as a level 1 heading. + -} import Control.Monad import Data.List +import qualified Data.Map as Map import Control.Error (readMay, fromMaybe) import System.Directory @@ -71,11 +78,22 @@ import Text.Pandoc.Error import Text.Pandoc.JSON import Text.Pandoc.Walk -stripPandoc :: Either PandocError Pandoc -> [Block] -stripPandoc p = - case p of - Left _ -> [Null] - Right (Pandoc _ blocks) -> blocks +stripPandoc :: Int -> Either PandocError Pandoc -> [Block] +stripPandoc _ (Left _) = [Null] +stripPandoc changeInHeaderLevel (Right (Pandoc meta blocks)) = maybe id (:) (title meta) $ modBlocks + where + modBlocks = modifyHeaderLevelBlockWith changeInHeaderLevel <$> blocks + title (Meta (Map.lookup "title" -> Just (MetaInlines inls))) = do + guard $ changeInHeaderLevel > 0 + Just $ Header changeInHeaderLevel ("",["section-title"],[]) inls + title _ = Nothing + +modifyHeaderLevelBlockWith :: Int -> Block -> Block +modifyHeaderLevelBlockWith n (Header int att inls) = Header (int + n) att inls +modifyHeaderLevelBlockWith _ x = x + +modifyHeaderLevelWith :: Int -> Pandoc -> Pandoc +modifyHeaderLevelWith n = walk (modifyHeaderLevelBlockWith n) ioReadMarkdown :: String -> IO(Either PandocError Pandoc) ioReadMarkdown content = return $! readMarkdown def content @@ -84,7 +102,7 @@ getContent :: Int -> String -> IO [Block] getContent changeInHeaderLevel file = do c <- readFile file p <- ioReadMarkdown c - return $! stripPandoc (modifyHeaderLevelWith changeInHeaderLevel <$> p) + return $! stripPandoc changeInHeaderLevel p getProcessableFileList :: String -> IO [String] getProcessableFileList list = do @@ -109,12 +127,5 @@ doInclude (CodeBlock (_, classes, options) list) newOptions = ("header-change","1") : options doInclude x = return [x] -modifyHeaderLevelBlock :: Int -> Block -> Block -modifyHeaderLevelBlock n (Header int att inls) = Header (int + n) att inls -modifyHeaderLevelBlock _ x = x - -modifyHeaderLevelWith :: Int -> Pandoc -> Pandoc -modifyHeaderLevelWith n = walk (modifyHeaderLevelBlock n) - main :: IO () main = toJSONFilter doInclude diff --git a/README.md b/README.md index bc789d6..28e2296 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,14 @@ pandoc command will be executed. relative/to/the/command/root.md #do/not/include/this.md ``` +If the file does not exist, it will be skipped completely. No warnings, no +residue, nothing. Putting an `#` as the first character in the line will make the +filter skip that file. + +For now the nested includes only work for two levels, after that the source +will be inserted and not parsed. + +*Note: the metadata from the included source files are discarded.* Alternatively, use one of the following to increase all the header levels in the included file. The first option is a shortcut for incrementing the level by 1. @@ -24,14 +32,10 @@ The second demonstrates an increase of 2. ```{ .include header-change=2 } -If the file does not exist, it will be skipped completely. No warnings, no -residue, nothing. Putting an `#` as the first character in the line will make the -filter skip that file. -For now the nested includes only work for two levels, after that the source -will be inserted and not parsed. - -*Note: the metadata from the included source files are discarded.* +If the header level is increased, the title from the included file is inserted at the +beginning of the included file as a header, at the level of the header level change. For +example, if the header is incremented by 1, the title is inserted as a level 1 heading. ## Installation One could either install it using the Cabal packaging system by running: diff --git a/pandoc-include.cabal b/pandoc-include.cabal index 169f3b3..9cb0fb7 100644 --- a/pandoc-include.cabal +++ b/pandoc-include.cabal @@ -23,6 +23,7 @@ Source-repository head Library Build-Depends: base >= 4.6 && < 5, + containers >= 0.3, errors >= 2.0.0, text >= 0.11, pandoc >= 1.13.0.0, @@ -36,6 +37,7 @@ Library Executable pandoc-include Build-Depends: base >= 4.6, + containers >= 0.3, errors >= 2.0.0, text >= 0.11, pandoc >= 1.13.0.0, diff --git a/test/alpha.md b/test/alpha.md index 5c09417..5ff1fc3 100644 --- a/test/alpha.md +++ b/test/alpha.md @@ -1,3 +1,7 @@ +% The Title is Alpha +% An author +% 11 Aug 2016 + # Alpha! Text from alpha. From e8d93b75bfcfbbd981bdff8891fd3652b2b359a4 Mon Sep 17 00:00:00 2001 From: David Baynard Date: Tue, 16 Aug 2016 14:41:02 +0100 Subject: [PATCH 7/9] Add reference ids to titles inserted as headers --- IncludeFilter.hs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/IncludeFilter.hs b/IncludeFilter.hs index fa0c8ad..9a76105 100644 --- a/IncludeFilter.hs +++ b/IncludeFilter.hs @@ -69,12 +69,14 @@ example, if the header is incremented by 1, the title is inserted as a level 1 h import Control.Monad import Data.List +import qualified Data.Char as C import qualified Data.Map as Map import Control.Error (readMay, fromMaybe) import System.Directory import Text.Pandoc import Text.Pandoc.Error +import Text.Pandoc.Shared import Text.Pandoc.JSON import Text.Pandoc.Walk @@ -85,8 +87,13 @@ stripPandoc changeInHeaderLevel (Right (Pandoc meta blocks)) = maybe id (:) (tit modBlocks = modifyHeaderLevelBlockWith changeInHeaderLevel <$> blocks title (Meta (Map.lookup "title" -> Just (MetaInlines inls))) = do guard $ changeInHeaderLevel > 0 - Just $ Header changeInHeaderLevel ("",["section-title"],[]) inls + Just $ Header changeInHeaderLevel (titleRef inls,["section-title"],[]) inls title _ = Nothing + titleRef = stringify . fmap (lowerCase . dashFromSpace) + dashFromSpace Space = Str "-" + dashFromSpace x = x + lowerCase (Str x) = Str (fmap C.toLower x) + lowerCase x = x modifyHeaderLevelBlockWith :: Int -> Block -> Block modifyHeaderLevelBlockWith n (Header int att inls) = Header (int + n) att inls From 0f2b53a72e388b9116d3d9081bd970b00e28a5c2 Mon Sep 17 00:00:00 2001 From: David Baynard Date: Thu, 11 Aug 2016 14:59:45 +0100 Subject: [PATCH 8/9] Increase version number --- pandoc-include.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandoc-include.cabal b/pandoc-include.cabal index 9cb0fb7..0fa8ad0 100644 --- a/pandoc-include.cabal +++ b/pandoc-include.cabal @@ -1,5 +1,5 @@ Name: pandoc-include -Version: 0.0.1 +Version: 0.0.2 Synopsis: Include other Markdown files Description: A Pandoc filter that replaces include labeled Code Blocks with the contents of the referenced From 80515b9332aa800f752d998cbea7929df517aa42 Mon Sep 17 00:00:00 2001 From: David Baynard Date: Mon, 22 Aug 2016 15:51:11 +0100 Subject: [PATCH 9/9] Add identifier to new heading --- IncludeFilter.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/IncludeFilter.hs b/IncludeFilter.hs index 9a76105..53d0f76 100644 --- a/IncludeFilter.hs +++ b/IncludeFilter.hs @@ -75,8 +75,8 @@ import Control.Error (readMay, fromMaybe) import System.Directory import Text.Pandoc +import Text.Pandoc.Shared (uniqueIdent, stringify) import Text.Pandoc.Error -import Text.Pandoc.Shared import Text.Pandoc.JSON import Text.Pandoc.Walk @@ -89,6 +89,7 @@ stripPandoc changeInHeaderLevel (Right (Pandoc meta blocks)) = maybe id (:) (tit guard $ changeInHeaderLevel > 0 Just $ Header changeInHeaderLevel (titleRef inls,["section-title"],[]) inls title _ = Nothing + -- WARNING titleRef doesn't check that titles are unique; for that try uniqueIdent. titleRef = stringify . fmap (lowerCase . dashFromSpace) dashFromSpace Space = Str "-" dashFromSpace x = x