Pandoc: в файле .md, как изменить блок метаданных YAML и поместить измененный блок в формат markdown с помощью фильтра lua

#lua #yaml #filtering #metadata #pandoc

#lua #yaml #фильтрацию #метаданные #pandoc

Вопрос:

Я хочу преобразовать некоторые части метаданных в заголовке YAML файла .md с пустым блоком, прежде чем передавать его в файл шаблона. То есть рабочий процесс будет таким:

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

lua_filter предназначен для выполнения перетасовки элементов подзапроса (которые состоят из 3 подпунктов: ‘answer’, ‘stem’ и ‘key’), а затем присвоить им порядковый номер списка (содержимое подпункта ‘key’).

Я не знаю, как выполнить часть фильтра lua.

  1. Пример файла YAML: 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 файл:
 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), 'nn')
            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}
 

Этот ужасный код — это то, с чем я экспериментировал, чтобы проверить, возможно ли перемешивание и изменение содержимого «ключа». Кажется, что это так, но моя проблема в том, как поместить измененные результаты в измененный файл .md. («Код» основан на https://pandoc.org/lua-filters.html#replacing-placeholders-with-their-metadata-value ; Я использовал прокомментированную функцию замены для выполнения «отладки», используя отпечатки здесь и там … Mea culpa!)

Я знаю о автономной опции -s в:

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

Но это отображает исходный материал YAML, а не измененный.

Заранее спасибо за вашу помощь.

Комментарии:

1. Измененные метаданные должны быть переданы обратно в pandoc. Одним из шагов является изменение m переменной и return ее в конце функции.

2. Вместо добавления [Решаемая] в заголовок, поместите свое решение в ответ и пометьте его как принятое.

Ответ №1:

Кажется, это то, что я искал:

Обновленный shuffle_filter.lua файл:

 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}}
 
  • Для вывода измененных метаданных в стандартный вывод (или готовый к передаче, например, в шаблон):

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

  • Для проверки измененного AST:

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