0

I’d like to remove all markdown links but keep the link text and square bracket using Lua filter. For example, the original content is like:

[@a-local-file, page 15](x-devonthink-item://742BD8FE-B962-422F-98C1-B1K4DQA5A117?page=15)

And I’d like to convert it to:

[@a-local-file, page 15]

I’ve tried to write a Lua filter for this conversion:

function Link(el)
    if el.target:find("^x%-devonthink%-item://") then
        return el.content
    end
end

However, with this Lua filter, it returned only the link text:

@a-local-file, page 15

There is a related question but the answer is not very straightforward to my question. Because my purpose is to use [@a-local-file, page 15] as NormalCitation. But if a pair of square brackets is added, it will be changed as AuthorInText, which is undesirable.

How to modify the code to keep both link text and square brackets for Pandoc’s normal citations? Thanks in advance!

TomBen
  • 302
  • 3
  • 6

1 Answers1

2

A simple trick is to wrap strings into tables, as pandoc will then treat them as pandoc.Inlines items and allow to concatenate them to the link.content, which is also of type pandoc.Inlines.

function Link (link)
  if link.target:match '^x%-devonthink%-item://' then
    return {'['} .. link.content .. {']'}
  end
end

Pandoc will treat this as if we had written

    return
        pandoc.Inlines{pandoc.Str '['} ..
        link.content ..
        pandoc.Inlines{pandoc.Str ']'}

Now, some formats use square brackets as part of their markup, and pandoc will escape them in that case. If the goal is to have unescaped brackets while round-tripping to Markdown, then we'll need to use RawInline elements instead of Str:

    return raw'[' .. link.content .. raw']'

where raw is defined as

local function raw (s)
  return {pandoc.RawInline('markdown', s)}
end

The content of RawInline elements is not escaped (if the raw format matches the target format).


Citations

The updated question mentions the desire to have this treated as a normal citation. This isn't quite as straight forward, because citation parsing isn't simple. What we can do, however, is create a Markdown string that looks the way we'd want it to, and then use pandoc.read to parse it into an AST:

    local linkstring = pandoc.utils.stringify(link.contents)
    -- alternative:
    -- local placeholder = pandoc.Pandoc{pandoc.Plain(link.contents)}
    -- local linkstring = pandoc.write(placeholder, 'markdown')
    local citationmd = string.format('[%s]', linkstring)
    return pandoc.utils.blocks_to_inlines(
      pandoc.read(citationmd, 'markdown').blocks
    )

Make sure that the filter runs before citeproc.

tarleb
  • 19,863
  • 4
  • 51
  • 80
  • Thanks! This code get `\[a-local-file, page 15\]`, where square brackets are escaped. But it should actually be `[a-local-file, page 15]` for the use of citations. How could it be modified to make it? – TomBen Feb 25 '23 at 00:28
  • Sorry I didn’t make my question clearly. The most important part of this Lua filter is removing links but keep link texts to use as the normal citation. I have updated the question. Thanks again. – TomBen Feb 25 '23 at 05:57
  • Thanks for your reply. But it't the same result, all citations are treated as author-in-text citation instead of the expected normal citation. – TomBen Feb 25 '23 at 09:38
  • D'OH, somehow I completely missed the part the part about `NormalCitation`. My bad. I'll try to update this later. – tarleb Feb 25 '23 at 14:58