6 ms·
Nested code fences in Markdown
- epage 9mo ago> In fact, a code fence need not consist of exactly three backticks or tildes. Any number of backticks or tildes is allowed, as long as that number is at least three Unfortunately, some markdown implementations don't handle this well. We were looking at using code-fence like syntax in Rust and we were worried about people knowing how to embed it in markdown code fences but bad implementations was the ultimate deal breaker. We switched to `---` instead, making basic cases look like yaml stream separators which are used for frontmatter.
- bityard 9mo ago`---` is already used in Markdown for horizontal rules?
- _ache_ 9mo agoYeap, along with `+++`, `**` and mixing if I remember correctly. I don't understand the logic of using an non-standard syntax because some non-standard implementations may not render correctly. Actually, yes, now you know for a fact that none of the Markdown implementation will render it correctly. So, I guess, they used `~~~` instead and it was an error in OP post.
- nicoburns 9mo agoThe problem here is that if you use ``` as a token in a non-markdown language, then it's going to be very hard to embed that code in a markdown code block. That problem doesn't happen with other syntax as it's already escaped by the code block. `---` inside a markdown code block will render as a literal `---`.
- yencabulator 9mo agoTo embed content with multiple sequential backticks, use more backticks than the max run.
- nicoburns 9mo agoIn theory, yes. But not all markdown implementations support this properly.
- yencabulator 9mo agoThe CommonMark spec even has an example test case! The excuses for poor implementations are pretty thin.
- lilyball 9mo agoNot all markdown implementations are CommonMark
- yencabulator 9mo agoThere's not much reason to be anything else than CommonMark + extensions.
- lilyball 9mo agoFor new implementations, sure. But it's harder to change existing implementations (anything not already CommonMark-compatible will introduce unexpected changes to existing content if you switch to CommonMark), and especially for anything that's not being actively developed it's unlikely to ever change.
- zelphirkalt 9mo agoAll this complication seems to stem from the simple fact, that the fences don't have a recognizably distinct start and end marker. It's all "`" or "~", instead of one symbol at the start and another, different symbol at the end. And then going into the different numbers of backticks or tildes. Why add such ambiguity, that will only make it harder to parse things correctly? This immediately raises the question: "What if I start a block with 4 backticks and end it with 5?" All these complications would have been avoidable with a more thought through design/better choices of symbols. For example one could have used brackets: [[[lang code here ]]] And if one wanted to nest it, it should automatically work: [[[html html code [[[css css code ]]] [[[js js code ]]] html code ]]] In case one wants to output literally "[[[" one could escape it using backslash, as usual in many languages. In a parser that would be much simpler to parse. It is kind of like parsing S-expressions. There is no need for 4 backticks, 5, or any higher number. I don't want to sit there counting backticks in the document, to know what part of a nested code block some code belongs to. It's a silly design.
- embedding-shape 9mo agoIndeed! Last time I dealt with this exact problem in a toy application made for myself, I ended up making the markdown parser only read ```$LANG syntax, and making it assume just ``` is a closing tag, not accepting it as a opening tag. Made it easier for the pretty syntax formatter to do it's job too, as it no longer has to figure out the language.
- armchairhacker 9mo ago> In case one wants to output literally "[[[" one could escape it using backslash, as usual in many languages. Sometimes you want to paste a large region of code into a code block, and escaping the content is harder than fixing and start and end delimiters. This matters particularly in Markdown, where embedding large regions of code or text is common, whereas other languages you’d put it in its own file. So I still suggest the ability to change the number of open and close brackets. Then you’ll also need an implicit newline or other way to distinguish content that starts with an open bracket.
- charles_f 9mo ago
- codazoda 9mo agoI might be able to use this, especially in LLMs where I ask them to give me things in code fences all the time. If I ask for markdown in a code fence, it all falls apart. If, however, I asked for markdown in a ~~~ code fence, or even ~~~~~, all would be right with the world, since they typically use ```.
- qingcharles 9mo agoI was debugging code last night that uses ~~~ as a delimiter in a string. At least, as you say, you can go crazy and use ~~~~~ to get around it.
- chuckadams 9mo agoMarkdown's parser seems to be a fascinating anomaly: a specification that consists entirely of exceptions and corner cases.
- metalliqaz 9mo agolol this is a great wording for something I've not been able to express before I sometimes wonder... is it Markdown's specification chaos the reason for its success? Maybe it was just barely enough spec to be usable but also small enough to allow anyone to make an implementation that seemed right. No qualifications to fail. Thus, it proliferated. The xkcd[1] problem is a darn shame, though. At least CommonMark exists for people who want to point to a "Standard" [1] https://xkcd.com/927/ https://xkcd.com/927/
- TimorousBestie 9mo agoMarkdown is definitely a case of “worse is better” and it helped that it was half-canonicalizing ASCII formatting workarounds that had been in common use for decades.
- chrismorgan 9mo ago… except its link syntax. That is an abomination that had never existed and should never have existed.
- PaulHoule 9mo agoMy feeling overall is that I can't get into flow writing Markdown, there are just enough things wrong that I never feel completely comfortable while doing it. It seems that in the HTML 5 age there is some subset of HTML which should be completely satisfying for anyone. Maybe it is custom components that work like JSX (e.g. <footnote>) or something like tailwind. Editing HTML with one eye on a live view is more pleasant for me than anything else. Every kind of rich editor that looks like Microsoft Word (esp. Word!) comes across as a dull tool where selections, navigation, and applying styles almost work. There's got to be some kind of conceptual problem at the root of it all that makes fixing it like pushing around a bubble under the rug. I want to believe in Dreamweaver but 2-second latency to process keystrokes on AMD's best CPU from 2 years ago and the incredulous attitude Adobe support has about the problem makes it a non-started [1] [1] if I ran an OS failing to update the UI in 0.2 sec gives an immediate kill -9 and telemetry of the event will get you dropped out of the app store not much later. I'm not saying rendering has to be settled in 0.2 sec but there has to be some response that feels... responsive.
- mohsen1 9mo agoI love hacker news! You learn something useful here and there. I always used html elements like <pre /> and <code /> to go around this in the past
- zokier 9mo agoI realize that it would be somewhat antithetical for markdown, but I increasingly feel that length-prefixing everything makes lot of stuff easier at pretty low cost. Anything depending on delimiters or start/end tags inevitably ends up with difficult quoting rules or some other awkward scheme (like seen here).
- data_ders 9mo agoTIL about triple curlies! mind blown
- maximgeorge 9mo ago[dead]
- Igor_Wiwi 9mo agoI will use it as a rendering benchmarking for mdview.io https://mdview.io/#mdv=N4IgbiBcCMA0IBMCGAXJUTADrhzWOAtgnjgMID2ATgKYCesABEgDYuMDmVFA7gHaMArgAdIWLH3F8AfrKmMABkqkAKCgH0KASgC0OgHQAfANrqAuoamzpOAiBQALGoRqkQLAJYcHKWzmG0AM40vlA4CBQAxoF+IABmFHwoAMoeAF6uUNAA7HaefDQAEjRePnjQ+rk4+TQA6h4IjnjZAGwADHa0SAg0VABiiaFiIIFIfDEgnTR8PVQAsr2ESA14KFSCNFMzvQAyqDQAHqvrm+EehACSkYkTkHGswXYRkQBySC5ugkkeKCw0CPpiLFApFuGwAJp4NoAXxA0KAA https://mdview.io/#mdv=N4IgbiBcCMA0IBMCGAXJUTADrhzWOAtgnjgMI...
- starkparker 9mo agoThis is also how you handle adding code blocks in GitHub comment suggestions, fwiw. ````suggestion This example should instead be: ```basic 10 PRINT "LOL" 20 GOTO 10 ``` ````
- Helmut10001 9mo agoYes, this is also how JupyterBook [1] does it (I think v1 uses Myst Markdown parser). I found this to work excellent! [1]: https://jupyterbook.org/ https://jupyterbook.org/
- behnamoh 9mo agowhat if you want to show ````? should you add ````` tags then?
- zahlman 9mo agoYes; TFA contains enough explanation to make it clear how to extend this arbitrarily. See also https://meta.stackexchange.com/questions/82718 https://meta.stackexchange.com/questions/82718 .
- culi 9mo agoDoes this work with arbitrary depth? Can I do `````ts const Accordian = styled.details<{ isAprilFirst: boolean; }>` ````css accent: rebeccapurple; font-family: ${ ```js props => props.isAprilFirst ? 'Comic Sans' : 'Time New Roman' ``` }; ```` `; `````
- hun3 9mo agoSure, as long as you don't run out of `s
- pratikdeoghare 9mo agoI faced this problem when designing my own notation [1]. Solved it by surrounding code with more ticks than maximum number of consecutive ticks inside its text. This allows arbitrary nesting. Postgres solves it by using `$something$ whatever $something$` [2]. [1] https://github.com/PratikDeoghare/brashtag https://github.com/PratikDeoghare/brashtag [2] https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING https://www.postgresql.org/docs/current/sql-syntax-lexical.h...
- zahlman 9mo ago> Solved it by surrounding code with more ticks than maximum number of consecutive ticks inside its text. This allows arbitrary nesting. So, the same thing that Markdown does, as described in TFA?
- rasur 9mo ago#+BEGIN_SRC lolcode blah #+END_SRC org-mode to the rescue ;p
- zelphirkalt 9mo agoThough it does get a little funny, when you want to write org mode code blocks, that contain actually org mode code. If I recall correctly a "+" at the beginning of the line is then used for escaping?
- rasur 9mo agoI've not had time to explore fully, but I just cracked open emacs on this windwoes machine, and tried it, and it auto-added a comma to the beginning of a nested #+BEGIN_SRC...
- trvz 9mo agoMarkdown assumes the user won’t do anything silly, and I’m fine with that. Rather the people enabling such behaviour are annoying.
- zahlman 9mo agoI hoped this would have some discussion of the design rather than simply saying how to do it, because I already knew (because it's come up on Stack Overflow / Stack Exchange meta a few times).
- deleted 9mo ago[deleted]
- rednafi 9mo agoAh, YAML and Markdown, two beautiful accidents of tech. It still boggles my mind that we collectively couldn’t come up with a post hoc spec and fix all the warts with a strict parser for either of them. Sure, it would break quite a bit of existing stuff, but the pain would probably be worth it.
- zokier 9mo agoCommonMark is such posthoc spec
- rednafi 9mo agoYet there’s GitHub-flavored Markdown, GitLab-flavored Markdown, and so on. Since people just write Markdown without caring about the parsers (nor should they), they break too often when you try to move them around. It’s even worse with YAML.
- Silphendio 9mo agoBoth of those flavors are based on the CommonMark spec. There's just some extra features and some forbidden html.
- esafak 9mo agoMarkdown is so fragile. When you start combining tables, code blocks, and collapsible sections it falls apart. I wish there was a robust way to emit GFM from something more solid.
- themk 9mo agoPandoc? It might help you. If you are programatically generating content, you can emit the JSON intermediate format. If you are hand writing, you can use something more sane like djot.
- pyrolistical 9mo agoAs long as you are not nesting it works pretty well. For anything more complicated, just give up and use html
- nick238 9mo agoDidn't know this. It kind reminds me of MIME multipart messages (used in email attachments, MMS, etc.) where the header includes a "boundary" tag which the parser will look for to terminate the part. It feels strange, like it could be some injection risk where if the file knew what the boundary was going to be, it could desync the bounds and turn one malicious, inactive file into one or more bad files.
- manwe150 9mo agoI believe the spec intends that a decent mail handler is required to scan the text and make sure the delimiter is not present or pick a different one. Or use a different encoding (eg base64) to prevent conflicts if you want streaming ability. Although bugs of course could break the best of intentions
- runfaster2000 9mo agoC# has this same model: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/reference-types#string-literals https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...