Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explicit \use command #1482

Merged
merged 34 commits into from
Jul 28, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
aa996d2
chore(manual): Change autodoc function to use content rather than arg
alerque Jul 19, 2022
3ad3de9
chore(classes): Change 'module' to 'require' to clarify \lua usage
alerque Jul 19, 2022
eb298c3
feat(classes): Add \use command to help deconflate \script usage
alerque Jul 19, 2022
b2d8ad7
docs(manual): Dogfood new \use command
alerque Jul 19, 2022
073a03e
Merge branch 'master' into package-command
alerque Jul 22, 2022
3144383
docs(manual): Update package usage bits
alerque Jul 22, 2022
451f083
chore(tests): Use new \use command throughout
alerque Jul 22, 2022
50a0619
refactor(core): Redo \use usage and add SILE.use() to be more consistent
alerque Jul 23, 2022
d76953f
docs(manpage): Update man page for current usage
alerque Jul 23, 2022
2411328
feat(cli): Change --require to --use to match declarative markup
alerque Jul 23, 2022
27e0e1b
docs(manual): Update book with new CLI usage
alerque Jul 23, 2022
e34ab9b
Merge branch 'master' into package-command
alerque Jul 23, 2022
6fab054
chore(core): Update to current \use usage throughout
alerque Jul 23, 2022
16b8900
fix(utilities): Correct traceback output for SILE.error() to show par…
alerque Jul 23, 2022
31be0c9
chore(classes): Use plain require() for \lua[require=foo.bar]
alerque Jul 24, 2022
bd06191
chore(classes): Normalize processing priority across input related co…
alerque Jul 24, 2022
0d530a5
fix(cli): Avoid throwing extra error on error without message
alerque Jul 26, 2022
e64ce0f
feat(core): Add ability to pass args to modules via \use and other co…
alerque Jul 26, 2022
1b9009f
feat(inputters): Allow CLI to mandate inputter used for master document
alerque Jul 26, 2022
9e54bad
feat(core): Add ability to pass args to modules via \use and other co…
alerque Jul 26, 2022
e1aa4e2
refactor(shapers): Use module naming that is easier to search for sim…
alerque Jul 27, 2022
8f97a73
refactor(inputters): Use module naming that is easier to search for s…
alerque Jul 27, 2022
54cb62f
refactor(outputters): Use module naming that is easier to search for …
alerque Jul 27, 2022
c67c2be
refactor(classes): Use module naming that is easier to search for sim…
alerque Jul 27, 2022
09303f8
chore(classes): Remove more traces of deprecation shims, followup c42…
alerque Jul 27, 2022
6406acb
refactor(packages): Drop class arg on package constructor, normalize …
alerque Jul 27, 2022
3fd4891
refactor(packages): Stick with 'options' not 'args' terminology
alerque Jul 27, 2022
ab106bb
test(inputters): Add test for passing options to inputter
alerque Jul 26, 2022
1f2a297
chore(classes): Simplify package loading with options instead of regi…
alerque Jul 27, 2022
43e682c
refactor(packages): Use module naming that is easier to search for si…
alerque Jul 27, 2022
4b44e01
chore(packages): Work aruond cart-horse problem instantiating package…
alerque Jul 27, 2022
63e3a3e
chore(classes): Drop unused return code handled by Penlight constructor
alerque Jul 28, 2022
4cdcae7
feat(cli): Allow passing options to any modules specified from --use
alerque Jul 28, 2022
8e30d0b
docs(manpage): Document possing module options from CLI
alerque Jul 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 38 additions & 13 deletions classes/base.lua
Original file line number Diff line number Diff line change
Expand Up @@ -298,46 +298,71 @@ function base:registerCommands ()
end, "Within a macro definition, processes the contents of the macro body.")

