Skip to content

Commit

Permalink
Produce compilable examples from extract.lua #640
Browse files Browse the repository at this point in the history
  • Loading branch information
hmenke committed Apr 25, 2019
1 parent 0104be3 commit 710bd7f
Showing 1 changed file with 60 additions and 16 deletions.
76 changes: 60 additions & 16 deletions doc/generic/pgf/extract.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
-- TODO: this has to go
local preamble = [[
\usetikzlibrary{3d,arrows,arrows.spaced,arrows.meta,bending,babel,calc,
fit,patterns,plotmarks,shapes.geometric,shapes.misc,shapes.symbols,
shapes.arrows,shapes.callouts,shapes.multipart,shapes.gates.logic.US,
shapes.gates.logic.IEC,circuits.logic.US,circuits.logic.IEC,
circuits.logic.CDH,circuits.ee.IEC,datavisualization,
datavisualization.polar,datavisualization.formats.functions,er,automata,
backgrounds,chains,topaths,trees,petri,mindmap,matrix,calendar,folding,
fadings,shadings,spy,through,turtle,positioning,scopes,
decorations.fractals,decorations.shapes,decorations.text,
decorations.pathmorphing,decorations.pathreplacing,decorations.footprints,
decorations.markings,shadows,lindenmayersystems,intersections,
fixedpointarithmetic,fpu,svg.path,external,graphs,graphs.standard,quotes,
math,angles,views,animations,rdf,perspective}
\usetikzlibrary{graphdrawing}
\usegdlibrary{trees,circular,layered,examples,force,phylogenetics,routing}
]]

local lfs = require("lfs")
local lpeg = require"lpeg"
local lpeg = require("lpeg")
local C, Cf, Cg, Ct, P, S, V = lpeg.C, lpeg.Cf, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.S, lpeg.V

-- strip leading and trailing whitespace
local function strip(str)
return str:match"^%s*(.-)%s*$"
end
-- strip braces
local function strip_braces(str)
return str:match"^{?(.-)}?$"
end

-- optional whitespace
local ws = S" \t\n\r"^0
Expand All @@ -21,14 +44,14 @@ local function set(t,k,v)
-- strip whitespace from keys
k = strip(k)
-- if the value is empty, set it to invalid character
v = v or invalid
v = v and strip_braces(v) or invalid
return rawset(t,k,v)
end

-- Grammar to extract code examples
local extractor = lpeg.P{"document",
name =
C((1 - S"]=")^1),
C((1 - S",]=")^1),

pair =
Cg(V"name" * (lit"=" * V"braces")^0) * lit","^-1,
Expand Down Expand Up @@ -78,42 +101,63 @@ local basename = function(file)
end

-- Main loop
sourcedir = "text-en/"
targetdir = "/tmp/"
if #arg ~= 2 then
print("Usage: " .. arg[-1] .. " " .. arg[0] .. " <source-dir> <target-dir>")
os.exit(1)
end
local pathsep = package.config:sub(1,1)
sourcedir = arg[1] .. pathsep
targetdir = arg[2] .. pathsep
assert(lfs.attributes(sourcedir, "mode") == "directory", sourcedir .. " is not a directory")
assert(lfs.attributes(targetdir, "mode") == "directory", targetdir .. " is not a directory")

for file in lfs.dir(sourcedir) do
if lfs.attributes(sourcedir .. file, "mode") == "file" then
print("Processing " .. file)

-- Read file into memory
local f = io.open(sourcedir .. file)
local text = f:read("*all")
f:close()
local name, ext = basename(file)

-- preprocess, strip all commented lines
text = text:gsub("\n%%[^\n]*\n","")

-- extract all code examples
local matches = extractor:match(text) or {}

-- write code examples to separate files
local setup_code = ""
for n, e in ipairs(matches) do
local options = e[1]
local content = e[2]

-- If the snippet is marked as setup code, we have to put it before
-- every other snippet in the same file
if options["setup code"] then
setup_code = setup_code .. strip(content) .. "\n"
end

-- Skip those that say "code only"
if not options["code only"] then
local newname = name .. "-" .. n .. "." .. ext

local examplefile = io.open(targetdir .. newname, "w")

-- TODO: Use options to convert to MWE
examplefile:write("===Options===\n")
for key, value in pairs(options) do
examplefile:write(key)
if value ~= invalid then
examplefile:write("=" .. value)
end
examplefile:write("\n")
examplefile:write"\\documentclass{article}\n"
examplefile:write"\\usepackage{fp,pgf,tikz,xcolor}\n"
examplefile:write(preamble)
examplefile:write"\\begin{document}\n"
examplefile:write"\\makeatletter\n" -- TODO: this has to go
examplefile:write(setup_code)
examplefile:write(options["pre"] and options["pre"] .. "\n" or "")
if options["render instead"] then
examplefile:write(options["render instead"] .. "\n")
else
examplefile:write(strip(content) .. "\n")
end
examplefile:write("===Content===\n")
examplefile:write(strip(content))
examplefile:write(options["post"] and options["post"] .. "\n" or "")
examplefile:write"\\end{document}\n"

examplefile:close()
end
Expand Down

0 comments on commit 710bd7f

Please sign in to comment.