Фильтр Quarto/Pandoc с использованием метапеременной

Я пытаюсь написать фильтр Lua для Quarto/pandoc, который удаляет все блоки кода, которые не соответствуют целевым языкам, как определено в заголовке yaml документа. Вот какой фильтр я получил на данный момент:

taget_lang = nil

function Meta(m)
  if m.taget_lang then
    taget_lang = pandoc.utils.stringify(m.taget_lang) 
  end
  print("In Meta, taget lang is " .. taget_lang)
  return m
end

function CodeBlock(el)
  print("In CodeBlock, taget lang is " .. taget_lang)
  if taget_lang then
    if el.attr.classes[1] ~= taget_lang then
      return {}
    end
    return el
  end
end

А это пример документа уценки (или, скорее, Quarto):

    ---
    title: Some title
    author: Some author
    date: last-modified
    format:
      ipynb: 
        toc: false
        filters: 
          - langsplit.lua
    taget_lang: "python"
    ---
    
    Here is some text.
    
    ```{python test-py}
    print("some python code")
    ```
    
    ```{r test-r}
    print("some R code")
    ```

Когда я использую quarto render test.qmd, я получаю такой вывод:

nil
nil
nil
nil
In Meta, taget lang is python

И визуализированный документ содержит весь код, что говорит мне о том, что функция CodeBlock не имеет доступа к taget_lang, определенному внутри Meta. Но, судя по документации, это должно работать. Есть какие-нибудь подсказки?

(Также меня не устраивает return {}, который вместо ничего возвращает пустой блок кода, но это отдельная тема)

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В документации указано, что метаданные обрабатываются после фильтрации блоков, поэтому target_lang устанавливается только после обработки элементов CodeBlock.

Есть два способа справиться с этим. Один из способов — фильтровать основной элемент Pandoc, что дает больше контроля:

function Pandoc (doc)
  local target_lang = doc.meta.target_lang
  return doc:walk {
    CodeBlock = function (cb)
      if cb.classes[1] ~= target_lang then
        return {} -- delete block
      end
    end
  }
end

Альтернативой является управление порядком выполнения фильтров путем явного возврата последовательности фильтров, например:

return {
  { Meta = Meta},
  { CodeBlock = CodeBlock },
}

Мне нужно было pandoc.utils.stringify(doc.meta.target_lang), в противном случае это сработало отлично!

JBGruber 01.06.2024 12:30

Что еще не очень хорошо, так это то, что возвращаются листья {} и пустой кодовый блок. Я попробовал nil, но по умолчанию используется исходный блок. Я открыл новый вопрос, так как он выходит за рамки первоначальной цели: stackoverflow.com/questions/78563491/…

JBGruber 01.06.2024 12:36

Судя по опыту, возврат nil из функций pandoc lua пока работает не так, как ожидалось. Вместо этого я использовал pandoc.Null(). Но учитывая проблему удаления pandoc.Null() , какая альтернатива здесь? Пожалуйста, пролейте немного света, @tarleb сенсей.

Shafee 02.06.2024 21:09

Я превратил это в расширение Quarto: github.com/JBGruber/quarto-targetlang Еще раз спасибо за помощь!

JBGruber 03.06.2024 18:33

@Shafee Теоретически замена return pandoc.Null() на return {} должна сработать. Фактически, function pandoc.Null() return {} end — это именно то определение, которое Куарто добавил для обеспечения совместимости со старыми скриптами.

tarleb 05.06.2024 22:34

Другие вопросы по теме