pandoc-placetable 0.1.1 → 0.1.2
raw patch · 3 files changed
+85/−54 lines, 3 filesdep +bytestringdep +http-conduit
Dependencies added: bytestring, http-conduit
Files
- README.md +23/−13
- pandoc-placetable.cabal +5/−3
- pandoc-placetable.hs +57/−38
README.md view
@@ -1,8 +1,9 @@-# Pandoc-placetable Filter+# pandoc-placetable filter -A Pandoc filter that replaces code blocks (that have the class `table`) with tables generated from CSV.-The CSV is read from the code block and from an optional external CSV file and concatenated. There's a-flag to enable parsing of inline markdown.+A Pandoc filter that replaces [fenced code blocks](http://pandoc.org/README.html#fenced-code-blocks)+(that have the class `table`) with tables generated from CSV. The CSV is read from the code block+and from an optional external CSV file and concatenated. There's an option to enable parsing of+inline markdown. Some usage examples: @@ -14,6 +15,9 @@ even,"with spaces" ``` + ```{.table file="https://docs.google.com/spreadsheets/my-publish-to-web-sheet-key&output=csv"}+ ```+ ```{.table inlinemarkdown=yes} "when compiled with the inlineMarkdown flag","we _can_ write **Markdown** here" ```@@ -27,16 +31,16 @@ ``` All attributes are optional and are specified as follows: -- file: The path to the CSV file that is appended to the code block's content-- header: If set to `yes`, then the first row of data is interpreted as the table headers.-- aligns: For each column, one letter (L, R or C) that specifies the column's alignment.-- inlinemarkdown: If set to yes, interprets the caption and CSV fields as markdown.+- **file**: The path or URL to the CSV file that is appended to the code block's content+- **header**: If set to `yes`, then the first row of data is interpreted as the table headers.+- **aligns**: For each column, one letter (L, R or C) that specifies the column's alignment.+- **inlinemarkdown**: If set to yes, interprets the caption and CSV fields as markdown. This requires pandoc-placetable to be compiled with the `inlineMarkdown` flag (see below).-- caption: The table caption.-- delimiter: A one-character string used in the CSV to separate fields, defaults to `,`.+- **caption**: The table caption.+- **delimiter**: A one-character string used in the CSV to separate fields, defaults to `,`. For characters not allowed standing alone in Pandoc markdown attributes, use `\t` for a tab and `\s` for a space.-- quotechar: A one-character string that may be used in the CSV to quote fields containing+- **quotechar**: A one-character string that may be used in the CSV to quote fields containing special characters, defaults to `"`. ## Installation@@ -52,7 +56,13 @@ ## Usage -Prepare a markdown file containing a [fenced code block](http://pandoc.org/README.html#fenced-code-blocks)-like the ones above, then:+Prepare a markdown file containing a fenced code block like the ones above, then: pandoc --filter pandoc-placetable input.md++## Acknowledgments++The idea and syntax for this filter was proposed by @jgm on+[pandoc-discuss](https://groups.google.com/forum/#!topic/pandoc-discuss/kBdJU_JktzI)+and first implemented by @baig's [pandoc-csv2table](https://github.com/baig/pandoc-csv2table),+over which I consider this filter an [improvement](https://github.com/mb21/pandoc-placetable/issues/1).
pandoc-placetable.cabal view
@@ -1,5 +1,5 @@ Name: pandoc-placetable-Version: 0.1.1+Version: 0.1.2 Build-Type: Simple Synopsis: Pandoc filter to include CSV files Description: A Pandoc filter that replaces code blocks (that have the class `table`)@@ -28,11 +28,13 @@ Executable pandoc-placetable Main-Is: pandoc-placetable.hs Build-Depends: base >=4.2 && < 5,+ bytestring >= 0.10,+ http-conduit >= 2.1, spreadsheet >= 0.1.3 && < 0.1.4, explicit-exception == 0.1.*, pandoc-types >= 1.12.0.0 If flag(inlineMarkdown)- Build-Depends: pandoc >= 1.14.0.0- cpp-options: -DINLINE_MARKDOWN+ Build-Depends: pandoc >= 1.14.0.0+ cpp-options: -DINLINE_MARKDOWN Buildable: True Default-Language: Haskell2010
pandoc-placetable.hs view
@@ -7,59 +7,78 @@ import Data.Monoid (mempty) import Data.Char (toUpper) import Data.List (isSuffixOf)+import Data.Version (showVersion)+import Network.HTTP.Conduit+import Paths_pandoc_placetable (version)+import System.Environment (getArgs) import Text.Pandoc.JSON import Text.Pandoc.Definition import Text.Pandoc.Builder (Inlines, Blocks, toList, fromList, table, para, str) +import qualified Data.ByteString.Lazy.Char8 as C+ #if defined(INLINE_MARKDOWN) import Text.Pandoc.Readers.Markdown import Text.Pandoc.Options #endif - main :: IO ()-main = toJSONFilter placeTable+main = do+#if defined(INLINE_MARKDOWN)+ let withInlineMarkdown = "with"+#else+ let withInlineMarkdown = "without"+#endif+ args <- getArgs+ let hasArg a = a `elem` args+ if hasArg "-v" || hasArg "--version" || hasArg "-h" || hasArg "--help"+ then putStrLn $ unlines [+ "pandoc-placetable " ++ showVersion version+ , "Compiled " ++ withInlineMarkdown ++ " the inlineMarkdown flag."+ , "https://github.com/mb21/pandoc-placetable"+ ]+ else toJSONFilter placeTable +httpConduitManager :: IO Manager+httpConduitManager = newManager tlsManagerSettings+ placeTable :: Block -> IO [Block] placeTable (CodeBlock (_, cls, kvs) txt) | "table" `elem` cls = do- csv <- case lookup "file" kvs of- Just name -> readFile name- Nothing -> return ""- let header = case lookup "header" kvs of- Just "yes" -> True- _ -> False- let inlinemd = case lookup "inlinemarkdown" kvs of- Just "yes" -> True- _ -> False- let toAlign c = case toUpper c of- 'L' -> AlignLeft- 'R' -> AlignRight- 'C' -> AlignCenter- _ -> AlignDefault- let aligns = case lookup "aligns" kvs of- Just as -> map toAlign as- Nothing -> repeat AlignDefault- let capt = case lookup "caption" kvs of- Just c -> c- Nothing -> ""- let qc = case lookup "quotechar" kvs of- Just q -> head q- Nothing -> '"'- let sep = case lookup "delimiter" kvs of- Just d -> if head d == '\\'- then case head (tail d) of- 't' -> '\t'- 's' -> ' '- _ -> '\\'- else head d- Nothing -> ','+ csv <- find "file" (return "") getCsv+ let header = find "header" False (== "yes")+ let inlinemd = find "inlinemarkdown" False (== "yes")+ let aligns = find "aligns" (repeat AlignDefault) (map toAlign)+ let capt = find "caption" "" id+ let qc = find "quotechar" '"' head+ let sep = find "delimiter" ',' $ \d ->+ if head d == '\\'+ then case head (tail d) of+ 't' -> '\t'+ 's' -> ' '+ _ -> '\\'+ else head d let s' = if null txt- then csv- else txt ++ "\n" ++ csv- let s = if isSuffixOf "\n" s'- then s'- else s' ++ "\n"+ then csv+ else txt ++ "\n" ++ csv+ let s = if isSuffixOf "\n" s'+ then s'+ else s' ++ "\n" return $ toList $ csvToTable header inlinemd aligns capt qc sep s+ where+ find key def extract = case lookup key kvs of+ Just x -> extract x+ Nothing -> def+ getCsv url = case parseUrl url of+ Nothing -> readFile url+ Just req -> do+ mgr <- httpConduitManager+ res <- httpLbs req mgr+ return $ C.unpack $ responseBody res+ toAlign c = case toUpper c of+ 'L' -> AlignLeft+ 'R' -> AlignRight+ 'C' -> AlignCenter+ _ -> AlignDefault placeTable a = return [a]