summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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"}
+ }
+ }
}