diff options
-rw-r--r-- | EXPRESSIONS | 46 | ||||
-rw-r--r-- | LICENSE | 202 | ||||
-rw-r--r-- | README.md | 23 | ||||
-rw-r--r-- | files/EXPRESSIONS | 36 | ||||
-rw-r--r-- | files/RULES | 61 | ||||
-rw-r--r-- | latex/RULES | 314 | ||||
-rw-r--r-- | latex/TARGETS | 1 | ||||
-rwxr-xr-x | latex/latex_runner.sh | 17 | ||||
-rw-r--r-- | pandoc/RULES | 404 | ||||
-rw-r--r-- | pandoc/TARGETS | 1 | ||||
-rw-r--r-- | ps/RULES | 122 |
11 files changed, 1227 insertions, 0 deletions
diff --git a/EXPRESSIONS b/EXPRESSIONS new file mode 100644 index 0000000..f1ca6f4 --- /dev/null +++ b/EXPRESSIONS @@ -0,0 +1,46 @@ +{ "stage_singleton_field": + { "vars": ["fieldname", "transition", "location"] + , "expression": + { "type": "assert_non_empty" + , "msg": + ["No artifact specified in field", {"type": "var", "name": "fieldname"}] + , "$1": + { "type": "disjoint_map_union" + , "msg": + [ "Expecting (essentially) a single artifact in field" + , {"type": "var", "name": "fieldname"} + ] + , "$1": + { "type": "foreach" + , "var": "src" + , "range": + {"type": "FIELD", "name": {"type": "var", "name": "fieldname"}} + , "body": + { "type": "disjoint_map_union" + , "$1": + { "type": "foreach" + , "var": "artifact" + , "range": + { "type": "values" + , "$1": + { "type": "DEP_ARTIFACTS" + , "dep": {"type": "var", "name": "src"} + , "transition": + { "type": "var" + , "name": "transition" + , "default": {"type": "empty_map"} + } + } + } + , "body": + { "type": "singleton_map" + , "key": {"type": "var", "name": "location"} + , "value": {"type": "var", "name": "artifact"} + } + } + } + } + } + } + } +} @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..83c2fae --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# Typesetting rules for the `just` build system + +A collection of rules related to typesetting. + +- Latex + - `["latex", "standalone"]` Simple rule to generate a `pdf` file, + given a collection of source files and the entry point. + - `["latex", "verbatim"]` Auxiliary target to wrap a file in a + `verbatim` environment. Useful if the source file is generated, + e.g., a sample run of a tool under development. + - `["ps", "family"]` Generate a collection of `eps` files from + 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. +- Pandoc + - `["pandoc", "standalone"]` Generate a single output file from + a given list of files in order and a template. + - `["pandoc", "template"]` Specify a template for pandoc by + specifying additional arguments and files for a pandoc invocation. + - `["files", "ordered"]` Specify a list of files in order. In + this way, a sequence of files can be specified in a single + place, even so it is used in different pandoc targets, e.g., + to render with different templates. diff --git a/files/EXPRESSIONS b/files/EXPRESSIONS new file mode 100644 index 0000000..7a418c4 --- /dev/null +++ b/files/EXPRESSIONS @@ -0,0 +1,36 @@ +{ "order": + { "expression": + { "type": "++" + , "$1": + { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "srcs"} + , "body": + { "type": "if" + , "cond": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "dep"} + , "provider": "keys" + } + , "then": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "dep"} + , "provider": "keys" + } + , "else": + { "type": "keys" + , "$1": + { "type": "map_union" + , "$1": + [ {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "dep"}} + , { "type": "DEP_ARTIFACTS" + , "dep": {"type": "var", "name": "dep"} + } + ] + } + } + } + } + } + } +} diff --git a/files/RULES b/files/RULES new file mode 100644 index 0000000..891ff55 --- /dev/null +++ b/files/RULES @@ -0,0 +1,61 @@ +{ "ordered": + { "doc": + [ "Collect the runfiles and artifacts of the \"srcs\" targets, keeping" + , "record of the order of the targets (in a provider). In this way," + , "a sequence of files can be described at a single place and used later" + , "in several targets where order matters and the respective provider is" + , "supported. As this rule supports its own provider, chaining is possible." + ] + , "target_fields": ["srcs"] + , "field_doc": + { "srcs": + [ "The files to include, in order. For targets that are defined by this" + , "rule, the provided order in honored." + ] + } + , "artifacts_doc": + [ "The runfiles and artifacts of the \"srcs\" field." + , "Within each target, artifacts take precedence; different targets in" + , "the \"srcs\" field may not conflict" + ] + , "runfiles_doc": ["Same as artifacts"] + , "provides_doc": + {"keys": ["The keys of the artifacts in the intended order."]} + , "imports": {"order": "order"} + , "expression": + { "type": "let*" + , "bindings": + [ [ "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"} + } + ] + } + } + } + ] + , ["order", {"type": "CALL_EXPRESSION", "name": "order"}] + ] + , "body": + { "type": "RESULT" + , "runfiles": {"type": "var", "name": "srcs"} + , "artifacts": {"type": "var", "name": "srcs"} + , "provides": + { "type": "singleton_map" + , "key": "keys" + , "value": {"type": "var", "name": "order"} + } + } + } + } +} diff --git a/latex/RULES b/latex/RULES new file mode 100644 index 0000000..89683a9 --- /dev/null +++ b/latex/RULES @@ -0,0 +1,314 @@ +{ "standalone": + { "doc": + [ "A standalone latex run" + , "" + , "Define a pdf file as the output of running pdflatex. A correct staging" + , "of the needed files has to be given through the runfiles of \"deps\"." + ] + , "target_fields": ["deps", "srcs"] + , "string_fields": ["main", "stage"] + , "field_doc": + { "srcs": ["The files needed for the latex 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." + ] + } + , "config_fields": ["env", "latex"] + , "config_doc": + { "latex": ["Name of the latex command, defaults to \"pdflatex\"."] + , "env": + [ "Any override to the default environment which sets only" + , "PATH and SOURCE_DATE_EPOCH" + ] + } + , "implicit": {"runner": ["latex_runner.sh"]} + , "imports": {"singleton": ["./", "..", "stage_singleton_field"]} + , "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"} + ] + } + } + ] + , [ "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"}} + ] + } + ] + , [ "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"} + } + } + } + ] + ] + , "body": + { "type": "RESULT" + , "artifacts": {"type": "var", "name": "pdf"} + , "runfiles": {"type": "var", "name": "pdf"} + } + } + } +, "verbatim": + { "doc": ["Add \\begin{verbatim}...\\end{verbatim} around files"] + , "target_fields": ["srcs"] + , "string_fields": ["prefix", "stage"] + , "field_doc": + { "srcs": + [ "The files to transform to tex files containing them verbatim." + , "In the output file, the ending is changed to .tex" + ] + , "prefix": ["Additional prefix to add to the output file name"] + , "stage": ["The logical directory to stage the outputs to"] + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "srcs" + , { "type": "disjoint_map_union" + , "msg": "Source files must not overlap, as this would lead to overlapping output" + , "$1": + { "type": "foreach" + , "var": "src" + , "range": {"type": "FIELD", "name": "srcs"} + , "body": + {"type": "DEP_ARTIFACTS", "dep": {"type": "var", "name": "src"}} + } + } + ] + , [ "verbatim files" + , { "type": "disjoint_map_union" + , "msg": + [ "Outputfiles must not overlap" + , "Input file names:" + , {"type": "keys", "map": {"type": "var", "name": "srcs"}} + ] + , "$1": + { "type": "foreach_map" + , "var_key": "src" + , "var_val": "input" + , "range": {"type": "var", "name": "srcs"} + , "body": + { "type": "let*" + , "bindings": + [ [ "action out" + , { "type": "ACTION" + , "inputs": + { "type": "singleton_map" + , "key": "in" + , "value": {"type": "var", "name": "input"} + } + , "outs": ["out"] + , "cmd": + [ "sh" + , "-c" + , "echo '\\\\begin{verbatim}' > out && cat in >> out && echo '\\\\end{verbatim}' >> out" + ] + } + ] + , [ "out" + , { "type": "lookup" + , "map": {"type": "var", "name": "action out"} + , "key": "out" + } + ] + , [ "out name" + , { "type": "join" + , "$1": + [ { "type": "join" + , "$1": {"type": "FIELD", "name": "prefix"} + } + , { "type": "change_ending" + , "ending": ".tex" + , "$1": {"type": "var", "name": "src"} + } + ] + } + ] + ] + , "body": + { "type": "singleton_map" + , "key": {"type": "var", "name": "out name"} + , "value": {"type": "var", "name": "out"} + } + } + } + } + ] + , [ "stage" + , { "type": "join" + , "separator": "/" + , "$1": {"type": "FIELD", "name": "stage"} + } + ] + , [ "staged verbatim files" + , { "type": "to_subdir" + , "subdir": {"type": "var", "name": "stage"} + , "$1": {"type": "var", "name": "verbatim files"} + } + ] + ] + , "body": + { "type": "RESULT" + , "artifacts": {"type": "var", "name": "staged verbatim files"} + , "runfiles": {"type": "var", "name": "staged verbatim files"} + } + } + } +} diff --git a/latex/TARGETS b/latex/TARGETS new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/latex/TARGETS @@ -0,0 +1 @@ +{} diff --git a/latex/latex_runner.sh b/latex/latex_runner.sh new file mode 100755 index 0000000..69f63cd --- /dev/null +++ b/latex/latex_runner.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +PDFLATEX=$1 +shift +MAIN=$1 +shift + +cd work +echo First latex run >> ../log +$PDFLATEX $MAIN >> ../log 2>&1 || { cat ../log ; exit 1; } +echo Second latex run >> ../log +$PDFLATEX $MAIN >> ../log 2>&1 || { cat ../log ; exit 1; } +echo Third latex run >> ../log +$PDFLATEX $MAIN >> ../log 2>&1 || { cat ../log ; exit 1; } +[ -f $MAIN.pdf ] \ + || ( [ -f $(basename $MAIN).pdf ] && cp $(basename $MAIN).pdf $MAIN.pdf ) \ + || { cat ../log ; exit 1; } diff --git a/pandoc/RULES b/pandoc/RULES new file mode 100644 index 0000000..7ce5433 --- /dev/null +++ b/pandoc/RULES @@ -0,0 +1,404 @@ +{ "template": + { "doc": ["Create a pandoc template with arguments"] + , "string_fields": ["name", "args"] + , "target_fields": ["data", "lua filters"] + , "field_doc": + { "name": ["Name of the template to use"] + , "args": ["Additional pandoc arguments"] + , "data": ["Template data files"] + , "lua filters": ["Files that should be used as lua filters"] + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "data" + , { "type": "disjoint_map_union" + , "msg": "Data files may not conflict" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "data"} + , "body": + { "type": "map_union" + , "$1": + [ {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "x"}} + , { "type": "DEP_ARTIFACTS" + , "dep": {"type": "var", "name": "x"} + } + ] + } + } + } + ] + , [ "lua filters" + , { "type": "disjoint_map_union" + , "msg": "Lua filters may not conflict" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "lua filters"} + , "body": + { "type": "map_union" + , "$1": + [ {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "x"}} + , { "type": "DEP_ARTIFACTS" + , "dep": {"type": "var", "name": "x"} + } + ] + } + } + } + ] + ] + , "body": + { "type": "RESULT" + , "artifacts": {"type": "var", "name": "data"} + , "runfiles": {"type": "var", "name": "data"} + , "provides": + { "type": "map_union" + , "$1": + [ { "type": "singleton_map" + , "key": "template-name" + , "value": + {"type": "join", "$1": {"type": "FIELD", "name": "name"}} + } + , { "type": "singleton_map" + , "key": "template-args" + , "value": {"type": "FIELD", "name": "args"} + } + , { "type": "singleton_map" + , "key": "lua filters" + , "value": {"type": "var", "name": "lua filters"} + } + ] + } + } + } + } +, "metadata": + { "doc": + ["Generate a file with meta data from data provided through context"] + , "config_vars": ["SOURCE_DATE_EPOCH", "DATE_FORMAT"] + , "config_doc": + { "SOURCE_DATE_EPOCH": + [ "The timestamp to include (in seconds since Jan 1, 1970 00:00 UTC);" + , "ignored if unset or value is 0." + ] + , "DATE_FORMAT": + ["The format to use for time stamps (defaults to \"%Y-%m-%d %H:%M\")."] + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "script" + , { "type": "join" + , "separator": "\n" + , "$1": + { "type": "++" + , "$1": + [ ["echo", "echo ---"] + , { "type": "if" + , "cond": {"type": "var", "name": "SOURCE_DATE_EPOCH"} + , "then": + [ { "type": "join_cmd" + , "$1": + [ "date" + , "-d" + , { "type": "join" + , "$1": + [ "@" + , { "type": "json_encode" + , "$1": + {"type": "var", "name": "SOURCE_DATE_EPOCH"} + } + ] + } + , { "type": "join" + , "$1": + [ "+date: \"" + , { "type": "var" + , "name": "DATE_FORMAT" + , "default": "%Y-%m-%d %H:%M" + } + , "\"" + ] + } + ] + } + ] + } + , ["echo ---", "echo\n"] + ] + } + } + ] + , [ "data" + , { "type": "ACTION" + , "cmd": ["sh", "-c", "sh ./generate > metadata.yaml"] + , "outs": ["metadata.yaml"] + , "inputs": + { "type": "singleton_map" + , "key": "generate" + , "value": + {"type": "BLOB", "data": {"type": "var", "name": "script"}} + } + } + ] + ] + , "body": {"type": "RESULT", "artifacts": {"type": "var", "name": "data"}} + } + } +, "standalone": + { "doc": ["Create a standalone document from the given inputs"] + , "target_fields": ["srcs", "template"] + , "string_fields": ["out", "meta data"] + , "field_doc": + { "srcs": + [ "The files to build the document from, in order." + , "Honors the order within a [\"files\", \"ordered\"] target." + ] + , "out": + ["The name of the output file.", "Must not conflict with input files."] + , "template": ["The template definition to use"] + , "meta data": + [ "Additional meta data to be set. Each entry has to have the" + , "form \"key=value\"." + ] + } + , "config_vars": ["env"] + , "config_doc": + { "env": + [ "Any override to the default environment which sets only" + , "PATH, SOURCE_DATE_EPOCH, and TEXINPUTS" + ] + } + , "implicit": {"metadata": [["./", ".", "metadata"]]} + , "imports": + { "src names": ["./", "../files", "order"] + , "stage": ["./", "..", "stage_singleton_field"] + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "out" + , { "type": "assert_non_empty" + , "msg": "A valid output name has to be provided" + , "$1": {"type": "join", "$1": {"type": "FIELD", "name": "out"}} + } + ] + , [ "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"} + } + ] + } + } + } + ] + , [ "srcs" + , { "type": "to_subdir" + , "subdir": "srcs" + , "$1": {"type": "var", "name": "srcs"} + } + ] + , [ "data" + , { "type": "disjoint_map_union" + , "msg": "Data files may not conflict" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "template"} + , "body": + { "type": "map_union" + , "$1": + [ {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "x"}} + , { "type": "DEP_ARTIFACTS" + , "dep": {"type": "var", "name": "x"} + } + ] + } + } + } + ] + , [ "data" + , { "type": "to_subdir" + , "subdir": "data" + , "$1": {"type": "var", "name": "data"} + } + ] + , [ "lua filters" + , { "type": "disjoint_map_union" + , "msg": "Lua filters may not conflict" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "template"} + , "body": + { "type": "DEP_PROVIDES" + , "provider": "lua filters" + , "dep": {"type": "var", "name": "x"} + } + } + } + ] + , [ "lua filters" + , { "type": "to_subdir" + , "subdir": "lua" + , "$1": {"type": "var", "name": "lua filters"} + } + ] + , [ "template-name" + , { "type": "join" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "template"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "x"} + , "provider": "template-name" + , "default": "default" + } + } + } + ] + , [ "template-args" + , { "type": "++" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "template"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "x"} + , "provider": "template-args" + } + } + } + ] + , [ "_" + , { "type": "if" + , "cond": + { "type": "lookup" + , "map": {"type": "var", "name": "srcs"} + , "key": {"type": "var", "name": "out"} + } + , "then": + { "type": "fail" + , "msg": + [ "Output must be disjoint from inputs." + , "Output file name is" + , {"type": "var", "name": "out"} + , "input files are" + , {"type": "keys", "$1": {"type": "var", "name": "srcs"}} + ] + } + } + ] + , ["src names", {"type": "CALL_EXPRESSION", "name": "src names"}] + , [ "src names" + , { "type": "foreach" + , "var": "name" + , "range": {"type": "var", "name": "src names"} + , "body": + {"type": "join", "$1": ["srcs/", {"type": "var", "name": "name"}]} + } + ] + , [ "meta data args" + , { "type": "++" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "meta data"} + , "body": ["-M", {"type": "var", "name": "x"}] + } + } + ] + , [ "filter args" + , { "type": "++" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": + {"type": "keys", "$1": {"type": "var", "name": "lua filters"}} + , "body": ["--lua-filter", {"type": "var", "name": "x"}] + } + } + ] + , [ "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": "singleton_map", "key": "TEXINPUTS", "value": "data:"} + , {"type": "var", "name": "env", "default": {"type": "empty_map"}} + ] + } + ] + , [ "metadata" + , { "type": "let*" + , "bindings": + [["fieldname", "metadata"], ["location", "metadata.yaml"]] + , "body": {"type": "CALL_EXPRESSION", "name": "stage"} + } + ] + , [ "generated" + , { "type": "ACTION" + , "inputs": + { "type": "map_union" + , "$1": + [ {"type": "var", "name": "srcs"} + , {"type": "var", "name": "data"} + , {"type": "var", "name": "lua filters"} + , {"type": "var", "name": "metadata"} + ] + } + , "outs": [{"type": "var", "name": "out"}] + , "env": {"type": "var", "name": "env"} + , "cmd": + { "type": "++" + , "$1": + [ [ "pandoc" + , "--data-dir=./data" + , "--resource-path=./data" + , "-o" + , {"type": "var", "name": "out"} + , "-s" + , "-N" + ] + , { "type": "if" + , "cond": {"type": "var", "name": "template-name"} + , "then": + ["--template", {"type": "var", "name": "template-name"}] + } + , ["--metadata-file", "metadata.yaml"] + , {"type": "var", "name": "template-args"} + , {"type": "var", "name": "filter args"} + , {"type": "var", "name": "meta data args"} + , {"type": "var", "name": "src names"} + ] + } + } + ] + ] + , "body": + {"type": "RESULT", "artifacts": {"type": "var", "name": "generated"}} + } + } +} diff --git a/pandoc/TARGETS b/pandoc/TARGETS new file mode 100644 index 0000000..addf37a --- /dev/null +++ b/pandoc/TARGETS @@ -0,0 +1 @@ +{"metadata": {"type": "metadata"}} diff --git a/ps/RULES b/ps/RULES new file mode 100644 index 0000000..6a4a184 --- /dev/null +++ b/ps/RULES @@ -0,0 +1,122 @@ +{ "family": + { "doc": + [ "From a single eps file, create many," + , "with /stage set to different values." + ] + , "target_fields": ["src"] + , "string_fields": ["stages", "stage", "drawbb", "name"] + , "field_doc": + { "src": ["The single eps source file the variations are taken from"] + , "stages": ["The values of /stage for wich a file should be generated."] + , "drawbb": ["If non-empty, set drawbb to true, else to false"] + , "stage": ["The logical directory to stage the output to"] + , "name": + [ "The base name of the output files" + , "The stage name will be appended, separated by \"_\", and the ending \".eps\" will be added" + ] + } + , "imports": {"stage_field": ["./", "..", "stage_singleton_field"]} + , "expression": + { "type": "let*" + , "bindings": + [ [ "stage" + , { "type": "join" + , "separator": "/" + , "$1": {"type": "FIELD", "name": "stage"} + } + ] + , ["name", {"type": "join", "$1": {"type": "FIELD", "name": "name"}}] + , [ "drawbb" + , { "type": "if" + , "cond": {"type": "FIELD", "name": "drawbb"} + , "then": "true" + , "else": "false" + } + ] + , [ "src.eps" + , { "type": "let*" + , "bindings": [["fieldname", "src"], ["location", "src.eps"]] + , "body": {"type": "CALL_EXPRESSION", "name": "stage_field"} + } + ] + , [ "outputs" + , { "type": "map_union" + , "$1": + { "type": "foreach" + , "range": {"type": "FIELD", "name": "stages"} + , "var": "n" + , "body": + { "type": "let*" + , "bindings": + [ [ "script.ed" + , { "type": "singleton_map" + , "key": "script.ed" + , "value": + { "type": "BLOB" + , "data": + { "type": "join" + , "$1": + [ "1\n/\\/stage.*bind def\nd\na\n/stage { " + , {"type": "var", "name": "n"} + , " } bind def\n.\n1\n/\\/drawbb.*bind def\nd\na\n/drawbb { " + , {"type": "var", "name": "drawbb"} + , " } bind def\n.\nw\nq\n" + ] + } + } + } + ] + , [ "out.eps" + , { "type": "ACTION" + , "inputs": + { "type": "map_union" + , "$1": + [ {"type": "var", "name": "src.eps"} + , {"type": "var", "name": "script.ed"} + ] + } + , "outs": ["out.eps"] + , "cmd": + [ "sh" + , "-c" + , "cp src.eps out.eps && chmod 644 out.eps && { ed out.eps < script.ed > log 2>&1 || { cat log ; exit 1; } }" + ] + } + ] + ] + , "body": + { "type": "singleton_map" + , "key": + { "type": "join" + , "$1": + [ {"type": "var", "name": "name"} + , "_" + , {"type": "var", "name": "n"} + , ".eps" + ] + } + , "value": + { "type": "lookup" + , "map": {"type": "var", "name": "out.eps"} + , "key": "out.eps" + } + } + } + } + } + ] + , [ "staged outputs" + , { "type": "to_subdir" + , "subdir": {"type": "var", "name": "stage"} + , "$1": {"type": "var", "name": "outputs"} + } + ] + ] + , "body": + { "type": "RESULT" + , "artifacts": {"type": "var", "name": "staged outputs"} + , "runfiles": {"type": "var", "name": "staged outputs"} + } + } + } +} |