From 710bd7fceaa8735fc3c0fb42e509dd919308cb0d Mon Sep 17 00:00:00 2001 From: Henri Menke Date: Thu, 25 Apr 2019 16:43:43 +1200 Subject: [PATCH] Produce compilable examples from extract.lua #640 --- doc/generic/pgf/extract.lua | 76 +++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/doc/generic/pgf/extract.lua b/doc/generic/pgf/extract.lua index e5ab08975..8b88092ac 100644 --- a/doc/generic/pgf/extract.lua +++ b/doc/generic/pgf/extract.lua @@ -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 @@ -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, @@ -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] .. " ") + 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