-
Notifications
You must be signed in to change notification settings - Fork 22.5k
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
[Markdown] Decide what to do about <dl> #4367
Comments
My vote is for the "Extend GFM" option. My main concerns with this are:
|
Here is another idea, how about we re-use markdown tables for definition lists? We could turn 2-columned tables with headers like in the example into definition lists. Example:
Upside:
Downside:
|
Extending GFM feels a bit like going towards a MediaWiki-esque syntax in my opinion. Nesting is an interesting point. Even if we went into the table variant @Gregoor described, that wouldn't save us completely (think of nested tables). Ideally, I'd like to see some generated. |
I'm with extending GFM. For your edification, below is HTML, Kramdown and table version taken from a page in the docs.
Raw HTML version
Kramdown versionCascade and inheritance CSS selectors The box model Backgrounds and borders Handling different text directions Overflowing content CSS values and units Sizing items in CSS Images, media, and form elements Styling tables Debugging CSS Organizing your CSS Table version
|
I was careless when I said this would all just work - needs a bit more thought for this case. While you can express a nested list kind of unambiguously you can't do so with this definition list syntax. That's because the first line has no marker. To markdown "ordinary rules" the new definition list looks like line continuations. Here is an example showing it failing:
I'm not sure how you would resolve this case in a way that works with github :-( |
I know there's at least one partial implementation of the definition list: https://github.com/Symbitic/remark-plugins/tree/master/packages/remark-deflist. It has a limitation of only supporting single-paragraph definitions. Looking at the implementation, I'd guess that generalizing it to any sort of block is rather more complex. I'm not quite sure if can be done without actually implementing a new syntax at the micromark level. Overloading listsI have another proposal, inspired by the table suggestion and reStructuredText's list tables: how about using a magic unordered list? We could have something like this: source
rendered (GFM)
rendered (Yari)
There's other variations you could do (e.g., using a magic word at the start of each It has the same upsides as the table: no new syntax and renders nicely in GitHub. It also adds a couple of benefits on top: it doesn't use the unpleasant table syntax and accommodates block-level content inside definitions (raised by @wbamberg). It has a new downside of relying on a magic word, but we have already done that for notes and warnings. As an implementation, transforming the underlying |
What I like about @ddbeck suggestion of overloading lists #4367 (comment) is that it allows nested deflists, which is something that we do have in our sources. If we went this approach would be good to have a more visible keyword/list marker. What I like about using the extended GFM is that it is clearly NOT an ordinary list. But that only supports single level. Can we live with that? Well, we can if we explicitly state that for the small number of nested definition list cases you can use HTML. Upshot, IMO the overloaded lists is the best option I've seen so far. |
By "extended GFM" do you mean what Kramdown does or something else? Because Kramdown does allow nesting (although the Unified implementation Daniel linked to above does not). I'm not happy about it but I do think it will be difficult to live without nesting in our current docs. |
I meant Kramdown. How does that do nesting? |
According to https://kramdown-sandbox.herokuapp.com/ , this markup:
...gives us this HTML: <dl>
<dt>One</dt>
<dd>a thing
<dl>
<dt>A</dt>
<dd>another thing</dd>
<dt>B</dt>
<dd>a different thing</dd>
</dl>
</dd>
<dt>Two</dt>
<dd>back to the outer list</dd>
</dl> |
For authoring, I think I like the Kramdown syntax better, but @ddbeck 's would be OK too. And I agree that we should consider how hard it is to implement extensions. I was going to say that as far as I know we almost never use multiple definitions for a single term, so it would probably be fine not to support this. But then I looked.... and we do things like this: content/files/en-us/web/javascript/reference/global_objects/array/slice/index.html Lines 31 to 53 in d963821
...which is obviously broken. There aren't too many of these (in JS at least), and I'd be open to trying to fix this markup. Unfortunately it's hard to automate since sometimes there might be actual real multiple definitions. I think hardly ever though. |
Thanks @wbamberg Yes, we use nested lists a bit, mainly for options of arguments. I have a slight leaning towards Kramdown syntax too (for the same reason). As shown below, neither is awesome in github. One
Two
|
I really like @ddbeck’s suggestion in #4367 (comment) best. I think that’s the easiest thing for authors/contributors — it doesn’t require them to learn a new syntax. That along with the other advantages it has (ability to nest, ability to contain block content) seems to make it a pretty neat solution. Also, I have a lot of experience creating and wrestling with normal lists in markdown — and I imagine we all do, and most contributors probably would as well. And that experience includes knowing already about some of the quirks it has — e.g., how to do nesting correctly, and how to include block content. I think the "Extend GFM" option could possibly also be a viable solution, but I can’t speak from experience, because I’ve never used it anywhere yet — in contrast to having a lot of experience with using the normal list syntax in @ddbeck’s suggestion. So it seems like the "Extend GFM" option is more of an unknown than the just-use-normal-lists-with-magic-keyword solution that @ddbeck proposed — that is, the "Extend GFM" option is more of risk to buy into than solution @ddbeck proposes. I’d also be happy with the table-based way that @Gregoor suggested in #4367 (comment) — if it handled block content. But from what others have said in this issue and elsewhere, it sounds like it doesn’t handle block content. If so, that’d kinda make it seem to be a non-starter. I most dislike the "Use raw HTML" option, by a wide margin. Adopting that and telling authors/contributors they need to use it would seem to me to sort of being giving up on the fundamentals of why we’re making this move to begin with. If we’re going to help authors move away from being required to author in HTML to contribute to MDN, let’s really move away — all the way. |
I can live with either, and I keep changing my mind about which I prefer - right now it's the @ddbeck solution because I value github rendering. But if we did that I would prefer a much more obvious deflist identifier string. I think there is clear leaning towards the two discussed above ^^^. Are we at the point of a vote? |
Something to think about for any choice here: I suspect that, longer-term, there will be a lot of interest in giving structure to the things that we typically use definition lists for. For instance, it might be really nice to have separate files for object properties, with a more structured format (that we can check against IDL and the like), that can be used as source data for generating definition lists. It's likely that whatever we choose here is going to end up transitional (or niche use). |
So that would be something like what we do with https://github.com/mdn/data for CSS syntax now, right? I can imagine that as the basis for object properties, we could maintain copies of the IDL blocks, and use an IDL parser and some code to generate the documentation stubs that we then populate. I think that unlike the CSS syntax case, we would need something more complicated like that in this case, because for object properties, we also have a lot of unstructured free-form prose that accompanies the structured (from IDL) information. But all that said, once we get to that point, it seems like we’d still have the same problem as we do now, as far as needing to decide on some list syntax for authors to use. I mean, the authors wouldn’t need to touch the structured (IDL) source — but they’d still need to author the part that provides the free-form prose descriptions, associated with (mapped to) each IDL member. The only alternatives I could imagine for managing the free-form prose in a way that associated it with the structured parts would be to add comments to the IDL, and extract those comments in the build — or else to manage the whole thing as JSON instead. But those clearly have pretty big disadvantages over having the source for the prose parts be in markdown. |
@sideshowbarker I don't want to get too far off-topic here, but in this case, I'm talking about revisiting some of the ideas that came out of Stumptown. For content about things which are themselves highly structured, I think there's the possibility of doing stuff like tightly controlling the form and sequence of Markdown headings to describe named parts of interfaces. It decouples authorship a bit (i.e., you're writing sections that become entries in a definition list), but that might be desirable, because you can use that structure produce other content (e.g., reuse across pages or editor tooltips) from the same source. |
I think this is the same thing I talked about upthread: #4367 (comment). But two things, as noted in #4367 (comment):
So we still need a way to represent |
I'd like to try to resolve this, and unless more facts come to light, or unless @Gregoor thinks it's not practical to implement it, I'm in favour of the Kramdown syntax. The main reason for this is that it's by a long way the most common Markdown syntax for
Please see also this thread about the possibility of adding I think it's a little misleading to say that the One interesting note from the CommonMark discussion I linked above is that the Kramdown syntax is awkward to parse because you have to backtrack after finding the
That would rule out: <dl>
<dt>A term</dt>
<dt>Another term</dt>
<dd>A definition</dd>
</dl> ...as well as: <dl>
<dt>A term</dt>
<dd>A definition</dd>
<dd>Another definition</dd>
</dl> |
I agree that’s a pretty compelling reason (the possibility for forward compatibility).
I wonder what instances (if any) we have in MDN of existing article using using more than one consecutive At least outside of MDN, it’s not hard to find quite legitimate cases of it — for example, I know it’s used in the markup for some specs (I think even in the HTML spec). It’s not uncommon to want to associate multiple ( |
Here’s one example of adjacent-sibling
But that’s just one example among many such cases in the HTML spec — if you go to https://html.spec.whatwg.org and open the devtools console and do this: document.querySelectorAll("dt + dt") …that returns 425 nodes. |
As far as instances of adjacent-sibling
…and that returns around 94 instances — though those are all concentrated in just 15 files:
https://github.com/mdn/content/blob/main/files/en-us/web/html/inline_elements/index.html#L102 has the largest number of them — but that’s an anomaly markup abuse. Not sure why it’s being used there, but it seems like it should be replaced with some other markup (regardless of the resolution of this issue). https://github.com/mdn/content/blob/main/files/en-us/web/css/list-style-type/index.html has the next-largest number, and looks like a legitimate usage; see the rendered view at https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-type#values — for example:
There are a couple more CSS docs that have cases, and six JavaScript docs that do — including https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness#when_to_use_jsxrefobject.is_versus_triple_equals:
Other examples:
|
After looking at the existing instances in MDN and at the instances in the HTML spec, I can’t really find any cases where it seems strictly necessary to mark them up with adjacent-sibling What I mean is that, in general, it seems like for any adjacent-sibling
I think a reasonable case could be made about that in fact being better for readability/usability as far as user experience.
Given the above, it seems like it’d be OK/reasonable to impose such a restriction. The authoring guidance for it would seem to be pretty simple to document (e.g., “just separate multiple terms with commas on a single line, rather than putting them on separate lines”) — but ideally we’d want to be able to lint for it too. However, given the following:
…then I’m guessing that trying to lint for it for it would run into the same problem. That is, if we could reliably parse for such cases to begin with, why would we not want to just allow them? So I think it’d be fine to still impose the restriction even if it’s not something we could lint for. |
Since there was more discussion about linting Kramdown-style lists, I spent more time trying to figure out where the sharp edges are with that (apart from parsing, which we've already acknowledged). I'm a bit troubled by them because I don't have a lot of ideas about how to sand down these edges (unlike the stuff we've considered for accepting the GFM table syntax or the solution we came up with notes and callouts). I'd really like some ideas because I don't have a lot of mitigation strategies that apply here. CommonMark previewsIn the one-level case, Kramdown style looks OK in GitHub: Source`callbackFn`
: Function to test for each element
`thisArg`
: Optional. Value to use as `this` when executing `callback`. CommonMark rendering
The problem arises when you've got nested lists: Source`callbackFn`
: Function to test for each element
`element`
: The current element being processed in the typed array.
`index`
: The index of the current element being processed in the typed array.
`array`
: The typed array `some` was called upon.
Here's a second paragraph.
`thisArg`
: Optional. Value to use as `this` when executing `callback`. CommonMark rendering
It both flattens the list and turns subsequent blocks in the nested definitions into source blocks. This makes the preview in my editor unhelpful. As far as I can tell, there's no way I can stylesheet my way out of this problem. All my solutions to this problem are kinda poor and I'd like to hear ideas on how to counter this. It's really frustrating to me that there's no gentle upgrade path for opting into this one Kramdown feature (especially since we're not using Kramdown generally). Conflict with PrettierWhile experimenting, I also ran into this problem: Prettier really wants to wreck these lists (turns out I have Prettier formatting Markdown files by default). Over in #4325 (comment), we talked about the possibility of using Prettier to make working with GFM tables a bit nicer. This syntax puts a roadblock up for that. The easiest solution is to wrap those sections with Prettier opt-outs: <!-- prettier-ignore-start -->
`callbackFn`
: Function to test for each element, taking three arguments.
A second paragraph.
`thisArg`
: Optional. Value to use as `this` when executing `callback`.
<!-- prettier-ignore-end --> Though that adds a weird, extra obligation for using these lists. (Prettier does support plugins, but it's not yet clear to me how easy it is to wrap the existing behavior and apply our special case.) |
Daniel, Gregor and I just had a discussion about this issue, which I'm going to capture in this comment. The concerns Daniel raised in #4367 (comment) are significant, especially the one about Prettier. What's worse is that they are symptoms of a general problem with adopting a "CommonMark-unfriendly" syntax: so much of the tooling tends to want CommonMark, that we're likely to encounter versions of this problem again, even if it were practical to fix the issue with Prettier. So we should consider a principle that we try to stay "CommonMark-friendly" even when we are extending the CommonMark/GFM syntax, and that means reconsidering something like Daniel's The main reason to want to use Kramdown syntax would be that it's well-specified and has working implementations, so there's good reason to believe that the edge cases have been worked out. I'm a bit anxious to invent a new syntax and have to go through that. But perhaps we can make this less of a problem if we support a limited version of If we think we can get away with a syntax in which a
...that is, interpret a Or maybe for nicer GitHub formatting, something like:
...which would render in GitHub like:
If authors really need full |
FWIW I really like the "nicer GitHub formatting" above #4367 (comment) Other than the colon, this is how I represent definition lists in markdown normally. |
I have had a go at writing this up -> #4987. |
I think this can either be closed or moved to the Discussions tracker? |
Yeah, I left this open because I hadn't yet got around to updating the spec for the conversion: #3350 (comment) but I have done that now. |
In MDN we use
<dl>
(description lists aka definition lists) quite extensively, and they're not natively supported in GFM.A quick look at the JS docs tells us what we already know: in 922 pages:
They're most commonly used for:
Some options:
Generate them
If we could generate these lists (in a macro, or directly in Yari) we could of course emit HTML, and could then use
<dl>
.We could possibly generate the lists of properties and methods in the future, because they are lists of links to separate pages. But it's difficult to see how we'd do the same for lists of parameters or exceptions. So this definitely isn't a solution now and probably isn't a complete solution ever.
Stop using them
There are so many of these that converting them would be hard, and it's hard to argue that they are not an appropriate choice for things like lists of parameters.
Use raw HTML
Unlike something like a note, where you just need opening and closing HTML tags and can have Markdown inside, using raw HTML for
<dl>
commits you of course to raw HTML for<dt>
and<dd>
as well. So you will end up with a lot of raw HTML here. It's not an attractive option.Extend GFM
This leads us to the extend-GFM option. The most popular choice here is the one used in Kramdown:
Kramdown describes this syntax in some detail: https://kramdown.gettalong.org/syntax.html#definition-lists and it's not very clear to me how much we would want to adopt this definition wholesale or how much we would want or need to constrain it. Not to mention what it would be like to implement: it would be really interesting to hear what @Gregoor thinks about that. I don't know if there is already a Unified handler to support this syntax.
(One obvious point is that we wouldn't support inline attribute lists (IALs, https://kramdown.gettalong.org/syntax.html#inline-attribute-lists.)
The text was updated successfully, but these errors were encountered: