problem-solving icon indicating copy to clipboard operation
problem-solving copied to clipboard

Rakudoc in third-party modules and some related topics

Open vrurg opened this issue 2 years ago • 51 comments

This is a meta-issue as it is about to cover a few topics I stumbled upon while writing docs for my last module. Perhaps it would make sense to spawn more specialized issues later, but for now it feels to me like having more sense in providing general overview of the situation.

It is also to be noted that I've got an answer to at least one of my question, but it was part of an undocumented conversation. Therefore it'd be included here as well. Other answers could be lurking out there too, but they're not known to me.

I would try to structure this from the perspective of a module developer, possibly not very experienced with documenting in Raku.

Where To Start?

Turns out we don't have a manual on how to write manuals. Something I'd rather expect to be part of module development section in the Raku documentation, or be linked to from the section. What I would like to see there is:

  1. Where to start in general, including such topics as recommended sections and styling in general
  2. How to organize the docs from distribution perspective: file locations, pros and cons of using dedicated .rakudoc, or inlining into .rakumod, etc.
  3. What tools to use.

I'd say this all is better be a single piece since, as a rule, writing docs is the final stage of project development.

Docs In An Installed Distribution

Giving further development to the item 2 from from above, there are cases when having documentation inlined into a .rakumod is not considered a good idea. My own latest example is LibXML::Class::Manual which is not a module and better not be. Other cases may include documenting classes which are declared within a module but one wants them to be available for a documentation reading tool by their full names:

unit module Foo;

class Bar {...}

And then:

$ rakudoc Foo::Bar

Our current Raku documentation states that .rakudoc are to be placed under doc/ directory of distribution source tree. But the directory is never included into precompiled installation. Thus, zef install Foo and then wiping zef's cache would leave one with no access to these docs whatsoever.

Though, for the clarity, even having the cache preserved is of little help because one has to know where is it located before using it. Moreover, if they don't know about the cache existence then it's not much different from not having it in first place.

The Reading Tool

For those coming from Perl background, having rakudoc is quite natural expectation. To be frank, I don't know what is the situation with documentation readers in other languages, but having one should be considered an advantage. From this point of view I tend to consider having the rakudoc as the standard.

Either way, there is no alternative to it presently. But in its current form it is barely useful too.

First of all, it requires a document to follow its demands with regard to the structure and it is very rigid in these demands. In particular, it has to be =TITLE, not =head TITLE, not =head1 TITLE. But then again, why =TITLE and =SUBTITLE, after all? My own preference is man-styled docs with =NAME, =SYNOPSIS, =DESCRIPTION, etc. In large due to keeping in mind that this how they should be used too.

The other requirement is to have :kind, :subkind, and :category keys on =begin pod – but what are they? What for? Seems like this is something apparent to The Raku Documentation project participants, but they are an undocumented mystery to me.

It is understandable that since rakudoc is not part of Rakudo and, apparently and definitely, of the Raku language, I cannot impose any requirements on it. But without an alternative implementing more democratic rules I'd have these question open. It is irrelevant to me wether they'd be answered by rakudoc or somebody picks up the task and implements a "competitor".

And then, once again, access to .rakudoc in precompiled distros...

Tooling?

Having some kind of standard tool or tools to deal with documentation, starting from verifying it and all the way down to producing output formats and even publishing them – it's a dream. Let it be here, just in case...

BTW, with RakuAST implementing this part would become more feasible.

TOC?

I'm not even certain as to what to ask about here. Some documents (the above mentioned manual, in particular) tend to grow big. Having TOC would help a lot in navigating them. Even if it's not clickable since having a document overview already eases search for necessary information.

Some docs are so tiny that TOC in them would be an overkill.

Having TOC as a part of Rakudoc standard seems to be an advantage. Making it available for opt-in/opt-out would be great too.

Rakudoc Cross-linking

L<> tag is giving more questions than answers. The first and the biggest problem is when it comes down to multi-format output (HTML, Markdown, etc.) where there could not only be different file extensions but even different directory structure – if there is any directories at all like when everything is thrown into a single PDF, for example. There is a real-life case of https://raku.land where links in READMEs are very fragile and often just do not work.

What aspects of linking we can take as axioms?

  • anchors (explicit or implicit)
  • inter-document
  • cross-document
  • the already mentioned multi-format output with different file extensions and URI schemas

A typical question of linking would look like: in a doc for module Foo::Bar::Baz I need to link to a paragraph in Foo::Fubar documentation so, that it would work in a local HTML; on a web page; on a version control service provider like GitHub, GitLab, whatever else is one's choice; etc.

Perhaps this question doesn't have a comprehensive answer, but at the moment there is barely anything reliable but WWW URLs. Not even relative paths are sufficiently good for the task.

vrurg avatar Jun 21 '23 01:06 vrurg

My own two cents.

First, about TOC. Best is to have =toc so one can chose where exactly they want to see it. This is best in cases when a kind of preface is required.

Speaking of links, @finanalyst has mentioned during our last RSC meeting that we can introduce, say :id configuration key, making it possible to create reliable links. The problem in general for now is when we have, say =head My Ideas there is no way to link to it in a way that when it gets renamed to =head Our Ideas the old L<> tags would still point out to the section.

Another matter to cover is that limiting links with only certain kinds of Rakudoc elements (like headings) make it harder for both the writer and the reader: "See section L<Our Ideas>, where you would find a list with an item of interest." Nah!

Look at the method L<foo|#method-foo> down below.

...

=begin item :id<method-foo>
B<C<method foo(...)>>

Hope you found what you're looking for here!
=end item

Having :id available for any (or almost any) kind of Rakudoc block would be very beneficial for docs readability.

Another point is cross-module/-document linking. Speaking of the Foo::Bar::Baz -> Foo::Fubar example, best if one can simply use L<Foo::Fubar|#some-id> and the rest would be taken care of by the tools. Moreover, I'd make the pipe | optional and have it just as `LFoo::Fubar#some-id in this particular case. Others would still require the separator.

vrurg avatar Jun 21 '23 01:06 vrurg

Having to always define :id for any potential anchor is too much. Therefore some rules of implicit anchor naming must be defined. But they have to be clear and standard for any output format. Whatever is eventually generated in the output, anchor name in Rakudoc would only depend on what Rakudoc itself states. So, one would know that =head Our Ideas can be referenced as #our-ideas at any time.

It feels to me that these rules are to be coded in RakuAST parser. Tools would simply pick up what they're offered with. This should also simplify producing links for something like L<Our Ideas> as the corresponding object would already have the target anchor name in it.

vrurg avatar Jun 21 '23 01:06 vrurg

I gave a 10 min presentation to the Core summit about changes needed in Rakudoc. As a result of the 3hours of discussion, I have rewritten the Rakudoc document / specification, making it backwards compatible, but also explaining a lot more about certain features of Rakudoc (aka POD6), such as metadata, the difference between code-oriented Rakudoc and page-oriented Rakudoc, directives vs blocks, etc.

A first draft of the Rakudoc document is currently being reviewed by @lizmat As soon as she is through, it will be sent for a BETA review to people who have been implementing Rakudoc in various ways. After the BETA review and incorporating changes, the document will be placed somewhere (as a Raku/Doc PR) for a wider community review. Also I will release a series of blogs about the changes to explain the rationale behind them.

As to the requests above (this is not an exhaustive list of the revisions):

  • An original unimplemented specification in S26 (the speculation about POD6) was P<:toc> which would place a TOC where the author wanted. This will be a part of the revised Rakudoc.
    • There is a problem in that for a large project like Raku documentation the designer will want to place the ToC in a standard place, such as a sidebar.
  • The idea of an :id<some-custom-anchor> will be in the Rakudoc revision, and will be applied to all blocks.
    • It is for the author to guarantee that the id is unique, a conflict is resolved by the browser or renderer.
    • If a =head block exists, then it automatically generates an anchor (as mentioned above), which is guaranteed to be unique. However, a custom :id will also generate an anchor at the same place. This way a document author can create an easy to remember anchor for their own documents.
    • The ability to add custom metadata already exists by using the =for directive. So if a =head1 This is a header exists and the id needs to be customised, then the new code will be:
=for head1 :to<easy_anchor>
This is a header

A compliant renderer will be expected to generate both the this_is_a_header and the easy_anchor anchors.

  • The need for a way to link by Module was noted at the Core summit with a new schema for L<> and P<> markup, namely mod://Some::Module. The syntax will be included in the Rakudoc revision, but the semantics have yet to be fully nailed down. It will link to the rakuland site though.
  • About the :kind :subkind metadata in Raku documentation files, this is a poorly documented feature of POD6. This data is used by the Renderer of the Raku documentation to compile cross document indexes and secondary files. Only some metadata is specified by the new Rakudoc revision, and if it is not in the specification, then it is ignored, unless a customised renderer is used.
  • About how to create documentation, and ways to view any module's documentation, this is indeed a need. There is a part of the META6 specification that includes a 'doc' directory, but this not used or recognised yet.

In addition, the move to RakuAST will change Rakudoc considerably. It will no longer need to be accessed via the $=pod mechanism, but will be primarily found using an .AST call on a file.

Hopes this explains some of the progress that is on its way.

finanalyst avatar Jun 21 '23 20:06 finanalyst

  • The need for a way to link by Module was noted at the Core summit with a new schema for L<> and P<> markup, namely mod://Some::Module. The syntax will be included in the Rakudoc revision, but the semantics have yet to be fully nailed down. It will link to the rakuland site though.

The specification shouldn't dictate, which platform module links are resolved to. Once raku.land has gained Rakudoc support it makes sense for docs.raku.org to link to raku.land (as that's currently the dominant platform). But other documentation providers should be free to link somewhere else. E.g. a command line documentation reader should try to resolve and display module links itself.

@finanalyst I guess this is what you meant. But I wanted to be sure.

patrickbkr avatar Jun 22 '23 06:06 patrickbkr

@patrickbkr yes, you're right about retaining a generic interface, but what I meant about 'the semantics have yet to be fully nailed down' is to work out how to do this. The reference to rakuland is more about an initial default. Because Rakudoc must be customisable, every renderer will have to be configurable in some way. I don't want to define how a renderer should be configured. However, by defining the behaviours of some blocks, say the way numbering works with =head and =item, Rakudoc is being specific about defaults, allowing Renderer developers to provide other behaviours. The =config directive to change behaviours. oO ( maybe we need to have a metadata option like :mod-prefix that by default is set to eg rakuland, then if a document writer wants a different behaviour, they could put

=config Markup-L mod-prefix 'https://another-site.eg/dist?'

) end of speculation Would this suit?

finanalyst avatar Jun 22 '23 09:06 finanalyst

I think documentation software will fall in one of several categories:

  • Software to display the official Raku documentation which may contain links to ecosystem modules -> hard code raku.land or let the user decide via some configuration on the website
  • Generic ecosystem module documentation viewers (raku.land, the rakudoc CLI tool) -> They should open links in their own interface.
  • Software to create or display documentation potentially unrelated to Raku. (podlite?) -> Won't have module links.
  • A company may have internal Raku code and documentation which they view in a private installation of e.g. raku.land. -> Configure that installation to resolve links to that private installation itself.

Following the above categories I see two cases:

  • the reader wants to change where such links go to (i.e. by setting some option in the viewer program / website)
  • the software presenting the documentation decides

@finanalyst Can you come up with an example where it would make sense for the mod-prefix to be specified in the documentation itself?

patrickbkr avatar Jun 22 '23 10:06 patrickbkr

I don't think there must be any suggestion/defaults on the Rakudoc side as to where module links must point at. Neither implicit, by the standard; nor explicit by document creator. In the latter case there is always an option of inserting the link manually, as a URL, since it's about to be rigidly hardcoded anyway.

This has to be 100% on the reader side.

vrurg avatar Jun 22 '23 15:06 vrurg

@vrurg I'm having difficulties reconciling your two comments:

best if one can simply use LFoo::Fubar|#some-id and the rest would be taken care of by the tools. Moreover, I'd make the pipe | optional and have it just as `LFoo::Fubar#some-id in this particular case

and recently

don't think there must be any suggestion/defaults on the Rakudoc side as to where module links must point at. Neither implicit, by the standard; nor explicit by document creator. In the latter case there is always an option of inserting the link manually, as a URL, since it's about to be rigidly hardcoded anyway.

The original desire seemed to be that in some documentation an author could say eg

This to-json method is similar to the L<to-json method in JSON::Fast|mod://JSON::Fast#to-json>

