SATySFi icon indicating copy to clipboard operation
SATySFi copied to clipboard

Add make-deps command

Open yasuo-ozu opened this issue 3 years ago • 5 comments

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?

yasuo-ozu avatar May 25 '21 07:05 yasuo-ozu

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.

na4zagin3 avatar May 25 '21 15:05 na4zagin3

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.

yasuo-ozu avatar May 28 '21 15:05 yasuo-ozu

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 > "$@"

yasuo-ozu avatar May 28 '21 17:05 yasuo-ozu

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)

na4zagin3 avatar May 30 '21 07:05 na4zagin3

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,

yasuo-ozu avatar Jun 01 '21 04:06 yasuo-ozu