messense / typst-py

Python binding to typst
Apache License 2.0
107 stars 11 forks source link

Allow `compile` function to take a string as input #4

Open slashformotion opened 1 year ago

slashformotion commented 1 year ago

Would it be possible to have a compile function that take a string as a parameter ?

ok-nick commented 1 year ago

I need to generate tens of thousands of individual pdfs, all that reference a unique path. To do that, I generate a .typ file that imports my template and calls it with the unique paths as parameters. The problem is that having to generate a temporary file per pdf is extremely slow, especially at such a large scale. It would be much more performant to skip this step entirely and pass a string or byte array directly to typst.

My use case is a workaround to this issue: https://github.com/typst/typst/issues/295

ntjess commented 1 year ago

Would it also fall under this feature request to allow compile to work with the output of metadata? That would allow powerful capabilities of compiling a subset of a document for i.e., making a separate file for each figure in a document which is a common journal publishing request.

messense commented 1 year ago

Would it also fall under this feature request to allow compile to work with the output of metadata?

Could you elaborate? I'm not sure what do you mean by "the output of metadata".

ntjess commented 1 year ago

Oops, I suppose query is what I meant to say rather than metadata.

Similar to #10, I mistakenly opened the wrong repo when adding this comment. I missed that this is for the typst-py package. My apologies! The comment is for the general typst repository allowing string compilation, not this specific package.

JCGoran commented 1 year ago

This seems like a very handy feature, and it would also make the package more "Pythonic" IMO. By more "Pythonic", consider for instance the built-in json module; the json.load function loads from a stream:

with open(file, 'r') as f:
    data = json.load(f)

while the json.loads function loads it from a string, which should be valid JSON:

data = json.load([VALID_JSON_STRING])

Making typst.compile work the same way would therefore bring it inline with the interface of the standard lib. However, from reading a bit through the codebase(s), it seems (from my limited understanding at least) that this would need to be implemented at the level of the typst library/compiler itself, not this wrapper, as the Rust compile method takes a file as input. Note that typst projects can involve multiple files, making this a bit complex to implement in full generality.

@ok-nick regarding your particular issue, have you considered using a RAM disk/temp filesystem as a workaround? If on Linux, mounting a dir as a tmpfs can potentially lead to significant performance gains (just make sure all of the files you are using for I/O are exclusively in that dir).

ok-nick commented 1 year ago

That'd be a good workaround for now, I'll have to try it out.

66Leo66 commented 1 month ago

I think this feature request is really useful for automation/scripting tasks that need to generate a (maybe simple) document without messing with temp files. typst-cli already accepts compile from stdin: typst/typst#3339. It would be cool if similar approach could be taken so that typst-py could support working with "fake files" (as added in the mentioned PR).

messense commented 1 month ago

Pull requests are welcome.