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

@-tags delimiter #1226

Open
panglesd opened this issue Oct 29, 2024 · 16 comments
Open

@-tags delimiter #1226

panglesd opened this issue Oct 29, 2024 · 16 comments

Comments

@panglesd
Copy link
Collaborator

panglesd commented Oct 29, 2024

I think it is clear from #1138 that tags should not expand unconditionally to the rest of the content.

So we need a way to have tags extend to several paragraphs. To make the discussion clearer, I open this issue separately from #1138 (which is about "what is the range of undelimited tags").

Here are the various options that I have recollected:

  1. (From @dbuenzli) a single @ on an empty line adds the next block in the tag
    @return This is a paragraph
    @
    This is another paragraph in the same tag block
    
  2. (From @dbuenzli) A @begin-block ... @end-block delimiter:
    @return @begin-block This is a paragraph
    
    This is another paragraph in the same tag block @end-block
    
  3. (From @EmileTrotignon) A {| |} delimiter:
    @return {| This is a paragraph
    
    This is another paragraph in the same tag block |}
    
  4. (From @EmileTrotignon) A {@ ...} delimitation:
    {@return This is a paragraph
    
    This is another paragraph in the same tag block}
    

Option 1. is weird to me (it can be explained, if we decide to delimit the range of an undelimited tag block with blank lines).
Option 2. I'm not a fan since it feels quite orthogonal to what is currently used to delimit, in the odoc syntax.
Option 3. is similar to option 2, replacing 11 letters with 2 symbols. Still orthogonal, I think!
Option 4. is clearly my favorite, as it seems to integrate naturally in the odoc way of delimiting.

Feel free to comment, suggest another syntax, ... like and subscribe!

@dbuenzli
Copy link
Contributor

  1. looks good!

@EmileTrotignon
Copy link
Collaborator

4 is also my favourite

@jonludlam
Copy link
Member

I'm also happy with 4 - though it's worth mentioning that any instance of [ in the text will turn it into a code block, so we may need to be able to escape them.

@panglesd
Copy link
Collaborator Author

Oh no, I did not think about that... Thanks for pointing it out. Having to escape them seems cumbersome: [ are used too often in odoc...

@dbuenzli
Copy link
Contributor

I don't understand why this is the case.

@panglesd
Copy link
Collaborator Author

panglesd commented Oct 30, 2024

The doc seems not to be perfectly up to date with regards to code blocks, but one can specify a language as well as some other metadata information in a code block. Example:

{@ocaml env=f1 version>=4.06 [code goes here]}

The language name (ocaml here) is supposed to be chosen without constraint: it could be @return. Then, how to distinguish this from a code block?

{@return [x + 1]}

@dbuenzli
Copy link
Contributor

Ah yes :-( Thanks for the explanation. In practice you'd have to escape only the first '[' but it is a bit annoying.

Some quick ideas. Perhaps combining 3 and 4 and have for example:

  1. {{@tag … }}
    
  2. {@ @tag … @}
    
  3. {@@tag …}
    
    and require language that start with an @ (quite unlikely) to escape {@\@oddlanguage []}.

I think 2. could be ok no ?

@panglesd
Copy link
Collaborator Author

Yes, I think 2. could be OK, but let's continue a bit the list before choosing :)

  1. Like 2 but without @ in the closing bracket:
     {@ @tag …}
    
  2. Have a regular way to group in a div. A div could be {@ ...} or (5') {@ ... @}.
     @tag {@ … }
     @tag {@ … @}
    
  3. Have a regular way to group in a div, but this time the syntax is taken from the extension nodes of OCaml. A div could be {% ...} or (6') {% ... %}.
     @tag {% … }
     @tag {% … %}
    

What I like about 6 and 6' is that we can easily add plugins which rewrite the extension node, if we allow them to be named: {%mermaid ... } (for mermaid diagrams) but that's a deep hole to fall into...

@dbuenzli
Copy link
Contributor

4. Like 2 but without @ in the closing bracket:

But couldn't {@ @return [x+1]} be a code block ? If not then why not.

Regarding 5, personally I rather have the directive in the braces that's the ocamldoc way.

Regarding 6, I think code blocks are sufficient for that. For example {@mermaid eval=true […]} or something like that.

@panglesd
Copy link
Collaborator Author

panglesd commented Oct 30, 2024

Regarding 6, I think code blocks are sufficient for that. For example {@mermaid eval=true […]} or something like that.

Yes, mermaid was a bad example... Maybe a custom kind of admonition would be a better example.

{%theorem
  If {m x} is even then {m x+1} is odd.
}

(although I agree that code blocks are sufficient, you can run the parser on them)

@panglesd
Copy link
Collaborator Author

panglesd commented Nov 5, 2024

Another option that was suggested (I'm collecting them):

Base the scope of the tag on indentation:

@return [foo] which for bla

  This is also in the tag scope since it's indented
  
This is not in the tag

I think this does not integrate well with the current odoc syntax (no current syntax is affected by indentation). #1219 is an example among others). It could be a new direction, but that's a big change.

However, it is worth mentioning since some people tried that.

@panglesd
Copy link
Collaborator Author

panglesd commented Nov 5, 2024

Regarding 6, let me add that we could slightly modify it to distinguish inline and block "extension nodes" :

This element is {%blink special} and inline.

{%%example
  This one is a block
}

Currently this is my personal preference since I think it will be useful for the future, if one day plugins are possible. Without a name, it is simply grouping a list of blocks into a single blocks (thus we can group blocks under a tag).

However, maybe 4. ({@ @tag …}) is less controversial, and decently solves this specific problem without interacting too much with the rest of the syntax (it can only be used in the context of tags).

@panglesd
Copy link
Collaborator Author

panglesd commented Nov 7, 2024

We discussed this during the dev meeting.

First, we do not want a grouping syntax independently of tags, as proposed in 5. and 6. Indeed, custom tags already exist in ocamldoc, and we would use that if we add "plugin support".

Here are some properties that were mentioned as nice to have (with various weight), for the syntax to group blocks in a tag:

  • (A) Be obvious that it is a grouping restricted to tags,
  • (B) Be easy to grep all occurrence of a tag, whether grouped or not
  • (C) Be sufficiently1 consistent with other existing syntax.
  • (D) Mix well with other syntax.
  • (E) Not to have to alter the beginning of your tag in order to have it span multiple blocks.
  • (F) Be short

We looked at the existing options. Some new syntax were also proposed:

  1. Use @{return multiple blocks}. The issue with this one is that one cannot grep for @return and get all occurrences of the return tag anymore. ((E) is also violated) (less obvious that the first word is a keyword)

  2. Use @return{multiple blocks}. Note that the absence of whitespace is important here, to distinguish between a regular tag, starting with a code block, and a multiple-block tag. The former has a space after the tag name, the latter no. Example:

@param{[inline code] in an extended code block}
@frontmatter {[ code block, not an extended tag ]}

Option 8. was the most convincing option at the end of the meeting.

Footnotes

  1. We have to give up on full consistency I think, as the one fully consistent {@tag ...} would be ambiguous with code blocks.

@EmileTrotignon
Copy link
Collaborator

I do not like the fact that option 8 is so sensitive to whitespace, I am afraid this will lead to a lot of mistakes.
I am not sure what the best option is. Maybe allow for whitespace, but have it so that

@param {[code block]} 

is a code block, but

@param { [inline code] blabla}

is a grouped tag. I think it is more intuitive to have { be a keyword but {[ is another so that you need to separate them or semantics might change. Like in Ocaml where module A = struct end is correct but module A = structend is not.

@panglesd
Copy link
Collaborator Author

panglesd commented Nov 8, 2024

Similarly, module A = struct end is valid but mod ule A = struct end is not.

For me, the issue with

@return { 
  blibli
}

makes it look like { can be used in other context than a tag.

in Ocaml where module A = struct end is correct but module A = structend is not.

You should open an issue upstream to fix this.

@jonludlam
Copy link
Member

Just as an aside, @panglesd found that lists not only have this issue but also have a solution:

- This is a list
- and the list is ended by a blank line

  This is a new paragraph outside of the list.

and

{ul
 {- This is a list}
 {- This list is not ended by the following blank line

     This new paragraph is part of the list}}

which makes me sad again that {@foo can be the start of a code block!

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

No branches or pull requests

4 participants