self:registerCommand("script", function (options, content)
if options.src then
if SU.hasContent(content) then
SILE.processString(content[1], options.format or "lua")
elseif options.src then
SILE.require(options.src)
else
SILE.processString(content[1], options.format or "lua")
SU.error("\\script funcion requires inline content or a src file path")
end
end, "Runs lua code. The code may be supplied either inline or using src=...")

self:registerCommand("include", function (options, content)
if options.src then
if SU.hasContent(content) then
SILE.processString(content[1], options.format)
elseif options.src then
SILE.processFile(options.src, options.format)
else
SILE.processString(content[1], options.format)
SU.error("\\include funcion requires inline content or a src file path")
end
end, "Includes a content file for processing.")

self:registerCommand("lua", function (options, content)
if options.module then
SILE.require(options.module)
if SU.hasContent(content) then
SILE.processString(content[1], "lua")
elseif options.src then
SILE.processFile(options.src, "lua")
elseif options.require then
local module = SU.required(options, "require", "lua")
return require(module)
else
SILE.processString(content[1], "lua")
SU.error("\\lua funcion requires inline content or a src file path or a require module name")
end
end, "Run Lua code. The code may be supplied either inline or using src=...")
end, "Run Lua code. The code may be supplied either inline, using require=... for a Lua module, or using src=... for a file path")

self:registerCommand("sil", function (options, content)
if options.src then
if SU.hasContent(content) then
SILE.processString(content[1], "sil")
elseif options.src then
SILE.processFile(options.src, "sil")
else
SILE.processString(content[1], "sil")
SU.error("\\sil funcion requires inline content or a src file path")
end
end, "Process sil content. The content may be supplied either inline or using src=...")

self:registerCommand("xml", function (options, content)
if options.src then
if SU.hasContent(content) then
SILE.processString(content[1], "xml")
elseif options.src then
SILE.processFile(options.src, "xml")
else
SILE.processString(content[1], "xml")
SU.error("\\xml funcion requires inline content or a src file path")
end
end, "Process xml content. The content may be supplied either inline or using src=...")

self:registerCommand("use", function (options, content)
if content[1] and string.len(content[1]) > 0 then
SILE.processString(content[1], "lua")
else
if options.src then
SU.warn("Use of 'src' with \\use is discouraged because some of it's path handling\n will eventually be deprecated. Use 'module' instead when possible.")
SILE.processFile(options.src, "lua")
else
local module = SU.required(options, "module", "use")
SILE.use(module)
end
end
end, "Run xml content. The content may be supplied either inline or using src=...")
end, "Load and initialize a SILE module (can be a package, a shaper, a typesetter, or whatever). Use module=... to specif what to load or include module code inline.")

