git.iko.soy/typeable/pandoc
on master help sign in
Lua filter: use Attributes constructor for Attrs

Element attributes are pushed to the stack via the `Attributes` function. `Attributes` creates an Attr like triple, but the triple also allows table-like access to key-value pairs.

commit3d6edbd9e39dfccdd76ec32f9aa34977b7b56fe0 authorAlbert Krewinkel <albert@zeitkraut.de> dateSat 15 Apr 2017, 09:31 (10 years ago) parentac27552
2 files changed+76−30
data/pandoc.lua+50−16 src/Text/Pandoc/Lua/StackInstances.hs+26−14
data/pandoc.lua+50−16
@@ -550,16 +550,6 @@ M.Superscript = M.Inline:create_constructor(
550550
551551-- Attributes
552552M.Attributes = {}
553−setmetatable(M.Attributes, M.Attributes)
554−M.Attributes.__index = function(t, k)
555− if k == "id" then
556− return t[1]
557− elseif k == "class" then
558− return table.concat(t[2], ' ')
559− else
560− return t.kv[k]
561− end
562−end
563553--- Create a new set of attributes (Attr).
564554-- @function Attributes
565555-- @tparam table key_values table containing string keys and values
@@ -567,17 +557,61 @@ end
567557-- @tparam[opt] {string,...} classes element classes
568558-- @return element attributes
569559M.Attributes.__call = function(t, key_values, id, classes)
570− local kv = {}
571− for i = 1, #key_values do
572− kv[key_values[i][1]] = key_values[i][2]
573− end
574560 id = id or ''
575561 classes = classes or {}
576− local attr = {id, classes, key_values, kv = kv}
562+ local attr = {id, classes, key_values}
577563 setmetatable(attr, t)
578564 return attr
579565end
580−M.Attributes.empty = M.Attributes('', {}, {})
566+M.Attributes.__index = function(t, k)
567+ if rawget(t, k) then
568+ return rawget(t, k)
569+ elseif k == "id" then
570+ if rawget(t, 1) == '' then
571+ return nil
572+ else
573+ return rawget(t, 1)
574+ end
575+ elseif k == "class" then
576+ if #(rawget(t, 2)) == 0 then
577+ return nil
578+ else
579+ return table.concat(t[2], ' ')
580+ end
581+ else
582+ for _, p in ipairs(t[3]) do
583+ if k == p[1] then
584+ return p[2]
585+ end
586+ end
587+ return nil
588+ end
589+end
590+M.Attributes.__newindex = function(t, k, v)
591+ if rawget(t, k) then
592+ rawset(t, k, v)
593+ elseif k == "id" then
594+ rawset(t, 1, v)
595+ elseif k == "class" then
596+ if type(v) == "string" then
597+ rawset(t, 2, {v})
598+ else
599+ rawset(t, 2, v)
600+ end
601+ else
602+ for _, p in ipairs(rawget(t, 3)) do
603+ if k == p[1] then
604+ p[2] = v
605+ return
606+ end
607+ end
608+ kv = rawget(t, 3)
609+ kv[#kv + 1] = {k, v}
610+ rawset(t, 3, kv)
611+ end
612+end
613+setmetatable(M.Attributes, M.Attributes)
614+
581615
582616--- Creates a single citation.
583617-- @function Citation
src/Text/Pandoc/Lua/StackInstances.hs+26−14
@@ -170,10 +170,10 @@ pushBlock :: LuaState -> Block -> IO ()
170170pushBlock lua = \case
171171 BlockQuote blcks -> pushViaConstructor lua "BlockQuote" blcks
172172 BulletList items -> pushViaConstructor lua "BulletList" items
173− CodeBlock attr code -> pushViaConstructor lua "CodeBlock" code attr
173+ CodeBlock attr code -> pushViaConstructor lua "CodeBlock" code (LuaAttr attr)
174174 DefinitionList items -> pushViaConstructor lua "DefinitionList" items
175− Div attr blcks -> pushViaConstructor lua "Div" blcks attr
176− Header lvl attr inlns -> pushViaConstructor lua "Header" lvl attr inlns
175+ Div attr blcks -> pushViaConstructor lua "Div" blcks (LuaAttr attr)
176+ Header lvl attr inlns -> pushViaConstructor lua "Header" lvl (LuaAttr attr) inlns
177177 HorizontalRule -> pushViaConstructor lua "HorizontalRule"
178178 LineBlock blcks -> pushViaConstructor lua "LineBlock" blcks
179179 OrderedList lstAttr list -> pushViaConstructor lua "OrderedList" list lstAttr
@@ -193,10 +193,10 @@ peekBlock lua idx = do
193193 Just t -> case t of
194194 "BlockQuote" -> fmap BlockQuote <$> elementContent
195195 "BulletList" -> fmap BulletList <$> elementContent
196− "CodeBlock" -> fmap (uncurry CodeBlock) <$> elementContent
196+ "CodeBlock" -> fmap (withAttr CodeBlock) <$> elementContent
197197 "DefinitionList" -> fmap DefinitionList <$> elementContent
198− "Div" -> fmap (uncurry Div) <$> elementContent
199− "Header" -> fmap (\(lvl, attr, lst) -> Header lvl attr lst)
198+ "Div" -> fmap (withAttr Div) <$> elementContent
199+ "Header" -> fmap (\(lvl, LuaAttr attr, lst) -> Header lvl attr lst)
200200 <$> elementContent
201201 "HorizontalRule" -> return (Just HorizontalRule)
202202 "LineBlock" -> fmap LineBlock <$> elementContent
@@ -218,11 +218,11 @@ peekBlock lua idx = do
218218pushInline :: LuaState -> Inline -> IO ()
219219pushInline lua = \case
220220 Cite citations lst -> pushViaConstructor lua "Cite" lst citations
221− Code attr lst -> pushViaConstructor lua "Code" lst attr
221+ Code attr lst -> pushViaConstructor lua "Code" lst (LuaAttr attr)
222222 Emph inlns -> pushViaConstructor lua "Emph" inlns
223− Image attr alt (src,tit) -> pushViaConstructor lua "Image" alt src tit attr
223+ Image attr alt (src,tit) -> pushViaConstructor lua "Image" alt src tit (LuaAttr attr)
224224 LineBreak -> pushViaConstructor lua "LineBreak"
225− Link attr lst (src,tit) -> pushViaConstructor lua "Link" lst src tit attr
225+ Link attr lst (src,tit) -> pushViaConstructor lua "Link" lst src tit (LuaAttr attr)
226226 Note blcks -> pushViaConstructor lua "Note" blcks
227227 Math mty str -> pushViaConstructor lua "Math" mty str
228228 Quoted qt inlns -> pushViaConstructor lua "Quoted" qt inlns
@@ -230,7 +230,7 @@ pushInline lua = \case
230230 SmallCaps inlns -> pushViaConstructor lua "SmallCaps" inlns
231231 SoftBreak -> pushViaConstructor lua "SoftBreak"
232232 Space -> pushViaConstructor lua "Space"
233− Span attr inlns -> pushViaConstructor lua "Span" inlns attr
233+ Span attr inlns -> pushViaConstructor lua "Span" inlns (LuaAttr attr)
234234 Str str -> pushViaConstructor lua "Str" str
235235 Strikeout inlns -> pushViaConstructor lua "Strikeout" inlns
236236 Strong inlns -> pushViaConstructor lua "Strong" inlns
@@ -245,11 +245,11 @@ peekInline lua idx = do
245245 Nothing -> return Nothing
246246 Just t -> case t of
247247 "Cite" -> fmap (uncurry Cite) <$> elementContent
248− "Code" -> fmap (uncurry Code) <$> elementContent
248+ "Code" -> fmap (withAttr Code) <$> elementContent
249249 "Emph" -> fmap Emph <$> elementContent
250− "Image" -> fmap (\(attr, lst, tgt) -> Image attr lst tgt)
250+ "Image" -> fmap (\(LuaAttr attr, lst, tgt) -> Image attr lst tgt)
251251 <$> elementContent
252− "Link" -> fmap (\(attr, lst, tgt) -> Link attr lst tgt)
252+ "Link" -> fmap (\(LuaAttr attr, lst, tgt) -> Link attr lst tgt)
253253 <$> elementContent
254254 "LineBreak" -> return (Just LineBreak)
255255 "Note" -> fmap Note <$> elementContent
@@ -259,7 +259,7 @@ peekInline lua idx = do
259259 "SmallCaps" -> fmap SmallCaps <$> elementContent
260260 "SoftBreak" -> return (Just SoftBreak)
261261 "Space" -> return (Just Space)
262− "Span" -> fmap (uncurry Span) <$> elementContent
262+ "Span" -> fmap (withAttr Span) <$> elementContent
263263 "Str" -> fmap Str <$> elementContent
264264 "Strikeout" -> fmap Strikeout <$> elementContent
265265 "Strong" -> fmap Strong <$> elementContent
@@ -270,3 +270,15 @@ peekInline lua idx = do
270270 -- Get the contents of an AST element.
271271 elementContent :: StackValue a => IO (Maybe a)
272272 elementContent = getTable lua idx "c"
273+
274+withAttr :: (Attr -> a -> b) -> (LuaAttr, a) -> b
275+withAttr f (attributes, x) = f (fromLuaAttr attributes) x
276+
277+-- | Wrapper for Attr
278+newtype LuaAttr = LuaAttr { fromLuaAttr :: Attr }
279+
280+instance StackValue LuaAttr where
281+ push lua (LuaAttr (id', classes, kv)) =
282+ pushViaConstructor lua "Attributes" kv id' classes
283+ peek lua idx = fmap LuaAttr <$> peek lua idx
284+ valuetype _ = TTABLE