summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberto Sartori <alberto.sartori@huawei.com>2022-12-06 10:52:47 +0100
committerKlaus Aehlig <aehlig@linta.de>2022-12-09 11:54:42 +0100
commit418c90a02d13a2dd05bd604250ff8da889e1ef86 (patch)
tree77f88e72e6f3ea2f259de88021437af6b1bbdd74
parent3381cd924d28e29abf318235e8827e4f71997b25 (diff)
downloadrules-typesetting-418c90a02d13a2dd05bd604250ff8da889e1ef86.tar.gz
add latexmk rule...
...the main improvement wrt to standalone rule is the usage of latexmk, which automatically runs latex the right number of times, and, if needed, can call bibtex as well. Co-authored-by: Oliver Reiche <oliver.reiche@huawei.com>
-rw-r--r--README.md5
-rw-r--r--latex/EXPRESSIONS211
-rw-r--r--latex/RULES261
3 files changed, 314 insertions, 163 deletions
diff --git a/README.md b/README.md
index 83c2fae..5e52412 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,11 @@ A collection of rules related to typesetting.
a single `eps` file by replacing the definition of `stage` and
`drawbb`. While not strictly related to latex, usually used
for "animated" diagrams in slides.
+ - `["latex", "latexmk"]` Simple rule to call `latexmk`, given a
+ collection of source files and the entry point. The main
+ difference with respect to `standalone` is given by the usage of
+ `latexmk` itself, which runs `latex` the needed number of times
+ eventually calling `bibtex` as well.
- Pandoc
- `["pandoc", "standalone"]` Generate a single output file from
a given list of files in order and a template.
diff --git a/latex/EXPRESSIONS b/latex/EXPRESSIONS
new file mode 100644
index 0000000..640f587
--- /dev/null
+++ b/latex/EXPRESSIONS
@@ -0,0 +1,211 @@
+{ "call latex":
+ { "vars":
+ [ "srcs"
+ , "main"
+ , "deps"
+ , "stage"
+ , "env"
+ , "executable"
+ , "runner"
+ , "runner type"
+ , "opts"
+ , "output file extension"
+ ]
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "stage"
+ , { "type": "join"
+ , "separator": "/"
+ , "$1": {"type": "var", "name": "stage"}
+ }
+ ]
+ , [ "srcs"
+ , { "type": "disjoint_map_union"
+ , "msg": "Sources may not conflict"
+ , "$1":
+ { "type": "foreach"
+ , "var": "x"
+ , "range": {"type": "var", "name": "srcs"}
+ , "body":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "x"}}
+ , { "type": "DEP_ARTIFACTS"
+ , "dep": {"type": "var", "name": "x"}
+ }
+ ]
+ }
+ }
+ }
+ ]
+ , [ "main"
+ , { "type": "assert_non_empty"
+ , "msg": "Entry-point main cannot be empty"
+ , "$1": {"type": "join", "$1": {"type": "var", "name": "main"}}
+ }
+ ]
+ , [ "_"
+ , { "type": "if"
+ , "cond":
+ { "type": "=="
+ , "$1":
+ { "type": "lookup"
+ , "map": {"type": "var", "name": "srcs"}
+ , "key":
+ { "type": "join"
+ , "$1": [{"type": "var", "name": "main"}, ".tex"]
+ }
+ }
+ , "$2": null
+ }
+ , "then":
+ { "type": "fail"
+ , "msg":
+ [ "main not the base name of a .tex file in srcs"
+ , "main has value"
+ , {"type": "var", "name": "main"}
+ , "srcs have file names"
+ , {"type": "keys", "$1": {"type": "var", "name": "srcs"}}
+ ]
+ }
+ }
+ ]
+ , [ "main"
+ , { "type": "if"
+ , "cond":
+ {"type": "==", "$1": {"type": "var", "name": "stage"}, "$2": ""}
+ , "then": {"type": "var", "name": "main"}
+ , "else":
+ { "type": "join"
+ , "separator": "/"
+ , "$1":
+ [ {"type": "var", "name": "stage"}
+ , {"type": "var", "name": "main"}
+ ]
+ }
+ }
+ ]
+ , [ "srcs"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1": {"type": "var", "name": "srcs"}
+ }
+ ]
+ , [ "deps"
+ , { "type": "disjoint_map_union"
+ , "msg": "Dependencies may not conflict"
+ , "$1":
+ { "type": "foreach"
+ , "var": "x"
+ , "range": {"type": "var", "name": "deps"}
+ , "body":
+ {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "x"}}
+ }
+ }
+ ]
+ , [ "tex inputs"
+ , { "type": "to_subdir"
+ , "subdir": "work"
+ , "$1":
+ { "type": "disjoint_map_union"
+ , "msg": "Staging conflict between staged sources and deps"
+ , "$1":
+ [ {"type": "var", "name": "deps"}
+ , {"type": "var", "name": "srcs"}
+ ]
+ }
+ }
+ ]
+ , [ "env"
+ , { "type": "map_union"
+ , "$1":
+ [ { "type": "singleton_map"
+ , "key": "PATH"
+ , "value": "/bin:/usr/bin:/usr/local/bin"
+ }
+ , { "type": "singleton_map"
+ , "key": "SOURCE_DATE_EPOCH"
+ , "value": "0"
+ }
+ , {"type": "var", "name": "env"}
+ ]
+ }
+ ]
+ , [ "cmd"
+ , { "type": "if"
+ , "cond":
+ { "type": "=="
+ , "$1": {"type": "var", "name": "runner type"}
+ , "$2": "latexmk"
+ }
+ , "then":
+ { "type": "++"
+ , "$1":
+ [ ["sh", "runner"]
+ , [{"type": "var", "name": "executable"}]
+ , [{"type": "var", "name": "main"}]
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "opts"}
+ , "then": {"type": "var", "name": "opts"}
+ , "else": ["-pdf"]
+ }
+ ]
+ }
+ , "else":
+ [ "./runner"
+ , {"type": "var", "name": "executable"}
+ , {"type": "var", "name": "main"}
+ ]
+ }
+ ]
+ , [ "output file"
+ , { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "tex inputs"}
+ , {"type": "var", "name": "runner"}
+ ]
+ }
+ , "outs":
+ [ { "type": "join"
+ , "$1":
+ [ "work/"
+ , {"type": "var", "name": "main"}
+ , { "type": "join"
+ , "separator": ""
+ , "$1": {"type": "var", "name": "output file extension"}
+ }
+ ]
+ }
+ ]
+ , "cmd": {"type": "var", "name": "cmd"}
+ , "env": {"type": "var", "name": "env"}
+ }
+ ]
+ , [ "output file"
+ , { "type": "map_union"
+ , "$1":
+ { "type": "foreach_map"
+ , "var_key": "name"
+ , "var_val": "file"
+ , "range": {"type": "var", "name": "output file"}
+ , "body":
+ { "type": "singleton_map"
+ , "key":
+ {"type": "basename", "$1": {"type": "var", "name": "name"}}
+ , "value": {"type": "var", "name": "file"}
+ }
+ }
+ }
+ ]
+ ]
+ , "body":
+ { "type": "RESULT"
+ , "artifacts": {"type": "var", "name": "output file"}
+ , "runfiles": {"type": "var", "name": "output file"}
+ }
+ }
+ }
+}
diff --git a/latex/RULES b/latex/RULES
index 89683a9..ec4c9cd 100644
--- a/latex/RULES
+++ b/latex/RULES
@@ -20,7 +20,7 @@
, "of a .tex file in \"srcs\"; the \"stage\" is prepended automatically."
]
}
- , "config_fields": ["env", "latex"]
+ , "config_vars": ["env", "latex"]
, "config_doc":
{ "latex": ["Name of the latex command, defaults to \"pdflatex\"."]
, "env":
@@ -29,180 +29,31 @@
]
}
, "implicit": {"runner": ["latex_runner.sh"]}
- , "imports": {"singleton": ["./", "..", "stage_singleton_field"]}
+ , "imports":
+ { "singleton": ["./", "..", "stage_singleton_field"]
+ , "call latex": "call latex"
+ }
, "expression":
{ "type": "let*"
, "bindings":
- [ [ "stage"
- , { "type": "join"
- , "separator": "/"
- , "$1": {"type": "FIELD", "name": "stage"}
- }
- ]
- , [ "srcs"
- , { "type": "disjoint_map_union"
- , "msg": "Sources may not conflict"
- , "$1":
- { "type": "foreach"
- , "var": "x"
- , "range": {"type": "FIELD", "name": "srcs"}
- , "body":
- { "type": "map_union"
- , "$1":
- [ {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "x"}}
- , { "type": "DEP_ARTIFACTS"
- , "dep": {"type": "var", "name": "x"}
- }
- ]
- }
- }
- }
- ]
- , [ "main"
- , { "type": "assert_non_empty"
- , "msg": "Entry-point main cannot be empty"
- , "$1": {"type": "join", "$1": {"type": "FIELD", "name": "main"}}
- }
- ]
- , [ "_"
- , { "type": "if"
- , "cond":
- { "type": "=="
- , "$1":
- { "type": "lookup"
- , "map": {"type": "var", "name": "srcs"}
- , "key":
- { "type": "join"
- , "$1": [{"type": "var", "name": "main"}, ".tex"]
- }
- }
- , "$2": null
- }
- , "then":
- { "type": "fail"
- , "msg":
- [ "main not the base name of a .tex file in srcs"
- , "main has value"
- , {"type": "var", "name": "main"}
- , "srcs have file names"
- , {"type": "keys", "$1": {"type": "var", "name": "srcs"}}
- ]
- }
- }
- ]
- , [ "main"
- , { "type": "if"
- , "cond":
- {"type": "==", "$1": {"type": "var", "name": "stage"}, "$2": ""}
- , "then": {"type": "var", "name": "main"}
- , "else":
- { "type": "join"
- , "separator": "/"
- , "$1":
- [ {"type": "var", "name": "stage"}
- , {"type": "var", "name": "main"}
- ]
- }
- }
- ]
- , [ "srcs"
- , { "type": "to_subdir"
- , "subdir": {"type": "var", "name": "stage"}
- , "$1": {"type": "var", "name": "srcs"}
- }
- ]
- , [ "deps"
- , { "type": "disjoint_map_union"
- , "msg": "Dependencies may not conflict"
- , "$1":
- { "type": "foreach"
- , "var": "x"
- , "range": {"type": "FIELD", "name": "deps"}
- , "body":
- {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "x"}}
- }
- }
- ]
- , [ "tex inputs"
- , { "type": "to_subdir"
- , "subdir": "work"
- , "$1":
- { "type": "disjoint_map_union"
- , "msg": "Staging conflict between staged sources and deps"
- , "$1":
- [ {"type": "var", "name": "deps"}
- , {"type": "var", "name": "srcs"}
- ]
- }
- }
- ]
+ [ ["srcs", {"type": "FIELD", "name": "srcs"}]
+ , ["main", {"type": "FIELD", "name": "main"}]
+ , ["deps", {"type": "FIELD", "name": "deps"}]
+ , ["stage", {"type": "FIELD", "name": "stage"}]
+ , ["output file extension", [".pdf"]]
, [ "env"
- , { "type": "map_union"
- , "$1":
- [ { "type": "singleton_map"
- , "key": "PATH"
- , "value": "/bin:/usr/bin:/usr/local/bin"
- }
- , { "type": "singleton_map"
- , "key": "SOURCE_DATE_EPOCH"
- , "value": "0"
- }
- , {"type": "var", "name": "env", "default": {"type": "empty_map"}}
- ]
- }
+ , {"type": "var", "name": "env", "default": {"type": "empty_map"}}
]
+ , ["executable", {"type": "var", "name": "latex", "default": "pdflatex"}]
, [ "runner"
, { "type": "let*"
, "bindings": [["fieldname", "runner"], ["location", "runner"]]
, "body": {"type": "CALL_EXPRESSION", "name": "singleton"}
}
]
- , [ "cmd"
- , [ "./runner"
- , {"type": "var", "name": "latex", "default": "pdflatex"}
- , {"type": "var", "name": "main"}
- ]
- ]
- , [ "pdf"
- , { "type": "ACTION"
- , "inputs":
- { "type": "map_union"
- , "$1":
- [ {"type": "var", "name": "tex inputs"}
- , {"type": "var", "name": "runner"}
- ]
- }
- , "outs":
- [ { "type": "join"
- , "$1": ["work/", {"type": "var", "name": "main"}, ".pdf"]
- }
- ]
- , "cmd": {"type": "var", "name": "cmd"}
- , "env": {"type": "var", "name": "env"}
- }
- ]
- , [ "pdf"
- , { "type": "map_union"
- , "$1":
- { "type": "foreach_map"
- , "var_key": "name"
- , "var_val": "file"
- , "range": {"type": "var", "name": "pdf"}
- , "body":
- { "type": "singleton_map"
- , "key":
- {"type": "basename", "$1": {"type": "var", "name": "name"}}
- , "value": {"type": "var", "name": "file"}
- }
- }
- }
- ]
+ , ["runner type", "standalone"]
]
- , "body":
- { "type": "RESULT"
- , "artifacts": {"type": "var", "name": "pdf"}
- , "runfiles": {"type": "var", "name": "pdf"}
- }
+ , "body": {"type": "CALL_EXPRESSION", "name": "call latex"}
}
}
, "verbatim":
@@ -311,4 +162,88 @@
}
}
}
+, "latexmk":
+ { "doc":
+ [ "A latexmk run"
+ , ""
+ , "Call latexmk passing main as the entry point. A correct staging"
+ , "of the needed files has to be given through the runfiles of \"deps\"."
+ ]
+ , "target_fields": ["deps", "srcs"]
+ , "string_fields": ["main", "stage", "opts", "output extension"]
+ , "field_doc":
+ { "srcs": ["The files needed for the latexmk run."]
+ , "stage":
+ [ "The directory the \"srcs\" logically reside in."
+ , "Entries are joined with \"/\"."
+ ]
+ , "deps":
+ ["Runfiles needed for the run of the standalone latex invocation"]
+ , "main":
+ [ "The entry point for the latex run; should be the base name"
+ , "of a .tex file in \"srcs\"; the \"stage\" is prepended automatically."
+ ]
+ , "opts":
+ ["The latexmk options to be used.", "If omitted, \"-pdf\" is assumed"]
+ , "output extension":
+ [ "The extension of the output to be produced (e.g., \".ps\", \".pdf\")."
+ , "If omitted, \".pdf\" is assumed."
+ ]
+ }
+ , "config_vars": ["env", "latexmk"]
+ , "config_doc":
+ { "env":
+ [ "Any override to the default environment which sets only"
+ , "PATH and SOURCE_DATE_EPOCH"
+ ]
+ , "latexmk": ["Name of the latexmk command, defaults to \"latexmk\"."]
+ }
+ , "imports": {"call latex": "call latex"}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["srcs", {"type": "FIELD", "name": "srcs"}]
+ , ["main", {"type": "FIELD", "name": "main"}]
+ , ["deps", {"type": "FIELD", "name": "deps"}]
+ , ["stage", {"type": "FIELD", "name": "stage"}]
+ , [ "output file extension"
+ , { "type": "if"
+ , "cond": {"type": "FIELD", "name": "output extension"}
+ , "then": {"type": "FIELD", "name": "output extension"}
+ , "else": [".pdf"]
+ }
+ ]
+ , [ "env"
+ , {"type": "var", "name": "env", "default": {"type": "empty_map"}}
+ ]
+ , [ "executable"
+ , {"type": "var", "name": "latexmk", "default": "latexmk"}
+ ]
+ , ["opts", {"type": "FIELD", "name": "opts"}]
+ , [ "runner"
+ , { "type": "singleton_map"
+ , "key": "runner"
+ , "value":
+ { "type": "BLOB"
+ , "data":
+ { "type": "join"
+ , "separator": "\n"
+ , "$1":
+ [ "set -e"
+ , "LATEXMK=\"$1\""
+ , "shift"
+ , "MAIN=\"$1\""
+ , "shift"
+ , "cd work"
+ , "\"$LATEXMK\" -output-directory=\"$(dirname \"$MAIN\")\" \"$@\" \"$MAIN\" > log 2>&1 || (cat log && exit 1)"
+ ]
+ }
+ }
+ }
+ ]
+ , ["runner type", "latexmk"]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "call latex"}
+ }
+ }
}