`@`-tags delimiter
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:
- (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 - (From @dbuenzli) A
@begin-block ... @end-blockdelimiter:@return @begin-block This is a paragraph This is another paragraph in the same tag block @end-block - (From @EmileTrotignon) A
{| |}delimiter:@return {| This is a paragraph This is another paragraph in the same tag block |} - (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!
- looks good!
4 is also my favourite
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.
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...
I don't understand why this is the case.
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]}
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:
-
{{@tag … }} -
{@ @tag … @} -
and require language that start with an @ (quite unlikely) to escape{@@tag …}{@\@oddlanguage []}.
I think 2. could be ok no ?
Yes, I think 2. could be OK, but let's continue a bit the list before choosing :)
- Like 2 but without
@in the closing bracket:{@ @tag …} - Have a regular way to group in a div. A div could be
{@ ...}or (5'){@ ... @}.@tag {@ … } @tag {@ … @} - 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...
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.
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)
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.
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).
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 sufficiently[^1] 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
[^1]: We have to give up on full consistency I think, as the one fully consistent {@tag ...} would be ambiguous with code blocks.
We looked at the existing options. Some new syntax were also proposed:
-
Use
@{return multiple blocks}. The issue with this one is that one cannot grep for@returnand get all occurrences of thereturntag anymore. ((E) is also violated) (less obvious that the first word is a keyword) -
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.
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.
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 endis correct butmodule A = structendis not.
You should open an issue upstream to fix this.
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!
Is this solved by https://github.com/ocaml/odoc/pull/1239 ?
No, we still cannot include multiple paragraphs in a tag.