|
| 1 | +--[[ |
| 2 | +multibib-renumber – renumber numbered references and their citations |
| 3 | +
|
| 4 | +Copyright © 2018-2024 Albert Krewinkel |
| 5 | +
|
| 6 | +Permission to use, copy, modify, and/or distribute this software for any |
| 7 | +purpose with or without fee is hereby granted, provided that the above |
| 8 | +copyright notice and this permission notice appear in all copies. |
| 9 | +
|
| 10 | +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 11 | +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 12 | +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 13 | +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 14 | +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 15 | +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 16 | +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 17 | +]] |
| 18 | + |
| 19 | +local pandoc = require 'pandoc' |
| 20 | +local List = require 'pandoc.List' |
| 21 | + |
| 22 | +-- this filter should run after the multibib filter |
| 23 | +-- (the logic is too dependent on the CSL, although it should do no harm) |
| 24 | + |
| 25 | +-- map from reference id to its new label |
| 26 | +local ref_map = List() |
| 27 | + |
| 28 | +-- ref counter |
| 29 | +local ref_counter = 1 |
| 30 | + |
| 31 | +local function collect_numbered_refs(div) |
| 32 | + if div.attr.classes:includes('csl-entry') then |
| 33 | + local identifier = div.attr.identifier |
| 34 | + local content = div.content |
| 35 | + -- expect single Para with a Span (depending on style) possibly containing |
| 36 | + -- the citation number (only do anything if it does) |
| 37 | + if (#div.content > 0 and #div.content[1].content > 0 and |
| 38 | + div.content[1].content[1].tag == 'Span') then |
| 39 | + local span = div.content[1].content[1] |
| 40 | + local content = span.content |
| 41 | + if #content > 0 then |
| 42 | + local text = content[1].text |
| 43 | + local pre, num, post = content[1].text:match("^(%p*)(%d+)(%p*)$") |
| 44 | + if pre and num and post then |
| 45 | + local ident = identifier:gsub('^ref%-', '') |
| 46 | + local label = string.format('%s%d%s', pre, ref_counter, post) |
| 47 | + content[1] = pandoc.Str(label) |
| 48 | + ref_map[ident] = label |
| 49 | + ref_counter = ref_counter + 1 |
| 50 | + return div |
| 51 | + end |
| 52 | + end |
| 53 | + end |
| 54 | + end |
| 55 | +end |
| 56 | + |
| 57 | +local function renumber_cites(cite) |
| 58 | + -- only consider cites with single citations |
| 59 | + if #cite.citations == 1 then |
| 60 | + local id = cite.citations[1].id |
| 61 | + local label = ref_map[id] |
| 62 | + -- only change the content if the label is defined |
| 63 | + if label then |
| 64 | + cite.content = label |
| 65 | + return cite |
| 66 | + end |
| 67 | + end |
| 68 | +end |
| 69 | + |
| 70 | +return { |
| 71 | + { Div = collect_numbered_refs }, |
| 72 | + { Cite = renumber_cites } |
| 73 | +} |
0 commit comments