-
Notifications
You must be signed in to change notification settings - Fork 15
Use md"...." for markdown comments? #29
Comments
I've go a @doc """
""" { :format => "md" } ->
myfunc(x) = x though that's perhaps a bit of a pain to have to write. Setting a module-level choice of formatting I've recently (in the last few days) moved the formatting code to Lexicon.jl, which isn't currently registered. This makes Docile format agnostic I hope. Docile is just storing the docstrings as raw strings now, previously I was parsing to Markdown.jl ASTs at module load time. |
I think it's much cleaner for the object to know its format (and output via Then, as in my original proposal in JuliaLang/julia#3988, Docile wouldn't store strings at all:
|
Would the type Markdown
content::String
end or would the content be converted into an AST when a module is loaded? Docile
Wrapping the strings in |
@MichaelHatherly, there is no way to interpolate into string macros (this is the tradeoff for no escaping); if you need that (rarely, I think?), you would need to do I agree that it would make the most sense to store it as a
|
You can do string interpolation in a string macro, but you have to implement it yourself. You get the raw string, and do your replacements. You can return expressions that reads local variables just like a normal
in the AST. |
I suspect having abstract Docstring
type Markdown <: Docstring
content::String
end
# ... Or is there already an abstract type in Base that could be subtyped instead? |
I think we might want |
Yes, that makes sense. |
I don't think they should be subtypes of anything (other than |
@ivarne, I think in this context we wouldn't want to implement "manual" interpolation. The reason is that the lack of interpolation here is a feature: it let's you easily write documentation examples that contain interpolation (meant to be printed literally as |
That is a valid concern that I support. Programmable documentation should probably be a little less surprising. I just said it was possible with string macros, and how, not that it was desirable. |
Perhaps an explicit @doc md"""
1 + 1 = $(1 + 1)
"""esc ->
f(x) = x Not such a high priority though. |
Closed by #35. |
I should mention that, although I haven't implemented it yet, I was going to have something like an I don't really agree with disallowing plain strings as documentation – why not just default to the common case (i.e. treat the string as if it were Regardless, Docile looks like it's coming along really nicely. Soon I should have time to give Markdown.jl a much-needed overhaul so that it's ready for things like this. |
I've got basic interpolation going, it's in interpolate.jl. Docile's defaulting to treating strings as markdown, and that can be set using the @docstrings [ :format => MarkdownDocstring ] Subject to naming changes. Since there's only a markdown parser currently that setting's kind of redundant, but having a default has been much nicer than changing all the docstrings I've got to There's a few quirks I've come across in Markdown.jl, which I'll post as issues tomorrow sometime. |
Sure, go ahead, I'll definitely try and fix any problems. More generally I want to aim for the new Common Markdown standard, which should iron out a lot of quirks. Are those interpolate.jl functions parsers in the Markdown.jl sense? In principle you should be able to inject the |
Yes, aiming for the standard would be great. I wasn't aware of the Markdown.jl parser interface, so there're probably not going to fit straight in. |
I'm not sold on the need for interpolation here; it seems like an unnecessary complication. In the rare cases where it is needed, it seems like one could just use |
To avoid having to type No need for the extra complication of interpolation or calling |
What does In what project would most of the docstrings require pervasive interpolation? My comment was predicated on the guess that interpolation in docstrings will be rare. (If the project wants to add some boilerplate to the end of every docstring, wouldn't it be better for the project to define a custom string macro It just seems cleaner and more flexible to me to let each documentation object |
Since Interpolation could be used to create REPL-like code examples (such as python docstrings sometimes have) with results without having to write the results into the string itself: @doc md"""
**Examples:**
```julia
julia> [1, 2, 3, 4]
$(stringmime("text/plain", [1, 2, 3, 4]))
...
""" After writing that out though, perhaps there's a better solution to that particular problem. My biggest problem is having to specify what kind of documentation I'm writing for every single docstring. It is only 2 characters, but if I can just chose a default and not have to worry about it after that I'd rather do that. I'd guess that for most packages docstrings will be written in just one format, rather than a mixture. |
That's exactly the right idea – we want to write things like @doc """
Returns a random walk, which will look something like:
$(plot(y=randwalk(100), x=1:100))
* `n`: The number of samples in the walk.
""" ->
randwalk(n) = cumsum(rand(n)) The idea is to embed that However, note that for this to work you can't just apply a function to the string, you have to let the string macro do its work at compile time. The That said, I think we can worry about the technical details once the |
@one-more-minute, that's a good example. However, I think that interpolation is probably the wrong model here, since I don't think you want to execute the interpolated code (e.g. the So, it might be better to have a custom markdown extension giving a syntax for embedded Julia code to be evaluated and substituted when the AST is parsed. But then it won't rely on interpolation. And you probably don't want to use |
Regarding a custom extension for embedded julia code, would fenced_code_attributes be sufficient for this? |
+1 to @stevengj 's comments. Being able to evaluate code for interpolation during loading of a module is not a reasonable requirement. In many cases, code required for that will not even be available yet. You also might want to embed a plot in the docs for a package that doesn't itself require plotting. |
@JeffBezanson, yes, I'm beginning to agree with that reasoning more. The interpolation is fine for really simple gimmicky examples, but doesn't work for anything more complex. No need to over-complicate things for no gain. |
I don't think the argument was against interpolation per se, just against evaluating code while the module is loading. That's fine, you can evaluate docs just after the module is loaded and cache the output, or even evaluate the docs lazily as Steven has suggested. (I prefer the former option myself, since it means you only pay the price of evaluation once, rather than every time you load the doc string – but that's a technical detail). |
Everything must be deferred as late as possible. Load times are already crushing us. |
Sure, but that's going to be solved by caching compiled code in 0.4, right? I completely agree that we need to optimise load time as far as 0.3 is concerned, I'm just suggesting that we might extend the caching idea to docs so that laziness isn't necessary in the first place. It may be that this is an extra complication that isn't worth dealing with in this first iteration though, in which case laziness seems like a fine way to go. |
Caching doesn't help during package development when you are repeatedly re-loading. We don't want to punish package developers with long load times for writing lots of documentation with excellent examples :) |
@JeffBezanson Agreed, just documenting a package shouldn't add to load times unnecessarily. @one-more-minute I've done some pre-compilation trials with Docile, and everything appears to work fine. Until that's finished though, we'll have to be lazy I'd think. |
@JeffBezanson That's a good point. If we need laziness as an option even when we do have caching then it makes a lot of sense to start with it. @MichaelHatherly Sure, that seems fair. Ultimately Markdown.jl is agnostic to all this stuff anyway – it will just dump the code in the AST and give you the tools to evaluate and render as you want. |
@one-more-minute, "lazily" doesn't mean that you pay the price "every time you load the doc string". It means that you perform computation as late as possible—only when you actually need to use the results—but then you cache the result for subsequent use. That is, the sequence I'm proposing is:
|
I do see what you mean by loading lazily, but since you're only likely to check a doc string once or twice per session it amounts to the same thing. As soon as you reboot Julia, you have to pay the evaluation price again for each doc string you look at. This is the problem that more persistent caching would solve. |
I see your point, but maybe we should wait to see how things work out in practice. We can always add offline documentation caching later, if incorporating expensive dynamically executed examples in documentation proves popular. Maybe it's better to hold off on dynamically executed examples entirely for the time being...it adds a lot of complexity when Julia still needs basic docstrings. And without dynamically executed examples, Markdown can be sent to the IJulia front end without parsing it at all (since Jupyter will render the raw |
Closed, since both base and Docile have implemented. |
Using an explicit prefix, via a string macro, has two advantages:
$
or\n
etcetera.The second point is more of a tradeoff, I suppose, but typing two extra characters seems a small price to pay. The first point is extremely compelling to me.
("..." strings could default to text/plain, or even be disallowed.)
The text was updated successfully, but these errors were encountered: