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

Custom punct before blocks #11

Closed
vldm opened this issue May 19, 2023 · 6 comments · Fixed by #34
Closed

Custom punct before blocks #11

vldm opened this issue May 19, 2023 · 6 comments · Fixed by #34

Comments

@vldm
Copy link
Collaborator

vldm commented May 19, 2023

Yew support "Dynamic tag" https://yew.rs/docs/concepts/html/elements#dynamic-tag-names
Which allows writing

<@{format!("h{}", level)} class="title">{ text }</@>

Current implementation of syn-rsx, instead force you to write same code in following syntax

<{format!("h{}", level)} class="title">{ text }</{format!("h{}", level)}>

To support yew syntax, we should extend transform_fn for blocks to also support outer punctuation.

Can be related to #8

To avoid duplication in current syntax (in open and closed tags), we can also avoid matching them if node_name has Block type, this allowing to support syntax like:

<{format!("h{}", level)} class="title">{ text }</{...}> // or any other custom syntax in closed tag block body
@vldm vldm changed the title Custom blocks Custom punct before blocks May 19, 2023
@vldm
Copy link
Collaborator Author

vldm commented Jul 17, 2023

Thanks to @LLBlumire wildcards are now allowed in close tags, so it is now easier to use "blocks" in element name.

Currently wildcard is limited to already valid NodeName, so:

//this works:
<{"foo"}> </_>
//this doesn't:
<@{"foo"}> </ @>

Because there still might be needs for special puncts in element name place, i decide to keep this issue open for a while.

Probably one way to add custom punctuation support is to allow NodeName extension through the config.

@ModProg
Copy link

ModProg commented Sep 29, 2023

I would be interested in working something probably related, I need a custom syntax in the tag, in my case, I want to support <for variable in expr> for for loops. (I have similar ideas for if let, etc.) these currently would only work with an additional brace around the expression, which I do not like.

This could probably be similar to custom blocks, though the parser supplied here has more responsibility, as it needs to terminate at the closing > on its own, and it would either need to produce a valid NodeAttribute, or OpenTag requires direct support for storing plain tokens.

If you have an idea how you want this to be implemented, I'd be happy to contribute.

@ModProg
Copy link

ModProg commented Sep 29, 2023

Maybe we could replace the syn::Block in NodeName::Block with a NodeBlock, that way it could store arbitrary tokens, and a transform_tag could just return Result<Option<NodeName>>, if it is Ok(Some(_)) this is the value used for the OpenTag::name, if it is Ok(None) the tag will be parsed as a normal tag.

Alternatively, we could make OpenTag an enum, but we already have the NodeName enum, and I think it would work quite well.

(Perhaps we could even parse the remaining tokens in the tag as NodeAttributes, though I don't have a use case for that, and really only want to do fully custom tag syntax).

@vldm
Copy link
Collaborator Author

vldm commented Sep 29, 2023

@ModProg hi, in my opinion it could be done by extending enum Node.
Probably we can add variant KeywordElement/BuiltinElement with custom body.
And trait with methods:

  1. peek_element(ParseStream)-> bool
  2. parse_element(RecoverableContext, ParseStream) -> Option<KeywordElementInner>

So that adding new type of elements would be moved outside of rstml.

There is two challenges that need to be solved:

  1. How to avoid duplication between ElementNode and KeywordElement
  2. If KeywordElementInner would be generic type - user should provide it through config with some reasonable default

@ModProg
Copy link

ModProg commented Sep 29, 2023

I guess a reasonable default would be Vec<Node> being what NodeElement's body is.

Another question, would this custom node necessarily be open tag, body, and optional closing tag, or should it be able to parse any syntax, i.e. even one not starting with <.

Technically this is something that is already supported by reparsing RawText, though a fully custom parser could probably do a bit more, i.e. allow usages of < that would be invalid in normal raw text.

if we were to support the peeking to be called even without a leading <, it could make sense to not have any NodeElement releated types here, i.e. making the Variant Node::Custom(T =Infallible/!).

@ModProg
Copy link

ModProg commented Sep 30, 2023

If we go with the fully custom node, I think it would make sense to expose part of NodeElement::parse_recoverable to allow custom nodes to easily parse bodies and closing tags.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants