1

I want to transform some parts of the metadata in the YAML header of a block-empty .md file before passing it to a template file. That is, the workflow would be this:

source_YAML_md_file -> lua_filter -> transformed_YAML_md_file -> template -> xml_file

The lua_filter is meant to perform shuffling on subquestion items (which consist of 3 subitems: 'answer', 'stem' and 'key') and then to assign them the list order number (contents of subitem 'key').

I don't know how to do the lua filter part.

  1. YAML sample file: source_YAML.md
---
category: matching

name: test question

questiontext_header: Test Header

questiontext_body: |
  * Blah, blah, blah.
  * More stuff.

shuffle: T
  
keys: T

subquestion:
- key: 1
  stem: |
    Old:
    
      * MacDonald
        + Had
        + a Farm.   
      * E-I-E-I-O
      
  answer: |
    * And on his farm
    * he had a cow 
  
- key: 2
  stem: |
    With a moo moo here
    
  answer: |
    and a moo moo there
  
- key: 3
  stem: |
    Twinkle, twinkle,
    
  answer: |
    * Little
    * Star 

  
- key: 4
  stem: |
    How I wonder 
    
  answer: |
    what you are! 
---
  1. shuffle_filter.lua file:
function shuffle(list)
    math.randomseed(os.time())
    for i = #list, 2, -1 do
        local j = math.random(i)
        list[i], list[j] = list[j], list[i]
    end
end

local vars = {}

function get_vars (m)
  for k, v in pairs(m) do 
    print(k, v, #v) 
    if v == m.subquestion and type(v) == 'table' and v.tag == 'MetaList' then
      print('SUBQUESTION')
      for a, b in pairs(v) do
        print('ab___', a, b)
        for c, d in pairs(b) do
          print('cd______', c, d)
        end
      end
      print('shuffling...')
      shuffle(m.subquestion)
      print('modified after shuffling:')
      for a, b in pairs(m.subquestion) do 
        print('ab___', a, b.t, b, #b)
        for c, d in pairs(b) do
          print('__cd____', '', c, d.t, d, #d) 
          for e, f in pairs(d) do
            if f.t == 'Str' then
              print('changing "key" index:')
              print('           ', 'former index:', '', pandoc.utils.stringify(f))
              f = pandoc.MetaInlines(tostring(a))
              print('____ef_____', '', '', e, f.t, f, d[e])
              print('           ', 'current index:', '', pandoc.utils.stringify(f), '\n\n')
            end
          end
        end
      end
    end
  end 
end

-- function replace (el)
--   if vars[el.text] then
--     return pandoc.Span(vars[el.text])
--   else
--     return el
--   end
-- end
-- 
-- return {{Meta = get_vars}, {Str = replace}}
-- return {Meta = get_vars}

This horrible code is what I've been experimenting with in order to check if shuffling and changing 'key' contents were possible. It seems they are, but my problem is how to put the modified results into a modified .md file. (The 'code' is based on https://pandoc.org/lua-filters.html#replacing-placeholders-with-their-metadata-value ; I used the commented replace function to perform "debugging" using printS here and there... Mea culpa!)

I'm aware of the -s standalone option in:

$ pandoc --lua-filter=shuffle_filter.lua -f markdown -t markdown -s  source_YAML.md

But this renders the original YAML stuff, not the modified one.

Thanks in advance for your help.

Syscall
  • 19,327
  • 10
  • 37
  • 52
Joan Sanz
  • 43
  • 4
  • The modified metadata must be passed back to pandoc. One step is to modify the `m` variable and to `return` it at the end of the function. – tarleb Dec 14 '20 at 10:09
  • Instead of adding [Solved] to the title, put your solution into an answer and mark it as accepted. – tarleb Dec 15 '20 at 07:14

1 Answers1

2

It seems this is what I was looking for:

Updated shuffle_filter.lua file:

function shuffle (m)
    -- 1) shuffle subquestions
    math.randomseed(os.time())
    for i = #m.subquestion, 2, -1 do        
        local j = math.random(i)
        m.subquestion[i], m.subquestion[j] = m.subquestion[j], m.subquestion[i]        
    end
    -- 2) update key index
    for i = 1, #m.subquestion, 1 do
        m.subquestion[i].key = pandoc.MetaInlines(tostring(i))
    end
  return m
end

return {{Meta = shuffle}}
  • To output the modified metadata to stdout (or ready to pipe it, e.g., into a template):

    $ pandoc --lua-filter=shuffle_filter.lua -s -f markdown -t markdown source_YAML.md

  • To check the modified AST:

    $ pandoc --lua-filter=shuffle_filter.lua -s -f markdown -t native source_YAML.md

Joan Sanz
  • 43
  • 4