summaryrefslogtreecommitdiff
path: root/count-para.lua
diff options
context:
space:
mode:
authoryctct <yctct@yctct.com>2025-11-06 10:11:29 +0100
committeryctct <yctct@yctct.com>2025-11-06 10:11:29 +0100
commit1c7856fd3aff5fd059f040262d9647f60a18e0c1 (patch)
tree0e819830d4ea86f6359a5ac49470a4fe1e9b0255 /count-para.lua
Add scripts and functions
Diffstat (limited to 'count-para.lua')
-rwxr-xr-xcount-para.lua210
1 files changed, 210 insertions, 0 deletions
diff --git a/count-para.lua b/count-para.lua
new file mode 100755
index 0000000..6d4b659
--- /dev/null
+++ b/count-para.lua
@@ -0,0 +1,210 @@
+--[[
+Make all 'regular' paragraphs into a div and assign a numeric ID
+Format this number in the margin
+Copyright © 2021 Michael Cysouw <cysouw@mac.com>
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+]]
+
+local count = 0
+local chapter = 0
+local indexUserID = {}
+
+------------------------------
+-- Options with default values
+------------------------------
+
+local resetAtChapter = false
+local enclosing = "[]"
+local chapterSep = "."
+local refName = "paragraph "
+local addPageNr = true
+
+function getUserSettings (meta)
+
+ if meta.resetAtChapter ~= nil then
+ resetAtChapter = meta.resetAtChapter
+ end
+
+ if meta.enclosing ~= nil then
+ enclosing = pandoc.utils.stringify(meta.enclosing)
+ end
+
+ if meta.chapterSep ~= nil then
+ chapterSep = pandoc.utils.stringify(meta.chapterSep)
+ end
+
+ if meta.refName ~= nil then
+ refName = pandoc.utils.stringify(meta.refName)
+ if FORMAT:match "latex" then
+ if refName == "#" then refName = "\\#" end
+ end
+ end
+
+ if meta.addPageNr ~= nil then
+ addPageNr = meta.addPageNr
+ end
+
+end
+
+------------------------
+-- Add global formatting
+------------------------
+
+function addFormatting (meta)
+
+ local tmp = pandoc.MetaList{meta['header-includes']}
+ if meta['header-includes'] ~= nil then
+ tmp = meta['header-includes']
+ end
+
+ if FORMAT:match "html" then
+ local css = [[
+<!-- CSS added by lua-filter 'count-para' -->
+<style>
+.paragraph-number {
+ float: left;
+ margin-left: -5em;
+ width: 4.5em;
+ text-align: right;
+ color: grey;
+ font-size: x-small;
+ padding-top: 5px;
+}
+</style>
+ ]]
+ tmp[#tmp+1] = pandoc.MetaBlocks(pandoc.RawBlock("html", css))
+ end
+
+ function addTexPreamble (tex)
+ tmp[#tmp+1] = pandoc.MetaBlocks(pandoc.RawBlock("tex", tex))
+ end
+
+ if FORMAT:match "latex" then
+ addTexPreamble("\\usepackage{marginnote}")
+ addTexPreamble("\\reversemarginpar")
+ addTexPreamble("\\usepackage{xcolor}")
+ addTexPreamble("\\newcommand{\\paragraphnumber}[1]{\\marginnote{\\color{black}\\tiny{#1}}[0pt]}")
+ end
+
+ meta['header-includes'] = tmp
+ return(meta)
+end
+
+-------------------------
+-- count Para and add Div
+-------------------------
+
+function countPara (doc)
+
+ for i=1,#doc.blocks do
+
+ -- optionally reset counter
+ if doc.blocks[i].tag == "Header"
+ and doc.blocks[i].level == 1
+ and doc.blocks[i].classes[1] ~= "unnumbered"
+ and resetAtChapter
+ then
+ chapter = chapter + 1
+ count = 0
+ end
+
+ -- get Para, but not if there is an Image inside
+ if doc.blocks[i].tag == "Para"
+ and doc.blocks[i].content[1].tag ~= "Image"
+ then
+
+ -- count paragraphs
+ count = count + 1
+ local ID = count
+ if resetAtChapter then
+ ID = chapter..chapterSep..count
+ end
+
+ -- format number to insert
+ local number = ID
+ if enclosing:len() == 1 then
+ number = enclosing..ID..enclosing
+ else
+ number = enclosing:sub(1,1)..ID..enclosing:sub(2,2)
+ end
+
+ -- check for user-inserted ids at the start of the paragraph
+ local firstElem = pandoc.utils.stringify(doc.blocks[i].content[1])
+ local userID = firstElem:match("{#(.*)}")
+ if userID ~= nil then
+ -- add to index
+ indexUserID[userID] = ID
+ -- remove reference from text
+ table.remove(doc.blocks[i].content, 1)
+ -- remove possible space
+ if doc.blocks[i].content[1].tag == "Space" then
+ table.remove(doc.blocks[i].content, 1)
+ end
+ end
+
+ -- insert number
+ if FORMAT:match "latex" then
+ -- use marginnote for formatting number in margin
+ local texCount = "\\paragraphnumber{"..number.."}"
+ if userID ~= nil then
+ -- add target for link to the number
+ texCount = "\\hypertarget{"..userID.."}{\n"..texCount.."\\label{"..userID.."}}"
+ end
+ table.insert(doc.blocks[i].content, 1, pandoc.RawInline("tex", texCount))
+ else
+ table.insert(doc.blocks[i].content, 1, pandoc.Space())
+ table.insert(doc.blocks[i].content, 1, pandoc.Span(number, pandoc.Attr(ID, {"paragraph-number"})))
+ end
+
+ end
+ end
+ return doc
+end
+
+------------------------------
+-- set in-text cross-references
+------------------------------
+
+function setCrossRefs (cite)
+
+ local userID = cite.citations[1].id
+ local paraID = indexUserID[userID]
+
+ -- ignore other "cite" elements
+ if paraID ~= nil then
+
+ -- make in-document cross-references
+ if FORMAT:match "latex" then
+
+ local texInsert = refName.."\\hyperlink{"..userID.."}{"..paraID.."}"
+ if addPageNr then
+ texInsert = texInsert.." on page~\\pageref{"..userID.."}"
+ end
+ return pandoc.RawInline("tex", texInsert)
+
+ else
+ return pandoc.Link(refName..paraID, "#"..paraID)
+ end
+
+ end
+end
+
+--------------------
+-- basic Pandoc loop
+--------------------
+
+return {
+ { Meta = addFormatting },
+ { Meta = getUserSettings },
+ { Pandoc = countPara },
+ { Cite = setCrossRefs }
+}