pandoc / lua-filters

A collection of lua filters for pandoc
MIT License
610 stars 166 forks source link

include-files.lua fails with relative path if not executed from the main document directory #238

Open chrisaga opened 2 years ago

chrisaga commented 2 years ago

All relative paths are processed relatively to the working directory. Relative path in a document (main source file) are obviously relative to the directory of this document. So the filter works only if the working directory (from which the pandoc command is run) is the directory where the main document is stored.

This should be easily fixed if we could access to the sourcefile variable set by Pandoc (see Pandoc's manual). I was not able to figure out how it can be accessed from a lua filter.

NB1. I suspect the same restriction applies to include-code-files.lua NB2. With this restriction we can not even build clean test cases with all files stored in a test subdirectory

wenbopeng commented 1 year ago

Absolute paths are fine, but the line 86 local fh = io.open(line) of the lua filter does not support non-Latin paths.

AH-Hammi commented 9 months ago

I found a solution. I modifyed the code a bit but didnt came to the moment to create a PR:

My modification looks as followed:

    local path = pandoc.path.directory(PANDOC_STATE.input_files[1]) .. "\\" .. cb.attributes.include
    local fh = io.open(path)
    if not fh then
      io.stderr:write("Cannot open file " .. path .. " | Skipping includes\n")
    else
      ...

When i am done with my exams I will do a PR

wenbopeng commented 9 months ago

I have solved it with the help of ChatGPT.


-- block-auto.lua
function RawBlock(raw)
  -- 根据嵌入的格式匹配相应的过滤器
  local filters = {
    markdown = pandoc.read(raw.text, 'markdown').blocks,
    html = pandoc.read(raw.text, 'html').blocks,
    latex = pandoc.read(raw.text, 'latex').blocks
  }
  -- 返回匹配到的过滤器的结果,如果没有匹配到,返回原始块
  return filters[raw.format] or raw
end

function CodeBlock (cb)
  -- 根据嵌入的格式匹配相应的过滤器
  local filters = {
    ["insert-markdown"] = function (path)
      local blocks = pandoc.pipe("pandoc", {"-f", "markdown", "-t", "markdown", path}, "")
      local doc = pandoc.read(blocks, "markdown")
      return doc.blocks
    end,
    ["insert-html"] = function (path)
      local blocks = pandoc.pipe("pandoc", {"-f", "html", "-t", "json", path}, "")
      local doc = pandoc.read(blocks, "json")
      return doc.blocks
    end,
    ["insert-latex"] = function (path)
      local blocks = pandoc.pipe("pandoc", {"-f", "latex", "-t", "json", path}, "")
      local doc = pandoc.read(blocks, "json")
      return doc.blocks
    end,
    ["insert-docx"] = function (path)
      local blocks = pandoc.pipe("pandoc", {"-f", "docx", "-t", "json", path}, "")
      local doc = pandoc.read(blocks, "json")
      return doc.blocks
    end
  }
  -- 创建一个空的结果列表
  local result = {}
  -- 遍历代码块中的每一行
  for line in cb.text:gmatch("[^\n]+") do
    -- 假设每一行都是一个文件路径,尝试匹配相应的过滤器
    local matched = false
    for class, filter in pairs(filters) do
      if cb.classes:includes(class) then
        -- 如果有匹配到的过滤器,调用它并将结果添加到结果列表中
        local blocks = filter(line)
        for _, block in ipairs(blocks) do
          table.insert(result, block)
        end
        matched = true
        break
      end
    end
    -- 如果没有匹配到任何过滤器,就保留原始内容,并将其作为一个段落添加到结果列表中
    if not matched then
      table.insert(result, pandoc.Para({pandoc.Str(line)}))
    end
  end
  -- 返回结果列表作为新的代码块内容
  return result
end

Instructions:


```{.insert-html}
D:\Research\R\Project\output\report.html
D:\Research\R\Project\output\report.md
D:\Research\R\Project\output\report.tex
D:\Research\R\Project\output\report.docx