From fb94c0f6a1b98d4f7ff34107d3b63c2c1d0afe1f Mon Sep 17 00:00:00 2001 From: Albert Krewinkel Date: Mon, 30 Jul 2018 19:55:25 +0200 Subject: Lua Utils module: add function blocks_to_inlines (#4799) Exposes a function converting which flattenes a list of blocks into a list of inlines. An example use case would be the conversion of Note elements into other inlines. --- doc/lua-filters.md | 31 +++++++++++++++++++++++++++++++ src/Text/Pandoc/Lua/Module/Utils.hs | 10 ++++++++++ src/Text/Pandoc/Shared.hs | 13 +++++++++++-- test/Tests/Lua.hs | 3 ++- test/lua/test-pandoc-utils.lua | 15 +++++++++++++++ 5 files changed, 69 insertions(+), 3 deletions(-) diff --git a/doc/lua-filters.md b/doc/lua-filters.md index 881c981f5..19428cde6 100644 --- a/doc/lua-filters.md +++ b/doc/lua-filters.md @@ -1438,6 +1438,37 @@ Lua functions for pandoc scripts. This module exposes internal pandoc functions and utility functions. +[`blocks_to_inlines (blocks[, sep])`]{#utils-blocks_to_inlines} + +: Squash a list of blocks into a list of inlines. + + Parameters: + + `blocks`: + : List of blocks to be flattened. + + `sep`: + : List of inlines inserted as separator between two + consecutive blocks; defaults to `{ pandoc.Space(), + pandoc.Str'¶', pandoc.Space()}`. + + Returns: + + - ({[Inline][#Inline]}) List of inlines + + Usage: + + local blocks = { + pandoc.Para{ pandoc.Str 'Paragraph1' }, + pandoc.Para{ pandoc.Emph 'Paragraph2' } + } + local inlines = pandoc.utils.blocks_to_inlines(blocks) + -- inlines = { + -- pandoc.Str 'Paragraph1', + -- pandoc.Space(), pandoc.Str'¶', pandoc.Space(), + -- pandoc.Emph{ pandoc.Str 'Paragraph2' } + -- } + [`hierarchicalize (blocks)`]{#utils-hierarchicalize} : Convert list of blocks into an hierarchical list. An diff --git a/src/Text/Pandoc/Lua/Module/Utils.hs b/src/Text/Pandoc/Lua/Module/Utils.hs index 7fa4616be..7016c7ebd 100644 --- a/src/Text/Pandoc/Lua/Module/Utils.hs +++ b/src/Text/Pandoc/Lua/Module/Utils.hs @@ -42,6 +42,7 @@ import Text.Pandoc.Lua.Util (addFunction, popValue) import qualified Data.Digest.Pure.SHA as SHA import qualified Data.ByteString.Lazy as BSL import qualified Foreign.Lua as Lua +import qualified Text.Pandoc.Builder as B import qualified Text.Pandoc.Filter.JSON as JSONFilter import qualified Text.Pandoc.Shared as Shared @@ -49,6 +50,7 @@ import qualified Text.Pandoc.Shared as Shared pushModule :: Maybe FilePath -> Lua NumResults pushModule mbDatadir = do Lua.newtable + addFunction "blocks_to_inlines" blocksToInlines addFunction "hierarchicalize" hierarchicalize addFunction "normalize_date" normalizeDate addFunction "run_json_filter" (runJSONFilter mbDatadir) @@ -57,6 +59,14 @@ pushModule mbDatadir = do addFunction "to_roman_numeral" toRomanNumeral return 1 +-- | Squashes a list of blocks into inlines. +blocksToInlines :: [Block] -> Lua.Optional [Inline] -> Lua [Inline] +blocksToInlines blks optSep = do + let sep = case Lua.fromOptional optSep of + Just x -> B.fromList x + Nothing -> Shared.defaultBlocksSeparator + return $ B.toList (Shared.blocksToInlinesWithSep sep blks) + -- | Convert list of Pandoc blocks into (hierarchical) list of Elements. hierarchicalize :: [Block] -> Lua [Shared.Element] hierarchicalize = return . Shared.hierarchicalize diff --git a/src/Text/Pandoc/Shared.hs b/src/Text/Pandoc/Shared.hs index 5b011c46a..412de99a0 100644 --- a/src/Text/Pandoc/Shared.hs +++ b/src/Text/Pandoc/Shared.hs @@ -94,6 +94,8 @@ module Text.Pandoc.Shared ( -- * for squashing blocks blocksToInlines, blocksToInlines', + blocksToInlinesWithSep, + defaultBlocksSeparator, -- * Safe read safeRead, -- * Temp directory @@ -757,12 +759,19 @@ blocksToInlinesWithSep sep = mconcat . intersperse sep . map blockToInlines blocksToInlines' :: [Block] -> Inlines -blocksToInlines' = blocksToInlinesWithSep parSep - where parSep = B.space <> B.str "¶" <> B.space +blocksToInlines' = blocksToInlinesWithSep defaultBlocksSeparator blocksToInlines :: [Block] -> [Inline] blocksToInlines = B.toList . blocksToInlines' +-- | Inline elements used to separate blocks when squashing blocks into +-- inlines. +defaultBlocksSeparator :: Inlines +defaultBlocksSeparator = + -- This is used in the pandoc.utils.blocks_to_inlines function. Docs + -- there should be updated if this is changed. + B.space <> B.str "¶" <> B.space + -- -- Safe read diff --git a/test/Tests/Lua.hs b/test/Tests/Lua.hs index 9d2d3b635..f00142f1d 100644 --- a/test/Tests/Lua.hs +++ b/test/Tests/Lua.hs @@ -109,7 +109,8 @@ tests = map (localOption (QuickCheckTests 20)) assertFilterConversion "pandoc.utils doesn't work as expected." "test-pandoc-utils.lua" (doc $ para "doesn't matter") - (doc $ mconcat [ plain (str "hierarchicalize: OK") + (doc $ mconcat [ plain (str "blocks_to_inlines: OK") + , plain (str "hierarchicalize: OK") , plain (str "normalize_date: OK") , plain (str "pipe: OK") , plain (str "failing pipe: OK") diff --git a/test/lua/test-pandoc-utils.lua b/test/lua/test-pandoc-utils.lua index 21f937edb..4421603ec 100644 --- a/test/lua/test-pandoc-utils.lua +++ b/test/lua/test-pandoc-utils.lua @@ -1,5 +1,19 @@ utils = require 'pandoc.utils' +-- Squash blocks to inlines +------------------------------------------------------------------------ +function test_blocks_to_inlines () + local blocks = { + pandoc.Para{ pandoc.Str 'Paragraph1' }, + pandoc.Para{ pandoc.Emph 'Paragraph2' } + } + local inlines = utils.blocks_to_inlines(blocks, {pandoc.LineBreak()}) + return #inlines == 3 + and inlines[1].text == "Paragraph1" + and inlines[2].t == 'LineBreak' + and inlines[3].content[1].text == "Paragraph2" +end + -- hierarchicalize ------------------------------------------------------------------------ function test_hierarchicalize () @@ -110,6 +124,7 @@ end function Para (el) return { + pandoc.Plain{pandoc.Str("blocks_to_inlines: " .. run(test_blocks_to_inlines))}, pandoc.Plain{pandoc.Str("hierarchicalize: " .. run(test_hierarchicalize))}, pandoc.Plain{pandoc.Str("normalize_date: " .. run(test_normalize_date))}, pandoc.Plain{pandoc.Str("pipe: " .. run(test_pipe))}, -- cgit v1.2.3