Skip to content

Instantly share code, notes, and snippets.

@johnd0e
Last active May 3, 2023 18:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnd0e/7d00f4d8899ec9920b2b84ceed4a6e02 to your computer and use it in GitHub Desktop.
Save johnd0e/7d00f4d8899ec9920b2b84ceed4a6e02 to your computer and use it in GitHub Desktop.
Makefile for documents converting using pandoc
-- transform to BulletList
function DefinitionList(el)
local items = {}
for i,item in ipairs(el.content) do
local dt,blocks = table.unpack(item) --term,definitions
local first = blocks[1]
items[i] = first
for j=2,#blocks do
first:extend(blocks[j])
end
dt:extend{pandoc.Str" "} --actually needed not for gfm but for some other flavors
first:insert(1,pandoc.Plain(dt))
end
return pandoc.BulletList(items)
end
-- Save space moving all (except first) sections content inside spoilers
local function condition (header, blocks, idx)
if pandoc.utils.stringify(header):match"cfgscript" then --hardcoded for now
blocks[idx] = pandoc.HorizontalRule()
return "skip"
end
end
local function callback (blocks, startIdx, endIdx)
-- transform headers into plain (but formatted) text
blocks[startIdx] = pandoc.Para{pandoc.RawInline("markdown", "[u]"), pandoc.Strong(blocks[startIdx].content), pandoc.RawInline("markdown","[/u]")}
blocks[startIdx].content:insert(pandoc.RawInline("markdown", " [spoiler]"))
blocks:insert(endIdx, pandoc.RawBlock("markdown", "[/spoiler]"))
return endIdx+1
end
local first = true
return {
{ -- remove redundant first header, as forum topic already has own title
Header=function()
if first then
first = false
return {}
end
end
}, { -- add spoilers
Pandoc=function(doc)
require"sections"(doc.blocks, callback, condition)
return doc
end
}
}
-- phpBB3 uses own markdown parser (https://s9etextformatter.readthedocs.io/Plugins/Litedown/Syntax/),
-- which differs in some minor details. That's why some fixes is need.
function Str (el)
-- normal way of escaping the asterisk is \*, but that does not work in Litedown.
if el.text=="*" then
return pandoc.RawInline("markdown","[i]*[/i]")
end
end
function Link (el)
-- replace by Emph because forum engine fails to parse such links
if el.target:match"^:" then
return pandoc.Emph(el.content)
end
-- remove links as forum engine does not create anchors for headers.
if el.target:match"^#" then
return pandoc.Strong(el.content)
end
end
-- grab first header as title, but only if no explicit metadata specified (yaml)
local title
function Header(el)
if title then return end
title = pandoc.utils.stringify(el)
end
function Meta(el)
if not el.pagetitle then
el.pagetitle = title
return el
end
end
ifeq (1,$(words $(MAKEFILE_LIST))) # if not included
.DEFAULT_GOAL:=help
endif
define HELP
Makefile for documents converting using pandoc.
Source: *.text (extension defined by SOURCE_EXT).
Target(s): enumerated in commandline (otherwise can be set in .DEFAULT_GOAL)
Usage:
make some_doc.html
Convert some_doc.text to some_doc.html.
Instead of ".html" any other pandoc-supported file type can be used.
make html
Convert *.text to *.html.
Instead of ".html" any other supported extension can be used, incl. hlf (must be enumerated in TARGET_EXT).
make some_doc.hlf
make hlf
Convert to .hlf using pandoc and HtmlToFarHelp.
make some_doc.forum
make forum
Convert to phpBB-flavored markdown (Litedown).
make clean
Clean current directory from all files with extensins specified in TARGET_EXT.
make help
This help
make install
Copy *.lua to $(APPDATA)\pandoc\filters
Or to $$(DATA_DIR)\filters (if defined).
Notes:
1. pandoc.exe and HtmlToFarHelp.exe must be available.
It is also possible to define full paths in env variables PANDOC/HTMLTOFARHELP.
2. Some conversions may require additional lua filters, which must be present in current directory.
Alternatively they can reside in $(DATA_DIR)\filters
(See `make install`)
3. Some conversions may require lua writers, which must be present in current directory.
Alternatively they can reside in $(DATA_DIR)\custom
4. The best way to customize this Makefile is including it in own Makefile, adding new rules
and (re)defining corresponding variables.
endef
SOURCE_EXT:=text
SOURCE_FORMAT?=--from=markdown-auto_identifiers-raw_tex+autolink_bare_uris
TARGET_EXT+=hlfhtml htm html md plain native json forum hlf
ifneq (,$(filter $(TARGET_EXT),$(SOURCE_EXT)))
$(error TARGET_EXT cannot include SOURCE_EXT)
else ifneq (1,$(words $(SOURCE_EXT)))
$(error SOURCE_EXT must be single ext)
endif
#https://pandoc.org/installing.html
PANDOC?=pandoc.exe
TARGET_FORMAT:= # deduced from extension; defaulting to html
FLAGS+=--wrap=preserve
EXTRA+=--lua-filter=FarLinks.lua
#https://www.nuget.org/packages/HtmlToFarHelp
HTMLTOFARHELP?=HtmlToFarHelp.exe
RM:=del
ifdef DATA_DIR
FLAGS+= --data-dir=$(DATA_DIR)
else
DATA_DIR:=$(APPDATA)\pandoc#default
endif
LUA_PATH:=$(LUA_PATH);$(DATA_DIR)\filters\?.lua;$(DATA_DIR)\filters\?\init.lua
# Far Manager help file
%.hlf: %.hlfhtml
@$(HTMLTOFARHELP) from="$<"; to="$@"
$(info $@)
# intermediate file for hlf
%.hlfhtml: TARGET_FORMAT:= --to=html --no-highlight
%.hlfhtml: EXTRA:=
# full-featured html, with headers, styles, ... (otherwise use `htm`)
%.html: FLAGS+= --standalone --strip-comments --lua-filter=HeaderToTitle.lua
# github-flavored markdown (pandoc --list-extensions=gfm)
%.md: TARGET_FORMAT:= --to=gfm --lua-filter=DefinitionToBulletList.lua
# prepare text for posting on forum.farmanager.com
%.forum: TARGET_FORMAT:=--to=markdown_strict+fenced_code_blocks-raw_html --lua-filter=DefinitionToBulletList.lua
%.forum: FLAGS+= --lua-filter=fold.lua --lua-filter=forum.lua
%.forum: EXTRA:=--shift-heading-level-by=1 --strip-comments
#prevent circular dependencies
%.text %.lua: ;
$(MAKEFILE_LIST): ;
.SECONDEXPANSION: #https://www.gnu.org/software/make/manual/html_node/Secondary-Expansion.html#Secondary-Expansion
%: $$(basename %).$(SOURCE_EXT) $(MAKEFILE_LIST) $(wildcard *.lua)
@$(PANDOC) $(SOURCE_FORMAT) $(TARGET_FORMAT) $(FLAGS) $(EXTRA) --output=$@ $<
$(info $@)
.PHONY: $(TARGET_EXT) clean help install
# targets like html md hlf...
SOURCES:=$(wildcard *.$(SOURCE_EXT))
NAMES:=$(basename $(SOURCES))
$(TARGET_EXT): %: $(addsuffix .%,$(NAMES))
TARGETS_MASK:=$(addprefix *.,$(TARGET_EXT))
clean:
$(info $(wildcard $(TARGETS_MASK)))
@$(RM) $(TARGETS_MASK)
help:
$(info $(HELP))
@rem
install: $(DATA_DIR)/filters $(addprefix $(DATA_DIR)/filters/, $(wildcard *.lua))
$(DATA_DIR)/filters:
mkdir $(subst /,\,$@)
$(DATA_DIR)/filters/%: %
@rem cmd /c mklink $(subst /,\, $@ $(realpath $<))
copy $< $(subst /,\,$@)
-- helper script to execute same `callback` function for every section
-- to the same section belong blocks beginning by header and ending by last block before next header
-- it is possible to skip some header (= include it inside section), with `condition` function, returning `true`
return function (blocks, callback, condition)
local start
local i = 1
repeat
if blocks[i].t=="Header" then
local skip = condition and condition(blocks[i], blocks, i)
if not skip then
if start then
local h = blocks[i]
i = callback(blocks, start, i) or i
assert(blocks[i]==h,"wrong index returned by callback")
end
start = i
end
end
i = i+1
until not blocks[i]
if start then
callback(blocks, start, i)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment