SATySFi
SATySFi copied to clipboard
Add make-deps command
Add deps-make command like gcc's -MM
flag.
Satyrographos has such a command, but it enumerates only @require:
or @import:
-ed files (recursively). So, there is no way to list used image files.
@import: local
let _ = load-pdf-image `in.pdf` 1
$ SATYROGRAPHOS_EXPERIMENTAL=1 satyrographos util deps-make a.saty --satysfi-version 0.0.5
a.pdf: a.saty local.satyh
Is it reasonable to implement deps-make command in satysfi
?
I’m for adding such a feature to SATySFi with adding optionally-open file APIs.
The main purpose of the -MM
option is to let a build tool know the dependencies.
Unlike programming languages, It’s normal for typesetting languages to process a document that depends on an intermediate file that is generated from other sources. For example, consider a case where a SATySFi document requires a sheetmusic PDF file that is generated from a Lilypond source file.
This causes a cyclic dependency during a fulll build.
- In order to build a document, its dependencies must be built beforehand.
- In order to extract runtime dependencies, the document must be built.
We need to break the cyclic dependency; the simplest way is to add APIs that try to read a file, record it as a dependency anyway, and return the result in option
.
Thanks for reply.
We need to break the cyclic dependency
I think this API-redesign is complex. Is there any problem in load-image
API which just returns stub image
object with arbitrary geometry when the file not exists?
Of course, the stub image
occurs error when processing page-break
, except when SATySFi is running with -MM mode.
Note: I am using this script to generate dependency file. It works in many cases, but not always.
%.d: %.saty
@eval `opam env` && SATYROGRAPHOS_EXPERIMENTAL=1 satyrographos util deps-make "$<" --target "" --satysfi-version 0.0.5 2>/dev/null | tr ' :' '\n' | sed -e '/^$$/d' | while read LINE; do \
cat "$$LINE" | sed -e 's/\(^\|[^\\]\)%.*$$/\1/' | sed -ne '/`/p' | sed -e 's/^.*`\([^`]*\)`.*$$/\1/' | sed -ne '/[a-zA-Z0-9]\+\.\(pdf\|jpg\)$$/p' | sed -e '/^http/d' | xargs -I{} echo '$(patsubst %.d,%.pdf,$@): '`dirname "$$LINE"`'/{}' ; \
done > "$@"
API with null objects could be simpler than that with option
(or either
) if every primitive that reads a file returned a image
.
In fact, we already have read-file
, which read a file, returning a list of lines. In future we may have more and more.
Let me elaborate my proposal:
File API returning a Option
We can have a new primitive, namely load-pdf-image-opt
,
primitive load-pdf-image-opt : string -> int -> image option
We then can define load-pdf-image
that has the semantics you suggested with stub
:
primitive stub : image
let load-pdf-image file-name page-number =
Option.from stub (load-pdf-image-opt file-name page-number)
This API allows more sophisticated handling of failures. For example, we can show a crossed box with the given size like draftfigure
.
let crossed-box width height = ...
let load-pdf-image-or-draft width height file-name page-number =
Option.from (crossed-box width height) (load-pdf-image-opt file-name page-number)
Thank you for detailed design on your API. I agree with it.
Or more short-circuited way, simply make those API as statically analyzable like this:
@load-pdf-image: `in.pdf` 1 as mypic
@read-file: `in.txt` 1 as mytext
% mypic : image, mytext : string
Of course, this API design is too restricted, and na4zagin3's API is flexible,