The renderer would have default mechanism to find JSON::Fast and point at the documentation.

Personally I don't like the suggestion purely because it leaves too much to the tooling, but I could see it would be useful.

But if such a functionality is wanted, how should a Renderer operate to become compliant?

finanalyst avatar Jun 22 '23 15:06 finanalyst

The renderer would have default mechanism to find JSON::Fast and point at the documentation.

I have combined the "renderer" and actual person-reader into a single term "reader". The point is that there is language side (the Rakudoc standard), the writer side (module/document author), and the "reader" side. Or, the other way around, "reader" is the one who reads Rakudoc sources.

Not the best definitions, but OK for the purpose of defining where the final link is produced.

Personally I don't like the suggestion purely because it leaves too much to the tooling, but I could see it would be useful.

Dynamic or semi-dynamic things like URLs are better be left off to the tools. As much as we should do is to provide recommendations, but nothing more. Patrick has provided very good examples as to when the final URL can differ from our understanding of it. My other point would be that changing a standard is not a particularly fast paced process. Not to mention the need for the tools to update afterwards. But in case of a disastrous disappearance of the site, hardcoded in the standard, we better let tool developers to react as quick as they can.

vrurg avatar Jun 22 '23 15:06 vrurg

The three terms are needed:

  • reader - a human reading documentation about a module or functionality. The reader will want to use a method that is most convenient. There are three current useful methods:
    • HTML rendered pages (such as the Raku documentation suite), but also in pages rendered by Podlite.
    • MarkDown rendered pages, eg. REAME.md
    • An IDE, such as Comma
  • developer / document author - a human writing software or describing how to use software, which the reader will want to use. The writer uses Rakudoc, which is neutral about the output format.
  • renderer - the software tool that converts Rakudoc instructions into a form useful to the reader. The renderer for the Raku documentation site is now Raku::Pod::Render.

So the suggestion is to include in the standard for the minimum Rakudoc the schema for L<> markup called mod://, in addition to the very common https://| http://. The aim is for mod:// to be followed by the name of a Raku module.

That part seems easy. The question is how to specify what a Rakudoc B<Renderer> should do when implementing that link? There may be multiple renderers (I am already planning a new renderer to work directly on RakuAST because Raku::Pod::Render works using $=pod).

It seems to me that a default behaviour should be indicated in the Rakudoc documentation. This default can be changed in the future.

However, this default can be changed / customised.

I am ABSOLUTELY against hard-coded solutions. I wrote Raku::Pod::Render because Pod::To::HTML hard coded everything. The bits that are now put into Mustache templates were my first PRs to Pod::To::HTML.

What I am trying to say is that even if there is maximum flexibility, there should be some reasonable defaults so that the first use of a Render can be as easy as possible for a new user.

finanalyst avatar Jun 22 '23 16:06 finanalyst

Something to consider when trying to create a URI scheme for this is that users should be able to link to a specific version like mod://JSON::Fast:ver<42>#to-json. The < and > would make it annoying to embed in L<>.

ugexe avatar Jun 24 '23 19:06 ugexe

That has a solution, one can use L<<>> or L«», unless you're referring to something else.

CIAvash avatar Jun 24 '23 19:06 CIAvash

@ugexe the Rakudo grammar is actually good at handling this sort of bracing. For instance C< L<> > passes L<> to the handler for C.

finanalyst avatar Jun 24 '23 19:06 finanalyst

As long as the delimiters are balanced it'll work, unless the <> part is in the URL section(I don't know if that's a bug):

=begin pod
L<mod://JSON::Fast:ver<42>#to-json>
# Pod::FormattingCode.new(type => "L", meta => [], config => {}, contents => ["mod://JSON::Fast:ver<42>#to-json"])

L<test|mod://JSON::Fast:ver<42>#to-json>
# Pod::FormattingCode.new(type => "L", meta => ["mod://JSON::Fast:ver<42"], config => {}, contents => ["test"])

L<<test|mod://JSON::Fast:ver<42>#to-json>>
# Pod::FormattingCode.new(type => "L", meta => ["mod://JSON::Fast:ver<42>#to-json"], config => {}, contents => ["test"])

L«test|mod://JSON::Fast:ver<42>#to-json»
# Pod::FormattingCode.new(type => "L", meta => ["mod://JSON::Fast:ver<42>#to-json"], config => {}, contents => ["test"])
=end pod

CIAvash avatar Jun 24 '23 19:06 CIAvash

@CIAvash Good catch. I would say the second case is a bug. Have you tried this with RakuAST?

finanalyst avatar Jun 24 '23 20:06 finanalyst

@finanalyst no, not sure how to do that. I'm still on Rakudo 2023.04. That doesn't support RakuDoc, does it?

CIAvash avatar Jun 24 '23 20:06 CIAvash

@CIAvash RakuAST for RakuDoc is very bleeding edge. Using your tests in a file called ttt.rakudoc, I get.

$ RAKUDO_RAKUAST=1 raku -e "'ttt.rakudoc'.IO.slurp.AST.say"
RakuAST::StatementList.new(
  RakuAST::Doc::Block.new(
    type       => "pod",
    paragraphs => (
      RakuAST::Doc::Paragraph.new(
        RakuAST::Doc::Markup.new(
          letter => "L",
          opener => "<",
          closer => ">",
          atoms  => (
            "mod://JSON::Fast:ver",
            RakuAST::Doc::Markup.new(
              letter => "",
              opener => "<",
              closer => ">",
              atoms  => (
                "42",
              )
            ),
            "#to-json",
          )
        ),
        "\n\n"
      ),
      RakuAST::Doc::Paragraph.new(
        RakuAST::Doc::Markup.new(
          letter => "L",
          opener => "<",
          closer => ">",
          atoms  => (
            "test|mod://JSON::Fast:ver",
            RakuAST::Doc::Markup.new(
              letter => "",
              opener => "<",
              closer => ">",
              atoms  => (
                "42",
              )
            ),
            "#to-json",
          )
        ),
        "\n\n"
      ),
      RakuAST::Doc::Paragraph.new(
        RakuAST::Doc::Markup.new(
          letter => "L",
          opener => "<<",
          closer => ">>",
          atoms  => (
            "test",
          ),
          meta   => (
            "mod://JSON::Fast:ver<42>#to-json",
          )
        ),
        "\n\n"
      ),
      RakuAST::Doc::Paragraph.new(
        RakuAST::Doc::Markup.new(
          letter => "L",
          opener => "«",
          closer => "»",
          atoms  => (
            "test",
          ),
          meta   => (
            "mod://JSON::Fast:ver<42>#to-json",
          )
        ),
        "\n\n"
      ),
    )
  )
)

So @ugexe was correct: the inner <> causes problems.

The interesting thing is that both of the first two cases in your example are wrong, the first one subtly. Rakudo is parsing the <> after the ver as a FormatCode with letter ''.