self:registerCommand("raw", function (options, content)
local rawtype = SU.required(options, "type", "raw")
Expand Down
14 changes: 7 additions & 7 deletions core/cli.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ cli.parseArguments = function ()
cliargs:option("-e, --evaluate=VALUE", "evaluate Lua expression before processing input", {})
cliargs:option("-E, --evaluate-after=VALUE", "evaluate Lua expression after processing input", {})
cliargs:option("-f, --fontmanager=VALUE", "choose an alternative font manager")
cliargs:option("-I, --include=FILE", "deprecated, see --use, --preamble, or --postamble", {})
cliargs:option("-m, --makedeps=FILE", "generate a list of dependencies in Makefile format")
cliargs:option("-o, --output=FILE", "explicitly set output file name")
cliargs:option("-O, --options=PARAMETER=VALUE", "set document class options", {})
cliargs:option("-I, --include=FILE", "deprecated, see --require, --preamble, or --postamble", {})
cliargs:option("-r, --require=MODULE", "require a resource to be loaded before processing input", {})
cliargs:option("-p, --preamble=FILE", "include an SIL, XML, or other content before the input document", {})
cliargs:option("-P, --postamble=FILE", "include an SIL, XML, or other content after the input document", {})
cliargs:option("-p, --preamble=FILE", "process SIL, XML, or other content before the input document", {})
cliargs:option("-P, --postamble=FILE", "process SIL, XML, or other content after the input document", {})
cliargs:option("-u, --use=MODULE", "load and initialize a module before processing input", {})
cliargs:flag("-t, --traceback", "display detailed location trace on errors and warnings")
cliargs:flag("-h, --help", "display this help, then exit")
cliargs:flag("-v, --version", "display version information, then exit", print_version)
Expand Down Expand Up @@ -85,8 +85,8 @@ cli.parseArguments = function ()
local options = parameters:match(option)
pl.tablex.merge(SILE.input.options, options, true)
end
for _, path in ipairs(opts.require) do
table.insert(SILE.input.requires, path)
for _, path in ipairs(opts.use) do
table.insert(SILE.input.uses, path)
end
for _, path in ipairs(opts.preamble) do
table.insert(SILE.input.preambles, path)
Expand All @@ -95,7 +95,7 @@ cli.parseArguments = function ()
table.insert(SILE.input.postambles, path)
end
for _, path in ipairs(opts.include) do
SU.deprecated("-I/--include", "-r/--require or -p/--preamble", "0.14.0", "0.15.0")
SU.deprecated("-I/--include", "-u/--use or -p/--preamble", "0.14.0", "0.15.0")
table.insert(SILE.input.includes, path)
end
-- http://lua-users.org/wiki/VarargTheSecondClassCitizen
Expand Down
46 changes: 43 additions & 3 deletions core/sile.lua
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ SILE.input = {
evaluates = {},
evaluateAfters = {},
includes = {},
requires = {},
uses = {},
options = {},
preambles = {},
postambles = {},
Expand Down Expand Up @@ -135,6 +135,46 @@ SILE.init = function ()
runEvals(SILE.input.evaluates, "evaluate")
end

SILE.use = function (module)
local pack
if type(module) == "string" then
pack = require(module)
elseif type(module) == "table" then
pack = module
end
local name = pack._name
local class = SILE.documentState.documentClass
if not pack.type then
SU.error("Modules must declare their type")
elseif pack.type == "class" then
SILE.classes[name] = pack
if class then
SU.error("Cannot load a class after one is already instantiated")
end
SILE.sratch.class_from_uses = pack
elseif pack.type == "inputter" then
SILE.inputters[name] = pack
-- nothing more to instantiate for inputters because format detection uses
-- all available modules, order is designated by the inputter module itself.
elseif pack.type == "outputter" then
SILE.outputters[name] = pack
SILE.outputter = pack()
elseif pack.type == "shaper" then
SILE.shapers[name] = pack
SILE.shaper = pack()
elseif pack.type == "typesetter" then
SILE.typesetters[name] = pack
SILE.typesetter = pack()
elseif pack.type == "package" then
SILE.packages[name] = pack
if class then
pack(class)
else
table.insert(SILE.inputs.preambles, pack)
end
end
end

SILE.require = function (dependency, pathprefix, deprecation_ack)
if pathprefix and not deprecation_ack then
local notice = string.format([[
Expand Down Expand Up @@ -195,12 +235,12 @@ SILE.process = function (ast)
end
end

local defaultinputters = { "xml", "lua", "sil" }
local preloadedinputters = { "xml", "lua", "sil" }

local function detectFormat (doc, filename)
-- Preload default reader types so content detection has something to work with
if #SILE.inputters == 0 then
for _, format in ipairs(defaultinputters) do
for _, format in ipairs(preloadedinputters) do
local _ = SILE.inputters[format]
end
end
Expand Down
6 changes: 5 additions & 1 deletion core/utilities.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ utilities.boolean = function (value, default)
return default
end

local _skip_traceback_levels = 2

utilities.error = function(message, bug)
_skip_traceback_levels = 3
utilities.warn(message, bug)
_skip_traceback_levels = 2
io.stderr:flush()
SILE.outputter:finish() -- Only really useful from the REPL but no harm in trying
error(nil, 2)
Expand All @@ -38,7 +42,7 @@ utilities.warn = function(message, bug)
io.stderr:write("\n! " .. message)
if SILE.traceback or bug then
io.stderr:write(" at:\n" .. SILE.traceStack:locationTrace())
io.stderr:write(debug.traceback(nil, 2) or "\t! debug.traceback() did not identify code location")
io.stderr:write(debug.traceback(nil, _skip_traceback_levels) or "\t! debug.traceback() did not identify code location")
else
io.stderr:write(" at " .. SILE.traceStack:locationHead())
end
Expand Down
39 changes: 19 additions & 20 deletions documentation/c02-gettingstarted.sil
Original file line number Diff line number Diff line change
Expand Up @@ -282,47 +282,46 @@ You may download these executables by selecting the latest build from \url{https

\section{Running SILE}

Let’s move to a new directory, and in a text editor, create the file
\code{hello.sil}. Copy in the content above and save the file. Now at your
command line run:
Let’s move to a new directory, and in a text editor, create the file \code{hello.sil}.
Copy in the content above and save the file.
Now at your command line run:

\terminal{$ sile hello.sil}

Once again, this should produce an output file \code{hello.pdf}.
Congratulations—you have just typeset your first document with SILE!

\note{SILE output filenames are generated by filing off the extension from
the first input filename and adding \code{.pdf}. If you want to write to
a different filename altogether, use the \code{-o file.pdf} command line
option to SILE. You can use \code{-o -} to write the PDF to standard output,
if you wish to use SILE as part of a pipeline.}
All the available CLI options are documented both in the help output (run \code{sile --help}) and in the man page (run \code{man sile}).
This manual will only mention a few in passing as they come up in other other topics.

\begin{note}
SILE output filenames are generated by filing off the extension from the master input filename and adding the proper extension for the outputter.
For most outputters this will be \code{.pdf} but for example the text backend will append \code{txt} instead.
If you want to write to a different filename altogether, use the \code{--output file.pdf} command line option.
You can use \code{--output -} to write the output directly to the system IO stream—useful if you wish to use SILE as part of a pipeline.
\end{note}

\section{Let’s Do Something Cool}

In \url{https://sile-typesetter.org/examples/docbook.xml}, you will find a typical DocBook 5.0
article. Normally turning DocBook to print involves a curious dance of XSLT
processors, format object processors and/or strange LaTeX packages. But SILE
can read XML files and it also comes with a \code{docbook} class, which tells
SILE how to render (admittedly, a subset of) the DocBook tags onto a page.
In \url{https://sile-typesetter.org/examples/docbook.xml}, you will find a typical DocBook 5.0 article.
Normally turning DocBook to print involves a curious dance of XSLT processors, format object processors and/or strange LaTeX packages.
But SILE can read XML files and it also comes with a \code{docbook} class, which tells SILE how to render (admittedly, a subset of) the DocBook tags onto a page.

Turning \code{dockbook.xml} into \code{docbook.pdf} is now as simple as:

\begin{verbatim}
\line
$ ./sile -I docbook.sil docbook.xml
$ ./sile --class docbook docbook.xml
\sileversion
Loading docbook
<classes/docbook.sil><docbook.xml>[1] [2] [3]
\line
\end{verbatim}

The \code{-I} flag adds a \em{preamble}, which is to say that it loads up
a \em{class} before reading the input file; the \code{docbook} preamble
provides processing expectations for DocBook tags, which means that once this
is loaded, DocBook files can be processed directly as SILE documents.
The \code{-c} flag sets the default class; a necessary step because docbook XML files do not come wrapped in a tag that specifies a SILE class.
The docbook class will provide the commands necessary to process the tags typically found in docbook files.

In Chapter 9, we’ll look at how the \code{docbook} class works, and how you
can define processing expectations for other XML formats.
In Chapter 9, we’ll look at how the \code{docbook} class works, and how you can define processing expectations for other XML formats.

\section{Running SILE remotely as a CI job}

Expand Down
Loading