Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to declare an element with an argument sink #4

Open
Mc-Zen opened this issue Jan 13, 2025 · 8 comments
Open

How to declare an element with an argument sink #4

Mc-Zen opened this issue Jan 13, 2025 · 8 comments
Labels
feature Request for a new feature fields Related to field parsing and typechecking in general

Comments

@Mc-Zen
Copy link

Mc-Zen commented Jan 13, 2025

Is it possible to declare an element that has a sink of (mostly positional I guess) arguments, like grid or stack?

@PgBiel
Copy link
Owner

PgBiel commented Jan 13, 2025

Good question! While allow-unknown-fields is available for unlimited named arguments, that's not really doing the job of a sink, let alone for positional arguments. Instead, you will have to override the arg parser and/or the constructor to accept arguments that don't belong to fields.

I think the constructor is easier to override if we assume that the positional arguments are required, so they can't be specified in set rules. However, if they are not required, then overriding parse-args is needed so they are recognized in set rules.

If you need to override parse-args and don't want to do everything from scratch, there is a parsing module exported by Elembic (not yet mentioned in the docs) which contains two functions, parse-fields (convert array of field() into a specialized dictionary with fields) and generate-arg-parser(fields dictionary, typecheck: true, ...) - you can use this to generate the fields dictionary before declaring the element, and then regenerate the original arg parser, which you can then use inside your parse-args override.

(I think I should probably just make parse-args be a function original => args => ..., haha)

@PgBiel PgBiel added the feature Request for a new feature label Jan 13, 2025
@PgBiel
Copy link
Owner

PgBiel commented Jan 13, 2025

However, this is expected to become a built-in feature in the future.

@Mc-Zen
Copy link
Author

Mc-Zen commented Jan 13, 2025

Alright, cool. Regarding things like grid, where only positional arguments are wanted (which is my use case and which also covers all there is in the Typst standard library), overriding the constructor should do the trick.

@PgBiel
Copy link
Owner

PgBiel commented Jan 13, 2025

I've updated parse-args to receive the default argument parser.

There are now instructions for this exact request in the docs: https://pgbiel.github.io/elembic/elements/creating/overriding-constr.html#argument-sink

@Mc-Zen
Copy link
Author

Mc-Zen commented Jan 13, 2025

Great, it works. However, now "set" rules are broken for that element afaics.

@Mc-Zen
Copy link
Author

Mc-Zen commented Jan 13, 2025

When I do

#show: e.set_(my-element, some-named-field: 2)

it complains with this part:

      assert(false, message: "element 'sunk': unexpected positional arguments\n  hint: these can only be passed to the constructor")

@PgBiel
Copy link
Owner

PgBiel commented Jan 13, 2025

Oh, that was a terrible oversight on my part. I forgot to check whether the positional arguments weren't empty before throwing the error, and if they were, not passing the additional argument.

I've fixed the example in the docs now. Thanks!

@Mc-Zen
Copy link
Author

Mc-Zen commented Jan 13, 2025

Now it works perfectly

@PgBiel PgBiel added the fields Related to field parsing and typechecking in general label Jan 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Request for a new feature fields Related to field parsing and typechecking in general
Projects
None yet
Development

No branches or pull requests

2 participants