Using << >> as the bracketing pair yields the correct form (the url should be in the meta attribute.

finanalyst avatar Jun 24 '23 20:06 finanalyst

@finanalyst hmm, don't know if that's a bug or not, but using multiple angle brackets or «» is safer for sure.

CIAvash avatar Jun 25 '23 05:06 CIAvash

So @ugexe was correct: the inner <> causes problems.

It indeed causes issues in the legacy $=pod generation. Am looking into this.

The interesting thing is that both of the first two cases in your example are wrong, the first one subtly. Rakudo is parsing the <> after the ver as a FormatCode with letter ''.

The rules according to S26 are that if you use the same delimiter inside a markup as the "outer" markup, they must balance. The easiest way to implement this, was to handle the as "letterless" markup codes. A "letterless" markup code can always just be stringified. One could argue the parser should do that for you, but I'm a little in two minds about that, as it would remove potentially valuable information.

Using << >> as the bracketing pair yields the correct form (the url should be in the meta attribute.

Different delimiters mean that you can have unbalanced as well, as they are completely ignored in markup parsing.

lizmat avatar Jun 25 '23 08:06 lizmat

A "letterless" markup code can always just be stringified. One could argue the parser should do that for you, but I'm a little in two minds about that, as it would remove potentially valuable information.

If the parser doesn't stringify, then a RakuAST-oriented renderer needs to look for letterless MC. Then this needs to be documented. It could be useful if a renderer is looking to do something with :var<>, :auth<> or :api<>. That seems a long way ahead.

Different delimiters mean that you can have unbalanced as well, as they are completely ignored in markup parsing.

But that would allow unbalanced delimiters. A note in documentation would indicate that if different delimiters are used, the parser will not pick up an imbalance.

finanalyst avatar Jun 25 '23 10:06 finanalyst

But that would allow unbalanced delimiters. A note in documentation would indicate that if different delimiters are used, the parser will not pick up an imbalance.

Sometimes you need to allow for unbalanced delimiters. C« < » comes to mind.

lizmat avatar Jun 25 '23 10:06 lizmat

https://github.com/rakudo/rakudo/commit/e66bcd670c fixes the L<test|mod://JSON::Fast:ver<42>#to-json> case.

RakuAST::Doc::Markup.new(
  letter => "L",
  opener => "<",
  closer => ">",
  atoms  => (
    "test",
  ),
  meta   => (
    "mod://JSON::Fast:ver<42>#to-json",
  )
)

lizmat avatar Jun 25 '23 10:06 lizmat

Some other things to consider that crossed my mind:

Is this mod:// string is meant to be an actual URI? If so I don't think we could use :, <, or > (among others) in the host portion of it. The file URI scheme solves a similar problem (that / can be contained in the first part -- i.e. the host) by starting the scheme with a triple slash ala file:/// (thus e.g. JSON::Fast would end up in the path portion of the URI instead of host).

Another other thing is that : < > would typically be URI encoded. This might not be a problem as most tooling can probably handle that conversion, but I do wonder if having the URI not parse-able by URI grammars in their initial form will lead to problems down the road. I'm not really sure there is a good solution for this, but it is worth being aware of.

Third, while it doesn't map directly to raku syntax, it might be better to pass filters like we normally would with a URI, ala mod:///Foo::Bar?version=1&api=2&auth="blorg". This also happens to solve some parts of the previous problem since we wouldn't be passing in < and >.

Fourth, should we use a different prefix like rakumod://? That might make it easier to have something that would show up on e.g. https://en.wikipedia.org/wiki/List_of_URI_schemes since it wouldn't be using a super generic scheme mod

Finally, should this URI map to a distribution + module? For instance a distribution called Net::HTTP which provides a module Net::HTTP::Get: rakumod:///Net::HTTP/Net::HTTP::GET?version=1&auth="github:ugexe". I.e. first path portion would be the distribution, the second path portion (which could be optional) would be something contained in that distribution.

ugexe avatar Jun 25 '23 13:06 ugexe

It shouldn't be an actual URI, should it? Language implementation should create the RakuDoc data and then RakuDoc renderer should create the suitable link/whatever IMO.

The old design docs mention L<doc:Module::Name>: https://design.raku.org/S26.html#Links

CIAvash avatar Jun 25 '23 14:06 CIAvash

To respond to @ugexe , let me start with some initial ideas.

The idea behind the mod: schema is to make it easier for a documentation writer to refer to a module without needing to know where the module is located.

A link has two parts L< 'the text shown in the documentation' | 'the meta data containing the link>`. So when I say 'meta data', I mean the second bit.

The metadata can already contain three schemas: http://, https://, file://

The original suggestion was to have quite a few more, but the one that seems to have usefulness is toc:, to which we are adding index:.

The new schema requested was mod:, but :rakumod seems a better idea since I'm sure someone will want to reference a module in another language, which would increase complexity without much benefit.

Since the idea is to make it easy to write and (read the raw Rakudoc), my feeling is that the rakumod: schema should be as close to the Raku standard idiom as possible.

The question about the URI mapping is something I would call the 'semantics' of the schema (I'm probably technically wrong here). I would think that when a renderer creates the rendered version, for example an HTML <a> tab, it should create something like Foo::Bar?version=1&api=2&auth="blorg" from L<< text | mod://Foo::Bar:ver<1>:api<2>:auth<blorg> >>.

As to distribution / module parts, I think there is a question to be resolved. Where doe s the link to point at? Suppose we have a distribution ExampleModule structured as

ExampleModule/
  docs/
     README.rakudoc
     Moredetail.rakudoc
  lib/
     ExampleModule.rakumod
  README.md

Now we have L<looking at the Example module|rakumod://ExampleModule>, where does it reference? And an HTML URL is going to expect an HTML page to be served back.

This indicates that a Rakumod: schema imposes an expectation on the site that is serving the link.

finanalyst avatar Jun 25 '23 14:06 finanalyst

Another point for rakumod: is that it's more self-documenting. It's crystal clear that the URI is identifying a Raku module.

Since we want to use a URI to identify these modules, we must adhere to the URI syntax. Everything else would just put an unneeded burden on tool developers. As such a tool developer, I'd expect to be able to pass the actual link to a standard URI parser to get at the individual components (most of all the scheme to determine, how to link). The URI part after the initial // is the authority which is [userinfo "@"] host [":" port]. As we don't have that kind of information in rakumod links, it doesn't make sense to include the //. Thus a sensible URI would look like rakumod:Foo::Bar

As to the question of how to encode adverbs, I would suggest that we stick to URI syntax as @ugexe suggested: rakumod:Foo::Bar?version=1&api=2&auth="blorg". The reasons are:

  • Since tools will already use a URI parser for processing these links, getting the adverbs will be very straight forward, without having to parse the path part yet again.
  • The :version<1> syntax might be quite common, but it's by no means standard and by far not the only one. A benign alternative would be :version(1), but syntactically it could also be :version(1 + 2) or really arbitrary code. I'm pretty sure we do not want to go down that route.
  • If you argue, that the above is nonsense and we'd of course not allow full Raku syntax in these adverbs, then you'll have to answer how to e.g. quote > characters contained in these fields (like auth super>>fancy>>company). The closer you stick to standard URI syntax, the more obvious the answers are.
  • Even with :version<1> you'll end up with the mentioned > >> at the end of the link, which only makes it harder to read.

Just a side node: technically, we don't want those links to be URIs, but IRIs instead. After all, we'll permit pretty much all of Unicode there as usual.

niner avatar Jun 25 '23 15:06 niner

Maybe it's because I haven't been involved, but I still don't understand why the tools need to parse the L<> link. Isn't it the job of Raku to provide the necessary and parsed data?

For the dist/module linking, I think it needs to be standardized, so tools know what doc to show as the main document and in what order.

CIAvash avatar Jun 25 '23 16:06 CIAvash

FWIW, in RakuAST, anything after the | in L<> will appear in the meta attribute. That it didn't so far in some cases, was a bug and that has been fixed.

lizmat avatar Jun 25 '23 18:06 lizmat

Just to be clear, I mean maybe Raku should do more than extracting the link, also parse it and provide an object representing the dist/module, since Raku already supports that syntax.

CIAvash avatar Jun 25 '23 18:06 CIAvash

@CIAvash Here's my take on your comment. (I hope I'm not stating the obvious)

Rakudoc is a markup language that is quite neutral to the way a user will view the documentation. ('quite neutral' although it leans heavily to HTML).

Rakudoc is eventually rendered to an output that the reader will view. So a Rakudoc some text L<pointer|https://docs.raku.org/language/pod> will be output into HTML as

some text <a href="http://docs.raku.org/language/pod>pointer</a>

and into Markdown as

some text [pointer](http://docs.raku.org/language/pod)

and eventually into epub in an xhml version.

Currently parses the Rakudoc into a $=pod tree as

[Pod::Block::Named.new(name => "pod", config => {}, contents => [Pod::Block::Para.new(config => {}, contents => ["some text ", Pod::FormattingCode.new(type => "L", meta => ["http://docs.raku.org/language/pod"], config => {}, contents => ["pointer"])])])]

It is the renderer that takes the pod block and turns it into html or markdown.

In the future, it won't be a POD block, but an AST tree that is used by the Render. Here is the AST tree for the same file.

RakuAST::StatementList.new(
  RakuAST::Doc::Block.new(
    type       => "pod",
    paragraphs => (
      RakuAST::Doc::Paragraph.new(
        "some text ",
        RakuAST::Doc::Markup.new(
          letter => "L",
          opener => "«",
          closer => "»",
          atoms  => (
            "pointer",
          ),
          meta   => (
            "http://docs.raku.org/language/pod",
          )
        ),
        "\n\n"
      ),
    )
  ),
)

The current conversation is exactly about standardising the distribution / module order and what is intended by it.

finanalyst avatar Jun 25 '23 18:06 finanalyst