Markdown Is a Terrible Language

๐ **Source:** [Markdown Is a Terrible Language](https://www.youtube.com/watch?v=DWcqbPm_Rn4)
> [!note]+ Document Notes
> tags: #markdown #markup-languages #web-development #parsing #programming-languages #syntax #html
> author: Theo - t3โคgg
> source: YouTube
> reference: https://www.youtube.com/watch?v=DWcqbPm_Rn4
> date created: 2024-12-19 14:22
>
> # ๐ท๏ธ Title: Markdown is a terrible language
>
<!-- deep-read:sections start -->
## ๐งฐ Action Inbox
- [H1] Evaluate markdown alternatives for documentation systems โ current parsing vulnerabilities #web-development
- [H2] Audit existing markdown implementations for ReDoS vulnerabilities โ CVE examples shown #security
- [H3] Consider build system approaches for markup languages โ compile-time hooks #architecture
## ๐งญ Table of Contents
- [[#๐ Summary]]
- [[#๐ Main Content]]
- [[#๐๏ธ Notes]]
- [[#๐ References]]
- [[#๐ฃ๏ธ Paraphrase]]
- [[#๐ฐ Newsletter]]
- [[#โ
Action Items]]
- [[#๐งช Hypotheses]]
- [[#๐ Methodology]]
- [[#โ Questions]]
- [[#๐ฎ Future Research]]
- [[#๐ก Implications]]
- [[#๐ง Learning Styles Assessment]]
- [[#๐ Accessibility Assessment]]
- [[#๐ DEIB Assessment]]
- [[#โ
Logical Validity]]
- [[#๐ก๏ธ DARVO Analysis]]
- [[#๐ฏ Conclusion]]
### ๐ References
- [Why the heck are we still using Markdown?](https://blog.brockmckegney.com/posts/why-are-we-using-markdown/) (Original article)
- [RWX CI Platform](https://swade.link/rwx) (Sponsor)
## ๐ Summary
- Theo critiques Markdown's fundamental design flaws while acknowledging his historical love for the language
- The core problems include ambiguous syntax, security vulnerabilities (ReDoS), and scope creep beyond its original purpose
- Markdown has evolved from simple markup to requiring full HTML parsing and complex compilation
- Multiple syntaxes can produce identical output, making parsing exceptionally difficult
- The language suffers from legacy decisions dating back to email/Usenet conventions from the 2000s
- Bottom line: Markdown succeeded as simple markup but fails when used as a pseudo-programming language
## ๐ Main Content
Theo examines a critical analysis of Markdown, explaining how a language he once loved enough to only submit Markdown resumes has fundamental flaws. The discussion covers how Markdown's flexibility created multiple ways to express the same formatting (bold, italic, headers), leading to parsing nightmares. Security vulnerabilities like ReDoS (Regular Expression Denial of Service) affect major implementations due to complex regex patterns. The inline HTML feature, while powerful, breaks the simplicity promise and creates XSS attack vectors. Modern usage requires features like footnotes, math typesetting, and custom styling that transform simple transliterators into full compilers with context-sensitive grammars. The author argues for purpose-built tools with proper build systems rather than continuing to extend Markdown beyond its capabilities.
## ๐๏ธ Notes
#### โฑ๏ธ [00:00](https://youtu.be/DWcqbPm_Rn4?t=0) โ [H1] Theo's historical dedication to Markdown
- Key idea: Refused job applications unless he could submit Markdown resume
- Evidence: "I literally didn't apply to jobs at companies where I couldn't submit my Markdown resume"
#### โฑ๏ธ [01:42](https://youtu.be/DWcqbPm_Rn4?t=102) โ [H2] Markdown scope creep problem
- Key idea: New file extensions embedding other content signals overextension
- Evidence: "Once we got to the point where we were making new file extensions to embed other types of content into our Markdown, we were probably over the line"
#### โฑ๏ธ [03:21](https://youtu.be/DWcqbPm_Rn4?t=201) โ [H3] RWX sponsor segment
- Key idea: Local CI testing without commits using cloud infrastructure
- Evidence: "All you have to do is run their CLI to trigger a run without having to commit the code"
#### โฑ๏ธ [05:45](https://youtu.be/DWcqbPm_Rn4?t=345) โ [H1] Multiple syntaxes produce identical output
- Key idea: Two completely different markdown syntaxes can render identically
- Evidence: "There is almost no syntax overlap between these other than the block quote at the end"
#### โฑ๏ธ [07:23](https://youtu.be/DWcqbPm_Rn4?t=443) โ [H2] Bold/italic syntax complexity
- Key idea: Multiple valid ways to write bold create parsing nightmares
- Evidence: "You can write a bold in different ways. You have the double star syntax, double underscores, or the B tag"
#### โฑ๏ธ [09:15](https://youtu.be/DWcqbPm_Rn4?t=555) โ [H1] ReDoS vulnerability example
- Key idea: Regular expression denial of service affects Markdown parsers
- Evidence: "This 6.9 severity level CVE for Markdown it. This is a legit DoS vulnerability"
#### โฑ๏ธ [11:32](https://youtu.be/DWcqbPm_Rn4?t=692) โ [H2] Inline HTML problems
- Key idea: Markdown parsers must also handle HTML parsing complexity
- Evidence: "The real issue is that to ship a Markdown parser, you also need to ship a friendly HTML parser"
#### โฑ๏ธ [14:45](https://youtu.be/DWcqbPm_Rn4?t=885) โ [H3] Feature creep requirements
- Key idea: Modern markdown needs far more than simple markup
- Evidence: "Basic LaTeX support with TikZ support with the ability to install packages, PlantUML, mermaid, custom styling"
#### โฑ๏ธ [16:21](https://youtu.be/DWcqbPm_Rn4?t=981) โ [H2] Security attack surface expansion
- Key idea: Plugin hooks and execution engines create XSS vulnerabilities
- Evidence: "Every time we allow inline HTML, plugin hooks, or embedded execution engines, we expand the attack surface"
#### โฑ๏ธ [18:45](https://youtu.be/DWcqbPm_Rn4?t=1125) โ [H3] Legacy syntax decisions
- Key idea: 2000s email conventions create modern parsing problems
- Evidence: "Markdown was inspired by pre-existing conventions for marking up plain text in email and Usenet posts"
#### โฑ๏ธ [21:32](https://youtu.be/DWcqbPm_Rn4?t=1292) โ [H1] Context-sensitive grammar problem
- Key idea: Footnotes make parsing dependent on document-wide context
- Evidence: "Reference style links and footnotes require global definition resolution"
#### โฑ๏ธ [23:15](https://youtu.be/DWcqbPm_Rn4?t=1395) โ [H2] From transliterator to compiler
- Key idea: Modern features transform simple mapping into full compilation
- Evidence: "Vanilla markdown needs a transliterator, which is literally a one-to-one mapping function. But modern markdown has to support stuff like footnotes, which takes this simple transliterator into a full-blown compiler"
#### โฑ๏ธ [26:45](https://youtu.be/DWcqbPm_Rn4?t=1605) โ [H1] Proposed solution approach
- Key idea: Purpose-built tools with proper build systems instead of extending Markdown
- Evidence: "What we need is a custom-built tool, not a Frankenstein's monster that we dare to call a language"
#### โฑ๏ธ [29:32](https://youtu.be/DWcqbPm_Rn4?t=1772) โ [H3] Historical criticism acknowledgment
- Key idea: Jeff Atwood called out Markdown problems in 2012
- Evidence: "John Gruber's original markdown.pl is one of the worst small programs I've ever read, completely riddled with outright bugs"
## ๐ References
- [Original article by Brock McKegney](https://blog.brockmckegney.com/posts/why-are-we-using-markdown/)
- [RWX CI Platform](https://swade.link/rwx)
- [CommonMark Specification](https://commonmark.org/)
- [Jeff Atwood's 2012 Markdown critique](https://blog.codinghorror.com/)
## ๐ฃ๏ธ Paraphrase
- Markdown's flexibility creates parsing nightmares because multiple syntaxes can produce identical output
- Security vulnerabilities like ReDoS affect major implementations due to complex regular expressions
- Modern feature requirements transform simple markup into complex compilation with context-sensitive grammars
## ๐ฐ Newsletter
Theo dives deep into why Markdown might be holding us back as developers. While acknowledging his former devotion to Markdown (he used to only apply to jobs that accepted Markdown resumes!), he explores how the language's flexibility has become its weakness. Multiple syntaxes for the same output, security vulnerabilities, and the complexity of modern requirements have transformed simple markup into compilation nightmares.
Key takeaway: Consider whether your documentation and content tools are truly serving your needs, or if you're working around fundamental limitations.
Resources: [Learn WordPress](https://learn.wordpress.org/), [Developer Docs](https://developer.wordpress.org/), [WP-CLI](https://wp-cli.org/)
## โ
Action Items
#### DevRel
- Developer experience: Evaluate documentation formats beyond Markdown for complex technical content
- Education: Create guidelines for safe Markdown usage patterns in community documentation
- Developer marketing: Consider accessibility implications of markup language choices
#### OSPO
- Security Management: Audit Markdown parsers for ReDoS and XSS vulnerabilities in documentation systems
- Software Inventory: Document markup language dependencies and their security implications
- Developer Support: Provide alternatives to Markdown for complex documentation needs
#### Community
- Contributors: Establish safe Markdown patterns for community-generated content
- Maintainers: Consider build systems for documentation that require advanced features
#### WordPress
- Core: Evaluate Gutenberg block parsing lessons applicable to markup language design
- Documentation: Assess DevHub/HelpHub Markdown usage for security and maintainability
- Support: Create guidelines for safe markup in user-generated content
#### The WPCC
- Programs: Develop best practices for documentation formats in funded projects
## ๐งช Hypotheses
- Context-sensitive grammars in markup languages lead to exponentially more parsing vulnerabilities
- Simple transliterator approaches are more secure than full compilation for basic content needs
- Build-time processing can eliminate many runtime security issues in markup languages
- Purpose-built tools outperform extended general-purpose languages for specific domains
### ๐ Methodology
- Compare CVE counts between simple and complex markup language implementations
- Measure parsing performance and memory usage across different syntax approaches
- Test attack surface reduction with build-time vs runtime processing
### โ Questions
- Could compile-time markup processing eliminate most XSS and ReDoS vulnerabilities?
- What would a security-first markup language design look like?
- How do we balance simplicity with the advanced features users demand?
### ๐ฎ Future Research
- Security analysis of alternative markup languages and their parsers
- User experience studies comparing different documentation formats
- Performance benchmarks of various markup compilation approaches
### ๐ก Implications
- Practice: Reconsider Markdown for complex documentation projects requiring advanced features
- Security: Audit existing Markdown implementations for regex-based vulnerabilities
- Education: Teach developers about markup language security implications
- Policy: Establish guidelines for safe markup language usage in production systems
### ๐ง Learning Styles Assessment
Reading level estimate: Grade 12-14 (technical content)
#### ๐ Visual learners
- Present: Code syntax examples, vulnerability demonstrations
- Improve: Syntax comparison diagrams, parser flow charts
#### ๐ Aural learners
- Present: Video format with clear narration and examples
- Improve: Audio-described code examples
#### ๐ฃ๏ธ Verbal learners
- Present: Analogies (C++ comparison), technical term definitions
- Improve: More real-world examples and use cases
#### ๐งฉ Kinesthetic learners
- Present: Interactive parsing examples, hands-on vulnerability demonstrations
- Improve: Sandbox environments for testing different markup approaches
#### ๐ง Logical learners
- Present: Clear problem progression, formal language theory references
- Improve: Decision trees for markup language selection
#### ๐งโ๐คโ๐ง Social learners
- Present: Community discussion context, historical perspectives
- Improve: Discussion prompts about team documentation choices
#### ๐งโโ๏ธ Solitary learners
- Present: Detailed technical analysis, independent research references
- Improve: Self-assessment checklist for markup security
#### ๐ฟ Naturalistic learners
- Present: Evolution analogy of markup languages
- Improve: Ecosystem thinking about tool dependencies
### ๐ Accessibility Assessment
#### Screen reader semantics
- Present: Clear heading structure, code block labels
- Improve: More descriptive alt text for code examples
#### Keyboard navigation
- Present: Standard video controls, clear focus indicators
- Improve: Timestamped navigation shortcuts
#### Contrast and readability
- Present: High contrast code examples
- Improve: Ensure syntax highlighting meets contrast requirements
#### Text resizing and reflow
- Present: Responsive layout supports zoom
- Improve: Test code block readability at 200% zoom
#### Media and captions
- Present: Full transcript provided
- Improve: Code example audio descriptions
#### Forms and interactions
- Present: Standard video interface
- Improve: Accessible video speed controls
### ๐ DEIB Assessment
#### Cultural breadth
- Present: English-focused technical discussion
- Improve: Examples from international markdown usage patterns
#### Inclusive language
- Present: Gender-neutral technical terms
- Improve: Avoid casual profanity in technical discussions
#### Neurodiversity support
- Present: Clear section structure, consistent formatting
- Improve: Content warnings for rapid code switching
#### Representation
- Present: Technical merit focus
- Improve: Acknowledge diverse developer tool preferences
#### Psychological safety
- Present: Respectful critique of technology choices
- Improve: Emphasize learning over blame for tool decisions
### โ
Logical Validity
#### Strong reasoning
- Deductive strength: Security vulnerabilities logically follow from parsing complexity
- Inductive strength: Multiple examples support pattern of Markdown problems
- Causal reasoning: Feature creep directly causes parsing complexity
- Analogical strength: C++ comparison effectively illustrates design problems
#### Fallacies
- Appeal to authority: Relying on Jeff Atwood's criticism without independent analysis
- False dichotomy: Presenting limited alternatives without exploring hybrid approaches
#### Tone of voice
- Overall tone: Conversational but technically informed, balancing humor with serious critique
### ๐ก๏ธ DARVO Analysis
- Deny: No denial patterns detected
- Attack: No personal attacks, focuses on technical merit
- Reverse victim/offender: No victim/offender dynamics present
- Emotional cues and rhetoric: Frustration expressed constructively toward technical problems
## ๐ฏ Conclusion
Markdown's evolution from simple markup to complex pseudo-programming language has created fundamental security, parsing, and maintenance problems. While acknowledging Markdown's historical importance and continued utility for basic use cases, the analysis suggests that modern requirements demand purpose-built tools with proper build systems rather than continuing to extend Markdown. The key insight is recognizing when a tool has exceeded its intended scope and being willing to adopt alternatives that better match current needs.
## ๐งฑ Refactor Appendix
### ๐ Literature Split Pad
Purpose: Stage CEE units that become Literature notes.
Split level: H3
### [H1] Multiple syntaxes create parsing complexity
> [!quote] Markdown is a terrible language by Theo - t3โคgg via YouTube. Published 2024. Accessed 2024-12-19.
> "There is almost no syntax overlap between these other than the block quote at the end."
Demonstrates how Markdown's flexibility becomes a liability for reliable parsing.
[view highlight](https://youtu.be/DWcqbPm_Rn4?t=345#H1) #xref #articleseed ID:rw_markdown_syntax
### [H2] ReDoS vulnerabilities affect major implementations
> [!quote] Markdown is a terrible language
> "This 6.9 severity level CVE for Markdown it. This is a legit DoS vulnerability."
Shows concrete security impact of complex regex patterns in
---
## Full Transcript
[00:00] I've been a huge fan and advocate of<br>[00:01] Markdown for as long as I can remember,<br>[00:03] even to the point where it hurt my<br>[00:04] career. I literally didn't apply to jobs<br>[00:07] at companies where I couldn't submit my<br>[00:08] Markdown resume as my official resume<br>[00:11] for the company. I had my entire resume<br>[00:13] on my GitHub, and if I had to or I was<br>[00:15] really interested, I would just submit a<br>[00:17] PDF with a single link to the Markdown<br>[00:19] file on my GitHub. That's how dedicated<br>[00:21] I was. I just didn't think all of these<br>[00:23] fancy ways of presenting information<br>[00:25] mattered when you had a good, simple,<br>[00:27] reliable language for it specifically. I<br>[00:30] will always be incredibly thankful to<br>[00:32] John Gruber and Aaron Swartz for<br>[00:33] creating something as magical as<br>[00:35] Markdown, having such a simple, reliable<br>[00:38] way to just write content and have it<br>[00:41] come out and render so well. It still<br>[00:44] has a bit of a magical feel to it. As<br>[00:46] someone who tried really hard to make<br>[00:48] LaTeX work in college, Markdown, once it<br>[00:50] clicked for me, just kind of became how<br>[00:52] I write everything to this day, which is<br>[00:54] why this article immediately grabbed my<br>[00:56] attention. Why the heck are we still<br>[00:59] using Markdown? As great as Markdown is,<br>[01:02] I am more than happy to agree we have<br>[01:03] went too far with it. Once we got to the<br>[01:05] point where we were making new file<br>[01:07] extensions to embed other types of<br>[01:09] content into our Markdown, we were<br>[01:11] probably over the line. And now that<br>[01:13] we're in a world where we're using LLMs<br>[01:15] and agents and all of these things, and<br>[01:17] Markdown is the method we communicate<br>[01:18] between them, it's getting even more<br>[01:20] questionable. I have a lot of different<br>[01:22] things I want to talk about with<br>[01:23] Markdown in the near future, things like<br>[01:25] how Markdown is not the right primitive<br>[01:26] for memory or how Markdown is actually<br>[01:28] pretty good as a programming scripting<br>[01:30] language in specific scenarios, which<br>[01:32] we'll definitely talk a lot about in the<br>[01:33] future. But today I want to question the<br>[01:35] fundamentals. Why are we still using<br>[01:37] Markdown? What makes it so great? And<br>[01:40] what would a better solution for the<br>[01:42] stuff we do today look like? I've barely<br>[01:44] even started and I can already imagine<br>[01:46] all of the Obsidian comments in my head,<br>[01:48] and if I know y'all love anything more<br>[01:50] than Obsidian, it's probably today's<br>[01:51] sponsor. I have a question for you.<br>[01:53] What's the most times you've committed<br>[01:54] code that didn't work just trying to fix<br>[01:56] CI? I've probably stacked up to 15<br>[01:58] commits before just watching CI break<br>[02:00] again and again. And all I wanted was<br>[02:02] the ability to run it locally without<br>[02:03] having to make more commits, ideally in<br>[02:05] a way that doesn't even force me to<br>[02:06] leave my editor or my agent. Today's<br>[02:08] sponsor RWX. I can tell you about how<br>[02:10] fast they are, how great they are to<br>[02:11] work with agents, or how they run things<br>[02:13] in parallel so you don't have to wait<br>[02:14] for a bunch of stuff that's blocking<br>[02:16] when it doesn't have to be. There's a<br>[02:17] lot of reasons to use RWX, but I don't<br>[02:19] want to talk about any of that because<br>[02:20] I'm in love with the CLI. Once you write<br>[02:22] the YAML file for your CI, all you have<br>[02:24] to do is run their CLI to trigger a run<br>[02:26] without having to commit the code. So,<br>[02:28] instead of committing, pushing, and<br>[02:29] waiting for the whole thing to run, you<br>[02:31] can just run a CLI command locally, it<br>[02:33] will then spin up a cloud instance that<br>[02:34] can still take advantage of all of the<br>[02:36] caching infra and all the other things<br>[02:38] they do right, and immediately get your<br>[02:39] feedback as to whether or not it worked.<br>[02:41] This should be enough to sell you. But<br>[02:42] when you combine it with their agent<br>[02:44] skill, suddenly it's like, oh, yeah.<br>[02:47] Seriously though, Run Loops are such a<br>[02:48] great solution to so many different<br>[02:50] problems. If you were working on a hard<br>[02:52] feature that you can't test, go write<br>[02:53] the test, commit it, and then tell the<br>[02:55] agent, make sure CI passes by running<br>[02:57] the RWX run command, and then when it<br>[02:59] passes, commit it and push. This is such<br>[03:01] a good workflow, and I'm amazed nothing<br>[03:02] else has it. And this is just the tip of<br>[03:04] the iceberg. The more you dig in, the<br>[03:05] more you'll appreciate RWX's unique way<br>[03:07] of fixing CI so that you will move<br>[03:09] faster instead of slower. Sign up for<br>[03:11] the CI that makes your agents faster at<br>[03:13] swade.link/rwx.<br>[03:14] So, why the heck are we still using<br>[03:16] Markdown? There are a few things in life<br>[03:18] that bring me much joy and heat at the<br>[03:20] same time, like a chocolate that hurts<br>[03:22] when eaten, or Markdown. Seriously, why?<br>[03:25] Half of the time we aren't even using<br>[03:26] the full language. Speaking of which,<br>[03:28] this is a bold opening. HTML is the best<br>[03:31] programming language. I know you've<br>[03:32] heard people say that the only<br>[03:33] programming language they know is HTML,<br>[03:35] and I know we both roll their eyes in<br>[03:37] discontent trying to get our programming<br>[03:39] language papers out of assembled decks<br>[03:40] on of papers on how HTML is only a<br>[03:43] markup language and not a programming<br>[03:44] language. I mean, yes, we're on the<br>[03:46] right, but that guy probably has<br>[03:48] something that we don't have.<br>[03:50] A life. Okay, already owned and the<br>[03:53] article's barely started. I I will have<br>[03:55] you know that my girlfriend loves when I<br>[03:58] talk about HTML and Markdown.<br>[04:00] But to each their own.<br>[04:01] Note, when the author is talking about<br>[04:02] Markdown, he is specifically talking<br>[04:04] about Common Mark unless stated<br>[04:05] otherwise, because it is the unambiguous<br>[04:08] syntax specification. I love the<br>[04:09] project. I really appreciate their<br>[04:11] efforts on making this language a bit<br>[04:12] more grounded. It's not the<br>[04:14] specification that's broken, it's the<br>[04:15] language itself. Oh boy.<br>[04:17] The good. Markdown is a minimal language<br>[04:20] used for typesetting trivial documents.<br>[04:21] It needed to do one simple job, get a<br>[04:23] Markdown file and output an HTML file.<br>[04:26] Its index is as legible as it gets, and<br>[04:28] it's easy to write even with no assists.<br>[04:30] Like the C language, you can see the<br>[04:31] output that will be created. Bold is<br>[04:33] always open, closed B tags at the end,<br>[04:36] and the italics are the same. Learning<br>[04:38] curve is simply nonexistent if you're<br>[04:39] just a casual user. Just one look at the<br>[04:41] cheat sheet and you're ready. But now<br>[04:43] the bad. We don't know what we want. Do<br>[04:46] we want UI? Do we want a programming<br>[04:47] language? We don't know. The only reason<br>[04:50] feature creep exists is because of<br>[04:51] unclear specifications. You want a<br>[04:54] minimal, easily legible markup language,<br>[04:56] you have Markdown. Simple as that,<br>[04:58] right? Well, here are two different<br>[05:00] syntaxes to generate the exact same<br>[05:03] output. You have the single hash for<br>[05:05] title, hello, stars for doing an italics<br>[05:09] here for I am, and then unambiguous,<br>[05:11] which you want bold, and then grammar in<br>[05:13] a block quote. This is roughly how I<br>[05:15] would write this. I would have used<br>[05:16] double stars for unambiguous, but I am<br>[05:19] what I am. Actually, actually, I would<br>[05:20] have used double stars for unambiguous<br>[05:22] and underscores for that, so I guess I'm<br>[05:23] closer to here. But I would never have<br>[05:25] done the header syntax like this. God.<br>[05:28] Yeah. There is almost no syntax overlap<br>[05:31] between these other than the block quote<br>[05:33] at the end. Woof. Oh boy, we're about to<br>[05:35] have fun. Hope you have the two eyeballs<br>[05:37] enough to see that Markdown is not what<br>[05:39] you asked for. These produce two<br>[05:40] identical outputs, and this is just the<br>[05:42] tip of the iceberg. It has so many poor<br>[05:44] decisions baked in that if you try to<br>[05:46] use it, it will actively fight against<br>[05:47] you the moment you think you know what<br>[05:49] you're doing. Let's start with bold,<br>[05:50] italic, and bold italic. In Markdown,<br>[05:52] you can write a bold in different ways.<br>[05:54] You have the double star syntax, double<br>[05:56] underscores, or the B tag. And these are<br>[05:58] just some of the ways a valid bold can<br>[05:59] be written. And these are for Common<br>[06:00] Mark. If you're using something which<br>[06:02] isn't marketing itself as Common Mark<br>[06:03] compliant, you can very well encounter<br>[06:05] valid stuff that produces the same<br>[06:07] input. Like this, or this, or yeah, God,<br>[06:10] yeah. We have had to deal with so much<br>[06:12] [ย __ย ] like this for T3 Chat, you guys<br>[06:14] have no idea. It is so absurdly<br>[06:18] difficult to handle all the different<br>[06:20] weird cases for Markdown rendering, but<br>[06:22] I will also personally say the edge<br>[06:24] cases for LaTeX are even worse. So,<br>[06:27] yeah.<br>[06:28] >> [snorts]<br>[06:28] >> And don't even get him started on<br>[06:30] layered ones like this. Oh God, I don't<br>[06:31] even want to try to parse this. Okay, we<br>[06:34] got the two star here, then this one is<br>[06:36] an italic. So, this whole section is<br>[06:37] bold here, this one is italicized. This<br>[06:40] is italicized.<br>[06:42] A is bolded here, not italicized, and<br>[06:45] this is re-italicized. Of is italicized.<br>[06:49] This is italics, and this is doubled the<br>[06:52] italics for the led here, I think. That<br>[06:55] hurt.<br>[06:57] Or this. Oh.<br>[06:59] No. No, please no.<br>[07:02] I'm not even going to try on that one.<br>[07:04] This thing is actually so peak that we<br>[07:06] have a class of parser vulnerabilities<br>[07:08] called ReDoS, regular expression denial<br>[07:10] of service, that are affecting this.<br>[07:12] Like this 6.9 severity level CVE for<br>[07:15] Markdown it. This is a legit DoS<br>[07:18] vulnerability.<br>[07:20] You just put a bunch of stars in a link<br>[07:21] and it can't process it. Beautiful.<br>[07:25] Beautiful.<br>[07:26] Yeah, this string here takes 65,553<br>[07:31] steps. That will [ย __ย ] over anything.<br>[07:33] Great, super cool. We love that.<br>[07:37] So, how much worse can it possibly get<br>[07:39] here? Exhibit B, ASM was a good idea,<br>[07:42] but this? In old languages where<br>[07:43] compilers were producing optimal code<br>[07:45] like a river in a desert, inline<br>[07:47] assembly helped them write<br>[07:48] performance-critical code with ease and<br>[07:50] the cost of the compiler engineers'<br>[07:52] blood, sweat, tears, and the birth of<br>[07:54] their firstborn son. Yeah, writing your<br>[07:56] inline assembly to get perfect code is<br>[07:59] hellish. It's one of the reasons that a<br>[08:00] project like FFmpeg is so tough, but<br>[08:02] also so important. Inline ASM allowed<br>[08:04] stuff like SIMD operations before the<br>[08:06] compiler supported them. You want an<br>[08:07] overview of early SIMD generation<br>[08:09] failures, you can take a look at those<br>[08:10] here. Oh God, that's the last thing I<br>[08:12] want to look at. Now, let's take this<br>[08:14] wonderful idea and bolt it directly into<br>[08:16] the most bloated, single-threaded,<br>[08:17] sandboxed environment expecting a simple<br>[08:19] and easy way to write documents. And<br>[08:21] that's how inline HTML inside Markdown<br>[08:23] was born. Oh boy. Inline HTML allows you<br>[08:27] to do stuff like this. I've had so many<br>[08:29] problems with inline HTML and Markdown<br>[08:31] personally that I am even more on this<br>[08:33] author's side now.<br>[08:35] Yeah. I am an insert simple programmer<br>[08:38] doing span class fancy text elegant<br>[08:41] close span programming. Div class<br>[08:42] animation. And here is my portfolio.<br>[08:45] Close div. Isn't this just simple? Isn't<br>[08:47] this just neat? The main reason why<br>[08:49] correct Markdown parsing is<br>[08:51] exceptionally hard isn't because<br>[08:52] Markdown syntax is so hard to<br>[08:54] comprehend, it's only 1/10 of the issue.<br>[08:56] The real issue is that to ship a<br>[08:58] Markdown parser, you also need to ship a<br>[09:00] friendly HTML parser. If you're using<br>[09:01] HTML inside of Markdown, why not use<br>[09:03] HTML from the start? Fair. I actually<br>[09:06] remember now, friend of the channel, who<br>[09:09] might even be here right now, Jacob<br>[09:10] Evans, tried really hard a while back,<br>[09:14] and it looks like he has given it up<br>[09:15] since, but he tried super hard to have a<br>[09:18] single Markdown file for his GitHub<br>[09:20] profile and for his homepage by serving<br>[09:23] the Markdown as HTML, because there's<br>[09:25] enough overlap that hypothetically, you<br>[09:28] could write a valid HTML homepage and<br>[09:30] have it render as your profile as well<br>[09:33] without code between the two. Literally<br>[09:35] the same exact bytes for both. And the<br>[09:38] results were hellish. He tried really<br>[09:39] hard to make it work.<br>[09:41] But man, it was very fun watching him<br>[09:43] try. Markdown in and of itself isn't<br>[09:45] powerful enough to satisfy the simple<br>[09:47] monkey brain developers like the author,<br>[09:49] who's only satisfied when the site looks<br>[09:50] good enough. Good enough in this case<br>[09:52] means it needs to have at least basic<br>[09:54] LaTeX support with TikZ support with the<br>[09:56] ability to install packages, PlantUML,<br>[09:58] mermaid, custom styling, custom<br>[10:00] shortcodes, tagging and taxonomy, proper<br>[10:03] footnotes, BibTeX support. I don't want<br>[10:05] a simple job from the simple tool, too.<br>[10:08] To nail a painting to the wall, I need a<br>[10:09] hammer. In this case, the hammer is<br>[10:11] markdown. But what if I wanted to paint<br>[10:13] too? I'll break the canvas the moment I<br>[10:14] try to paint it with a hammer. Breaking<br>[10:16] the canvas also means a whole lot of<br>[10:17] CVEs, primarily around cross-site<br>[10:19] scripting vulnerabilities. This has me<br>[10:21] thinking. As we think, I want to take a<br>[10:22] look at my blog and see how [ย __ย ] my<br>[10:25] markdown is. I haven't thought about<br>[10:26] this in a while. So we already have a<br>[10:28] helmet here. That's great.<br>[10:31] I have an iframe embedded cuz it's a<br>[10:33] YouTube video. So in the first 13 lines<br>[10:36] in the second paragraph here, I'm<br>[10:38] already doing weird HTML [ย __ย ] Then the<br>[10:40] rest is fine. Oh, here's a great one. I<br>[10:42] needed to have an image tag that was<br>[10:45] also a link. So I put an image HTML tag<br>[10:49] inside of brackets to attach the link.<br>[10:52] Isn't this wonderful?<br>[10:54] I had to check two posts to find some<br>[10:56] cursed [ย __ย ] More cursed HTML<br>[10:58] inlined. Man, I used to be so good at<br>[11:00] writing. It's a shame that the syntax is<br>[11:02] awful. Yeah. Get the idea. It As soon as<br>[11:04] you want to use markdown for more<br>[11:06] interesting stuff, you end up writing<br>[11:09] some cursed stuff. Every time we allow<br>[11:11] inline HTML, plugin hooks, or embedded<br>[11:13] execution engines, we expand the attack<br>[11:15] surface. The result is predictable.<br>[11:17] Recurring cross-site scripting<br>[11:18] vulnerabilities across major markdown<br>[11:20] implementations and much, much more. And<br>[11:22] this will continue to rise with the vibe<br>[11:23] [ย __ย ] parsers that are hitting the<br>[11:25] market. Yep. I've seen a lot of attempts<br>[11:27] to rethink how we parse markdown because<br>[11:29] all of the agents spit out markdown. We<br>[11:31] want to make things that are better,<br>[11:32] faster, more reliable, and all of them<br>[11:34] are just full of exploits, edge cases,<br>[11:36] vulnerabilities, and more. Apparently,<br>[11:37] Obsidian markdown is even more cursed.<br>[11:39] I'm sure I will love that. Speaking of<br>[11:41] things I love, we're now in exhibit C,<br>[11:42] the old and obscure syntax. Markdown,<br>[11:45] like all the good tech we have around<br>[11:46] the World Wide Web, was made in the good<br>[11:48] old 2000s. Markdown was inspired by<br>[11:50] pre-existing conventions for marking up<br>[11:52] plain text in email and Usenet posts.<br>[11:54] Mind you, before 2000, most serious mail<br>[11:56] looked like this. Do you see this quote<br>[11:58] syntax putting the colon at the start of<br>[12:00] every line?<br>[12:02] Oh god, this ending in the signature.<br>[12:04] Woo. Do you see the beauty of it? The<br>[12:06] quote syntax, the vertical separation<br>[12:08] with pipes. This is what markdown was<br>[12:09] needed for, which it would fail horribly<br>[12:11] at because in markdown you can't divide<br>[12:12] the screen into n parts without inline<br>[12:14] HTML black magic. But because of this<br>[12:16] legacy, you have two different ways of<br>[12:18] writing headings, the normal way and the<br>[12:20] ATX way. You have two different ways and<br>[12:22] more than two CVEs of writing bold and<br>[12:24] italic. You have two different ways of<br>[12:25] writing horizontal rules, which collide<br>[12:27] with one of them, colliding with the set<br>[12:29] text header syntax. You have two<br>[12:30] different ways of writing unordered<br>[12:31] lists. You have an ordered list, which<br>[12:33] doesn't care about how you ordered them.<br>[12:35] And you have a footnote syntax, which<br>[12:37] moves the entire grammar to<br>[12:38] context-dependent grammar. And I<br>[12:40] remember the first time I saw that like<br>[12:42] the right way to do lists in markdown,<br>[12:44] the correct thing is to put zeros<br>[12:45] because then your markdown parser can<br>[12:47] number them correctly and if you change<br>[12:48] the order of things, you don't have to<br>[12:49] go redo all the numbers. Ugh, so much<br>[12:52] [ย __ย ] Oh, oh, I didn't see this<br>[12:55] line. This language is literally the C++<br>[12:58] of markup languages. Oh man. Now that<br>[13:01] I've seen this, I can't unsee this. That<br>[13:03] is entirely correct. This might be my<br>[13:06] favorite programming video ever other<br>[13:08] than maybe the OOP is garbage video.<br>[13:12] It's 2 hours long and I had to stop and<br>[13:15] pause and go back to it later because<br>[13:17] unlike most 2-hour-long videos, I<br>[13:19] couldn't watch that one in the<br>[13:20] background cuz it was too good. So I<br>[13:22] actually sat and like locked in and just<br>[13:24] stared at my phone for 2 hours. My<br>[13:26] roommate at the time asked if I was<br>[13:27] okay. I was like, "I'm more than okay.<br>[13:29] You're going to have to watch this<br>[13:30] after." This video is so good. Highly<br>[13:33] recommend it. And knowing that, having<br>[13:35] that still in my head, C++ in markdown,<br>[13:39] yeah, there's a lot of overlap. Nearly<br>[13:41] everything can be done in two different<br>[13:42] ways, which some of them might allow for<br>[13:43] cross-site scripting and somehow leak<br>[13:45] memory in HTML. It's used everywhere,<br>[13:47] but it also fails everywhere equally.<br>[13:49] And now we're at exhibit D. You can't<br>[13:51] simply just parse it, you also have to<br>[13:53] use it. Parsing is the easy thing.<br>[13:55] If you remember, I told you that the<br>[13:57] footnote syntax moves this grammar up to<br>[13:59] a context-sensitive one. Let me<br>[14:01] elucidate you. Okay, so if we have this<br>[14:03] syntax with the carrot for a citation,<br>[14:06] this becomes test bracket one there. But<br>[14:09] if we actually handle a citation at the<br>[14:11] bottom, now the markdown changes cuz<br>[14:14] this is now a link instead. Previously,<br>[14:17] it just put this in, now this thing<br>[14:19] further on changes how this part here is<br>[14:22] parsed. Oh boy. Actually though,<br>[14:24] footnotes aren't supported in<br>[14:25] CommonMark. They have links. The only<br>[14:27] notable difference is that link syntax<br>[14:29] means you can put only one word after<br>[14:31] the definition as opposed to a shameful<br>[14:33] explanation of why bananas on pizza is a<br>[14:35] good idea. Reference style links and<br>[14:37] footnotes require global definition<br>[14:38] resolution. A token's meaning depends on<br>[14:41] declarations elsewhere in the document.<br>[14:43] That breaks purely context-free parsing<br>[14:44] assumptions. Ergo, the updates to a CSG<br>[14:47] from a CFG. I had some intuition that<br>[14:50] markdown as as we use it was a<br>[14:52] context-sensitive grammar, but god damn,<br>[14:54] this is a really, really damning example<br>[14:57] of that.<br>[14:58] Woo.<br>[14:59] All this a lot of words for saying, "If<br>[15:01] you want a simple language, it should<br>[15:02] say simple."<br>[15:03] Rendering is the hard thing. I think<br>[15:05] this is the most controversial part<br>[15:06] about the author's rant because nobody<br>[15:08] wants to admit that what we use and need<br>[15:10] are two very different things. Vanilla<br>[15:12] markdown needs a transliterator, which<br>[15:14] is literally a one-to-one mapping<br>[15:15] function. You see bold and then HTML<br>[15:18] bold comes out. But modern markdown has<br>[15:20] to support stuff like footnotes, which<br>[15:22] takes this simple transliterator into a<br>[15:24] full-blown compiler. And after you made<br>[15:26] this step, here's the ladder that you'll<br>[15:27] climb. I need a personal knowledge<br>[15:29] management system. Oh boy, the Obsidian<br>[15:31] people are going to love this.<br>[15:33] Requirement, I'll need footnotes. Cool.<br>[15:35] We're now at a CSG grammar. Now we've<br>[15:37] built a compiler. Oh, you want custom<br>[15:39] callouts? Hooks that bind HTML with<br>[15:40] markdown? Now you have a dependency<br>[15:42] graph. I'll need math. Well, you need<br>[15:44] typesetting library integrations, too.<br>[15:45] So your dependency graph just got way<br>[15:47] more complex with execution engines as<br>[15:49] well. And if you want custom styling,<br>[15:51] custom CSS, you now have to deal with<br>[15:52] CSS injections with file-based scoping<br>[15:55] rules. This one is really fun. Having<br>[15:57] CSS in one markdown file and making sure<br>[15:59] it doesn't break things in others, good<br>[16:01] luck, have fun. This is a great section.<br>[16:03] I'm sure y'all will love. I swear what I<br>[16:04] have to do in Obsidian work to make my<br>[16:06] needs using markdown make it seem like<br>[16:08] Notion made a sane decision copying Word<br>[16:10] and Excel internally instead.<br>[16:12] Yeah. The author thinks that Notion<br>[16:15] seems sane because of how bad markdown<br>[16:17] is. Do you understand how absurd that<br>[16:19] is? Honestly, okay, here I'm going to<br>[16:21] drop my hot take here. I like Notion's<br>[16:23] use of markdown as hotkeys effectively,<br>[16:27] where you can export markdown from<br>[16:29] Notion, but the formatting of it's<br>[16:31] broken and garbage. It's so bad. So like<br>[16:33] don't do that. But when I'm typing in<br>[16:35] Notion, the fact that I can just use<br>[16:37] markdown syntax to change the element<br>[16:39] without having to learn a whole bunch of<br>[16:40] new hotkeys, that's really nice. Like if<br>[16:42] I'm looking at the Notion doc for this<br>[16:44] video,<br>[16:45] I say sup and I decide this should<br>[16:46] actually be a title. Hash space, now<br>[16:48] it's a title. Oh, I want a smaller one,<br>[16:50] two hash space, three hash space.<br>[16:52] That's really nice. But that's a<br>[16:54] different use case. That's not the<br>[16:56] syntax we're using. That is a syntax or<br>[16:59] a grammar that we're familiar with being<br>[17:01] used effectively as a hotkey layer. Fun.<br>[17:03] Uh Wabo just linked me async syntax in<br>[17:07] markdown. This is JS though, but still,<br>[17:11] this syntax for doing execution with<br>[17:13] awaits in blockers<br>[17:16] is so cursed. This is like view levels<br>[17:19] of cursed, but in a markup language.<br>[17:21] Async markdown,<br>[17:22] not even once.<br>[17:25] This This horrifies me.<br>[17:27] I feel sick. Oh god, there's more? Oh,<br>[17:29] this is DataView JS as text in Oh, no, I<br>[17:33] want nothing to do with any of this.<br>[17:35] Save me. Get me away. No, let's let's<br>[17:37] see how we solve this according to the<br>[17:39] author. You ask the guy with a majestic<br>[17:41] beard with 30-plus years of experience<br>[17:42] in 8086 assembly, the answer is plain<br>[17:44] text. You ask the guy with MacBook and<br>[17:46] OpenClaw running three different Mac<br>[17:48] minis making a startup a day, the answer<br>[17:50] is MDX. No, I Okay, I'm not an OpenClaw<br>[17:53] guy with three Mac minis. I do have<br>[17:55] three Mac minis in this apartment, but<br>[17:56] only one is on. I even know MDX is not<br>[17:58] the right answer here. You ask the guy<br>[18:00] who codes in C for a living, the answer<br>[18:01] is reStructuredText.<br>[18:03] You ask the author, the answer is none.<br>[18:05] All of these solutions are broken in<br>[18:06] their own ways. Plain text is beautiful,<br>[18:08] but I can't show it to somebody that<br>[18:09] doesn't know what a null pointer<br>[18:11] dereferences. reStructuredText is<br>[18:13] wonderful if you only read it and never<br>[18:14] write it. And MDX is so busy trying to<br>[18:17] be HTML, it forgets it needs to be<br>[18:18] legible. And the biggest problem in all<br>[18:20] of them is that they don't have a build<br>[18:22] system. We cut corners in the name of<br>[18:24] speed. If they had a build system, a<br>[18:26] sane, unambiguous, legible syntax<br>[18:28] purpose-built for what it's needed to<br>[18:29] be, I think all of the problems will be<br>[18:31] fixed. Don't allow inline HTML, allow<br>[18:34] for well-defined shortcodes and<br>[18:35] functions to manipulate the text. Allow<br>[18:37] for custom hooks to be executed before,<br>[18:39] during, and after the compilation. Oh,<br>[18:41] so you are in favor of async markdown.<br>[18:43] And most importantly, define everything.<br>[18:45] What we need is a custom-built tool, not<br>[18:47] a Frankenstein's monster that we dare to<br>[18:48] call a language. Not saying markdown or<br>[18:50] markup should be a programming language,<br>[18:52] I'm saying we are trying to use it like<br>[18:53] one and because it lacks a formal<br>[18:55] foundation, it's failing at both. I<br>[18:57] genuinely think that a proper build<br>[18:58] system around a saner markup language<br>[19:00] with compile-time hook support can fix a<br>[19:02] lot of the problems around this with the<br>[19:04] right constraints. At this point, we<br>[19:05] should just let go of markdown for good<br>[19:07] and look for our answers elsewhere,<br>[19:09] probably with a trivially parsable<br>[19:10] grammar. He has a whole formal language<br>[19:12] theory section here. Markup languages<br>[19:15] are a standard text encoding system<br>[19:16] consisting of a set of symbols inserted<br>[19:18] in a text document to control its<br>[19:20] structure, formatting, or the<br>[19:21] relationship between its parts. And<br>[19:23] programming languages are computer<br>[19:25] programming languages, any of various<br>[19:27] languages for expressing a set of<br>[19:28] detailed instructions for digital<br>[19:29] computer.<br>[19:30] As you can clearly see, these official<br>[19:32] definitions are not the way to go. So<br>[19:33] he's going to use another separate one.<br>[19:35] A language is a programming language if<br>[19:36] it's Turing complete. Oh god, so<br>[19:38] markdown is definitely a programming<br>[19:39] language. I write JavaScript for a<br>[19:41] living, so we're not going to get into<br>[19:44] EBNF and context-free languages.<br>[19:46] Articles in the description if you're<br>[19:47] the type that cares about these depths<br>[19:49] to Turing completeness things. God, none<br>[19:52] of these words are in the Bible. The<br>[19:53] thing separating a set of mathematical<br>[19:55] axioms from provability to<br>[19:56] non-provability is the want of recursion<br>[19:59] self-reference, which manifests itself<br>[20:01] as the common multiplication operation.<br>[20:03] A trivial observation can have<br>[20:05] non-trivial reactions. Yeah. Oh God, I<br>[20:08] missed this.<br>[20:09] Man, I forgot about this. This was in<br>[20:11] 2012. Jeff Atwood wrote an article<br>[20:14] begging Gruber to give up Markdown or at<br>[20:17] least bless these attempts to make a<br>[20:19] better standard. Oh man, this is<br>[20:21] actually really good. I wish that this<br>[20:22] happened. RIP. John Gruber's original<br>[20:24] markdown.pl is one of the worst small<br>[20:26] programs I've ever read, completely<br>[20:27] riddled with outright bugs and<br>[20:29] misfeatures that continually bite its<br>[20:30] users in the ass. It's awful even by the<br>[20:33] already low standards of handwritten<br>[20:35] many past regex-based spaghetti parsers.<br>[20:37] Nobody should be using this original<br>[20:39] script and unfortunately many of the<br>[20:40] other implementations out there are<br>[20:41] direct transliterations that replicate<br>[20:43] all of its absurd errors. Like where if<br>[20:45] you mention the MD5 hash of another<br>[20:46] token in the document, the hash will be<br>[20:48] replaced with the token because it uses<br>[20:49] that as inline escaping mechanisms.<br>[20:51] Reddit hit with a cross-site scripting<br>[20:53] virus that got through the filters<br>[20:54] because of this. Jesus Christ. And<br>[20:57] another Markdown is a disaster from last<br>[20:59] year.<br>[21:08] Wild. I did not know there was this<br>[21:10] quiet cult of people fighting the chaos<br>[21:13] that is Markdown, but it's really cool<br>[21:15] to see and I have a lot of respect for<br>[21:17] the author for taking the time to write<br>[21:19] this. Thank you to Brock for writing<br>[21:20] this. This was a fantastic read. I did<br>[21:24] not realize how much I hated Markdown<br>[21:26] and I use it every day. This article<br>[21:29] very much pushed me over the edge to<br>[21:31] more deeply appreciate how bad it is.<br>[21:34] Sadly, this author does not have a<br>[21:35] Twitter or anything linked so I can't<br>[21:37] throw you at anything other than his<br>[21:38] blog, but I would recommend checking it<br>[21:40] out if you're nerdy about these things<br>[21:41] and the original article has even more<br>[21:43] fun details if you want to check it out<br>[21:44] yourself. I got nothing else though.<br>[21:47] I can't help but notice the irony of me<br>[21:48] wearing this HTML shirt and I'm going to<br>[21:50] resist the urge to go rewrite all of my<br>[21:52] stuff in HTML or maybe a new markup<br>[21:55] language I make up myself. Please don't<br>[21:56] make me do this guys. T3 down is not the<br>[21:58] solution, but<br>[22:00] I am admitting<br>[22:01] >> [sighs]<br>[22:02] >> a little bit of temptation.<br>[22:03] Until next time.<br>[22:05] Peace nerds.
<!-- deep-read:sections end -->
๐ **Full text:** ![[Full Document Contents/Articles/Markdown Is a Terrible Language.md|Markdown Is a Terrible Language by YouTube]]
## Highlights
- will always be incredibly thankful to John Gruber and Aaron Swartz for creating something as magical as Markdown, having such a simple, reliable way to just write content and have it come out and render so well. It still has a bit of a magical feel to it. As someone who tried really hard to make LaTeX work in college, Markdown, once it clicked for me, just kind of became how I write everything to this day, which is why this article immediately grabbed my attention. Why the heck are we still using Markdown? As great as Markdown is, ([View Highlight](https://read.readwise.io/read/01kq7w81yzjcbg4y12vg4jr1bv))
- Tags: ๐ป ai highlighted
- a good workflow, and I'm amazed nothing else has it. And this is just the tip of the iceberg. The more you dig in, the more you'll appreciate RWX's unique way of fixing CI so that you will move faster instead of slower. Sign up for the CI that makes your agents faster at swade.link/rwx. So, why the heck are we still using Markdown? There are a few things in life that bring me much joy and heat at the same time, like a chocolate that hurts when eaten, or Markdown. Seriously, why? Half of the time we aren't even using the full language. Speaking of which, this is a bold opening. HTML is the best ([View Highlight](https://read.readwise.io/read/01kq7w81zdvgks2bf4zwvfw21h))
- Tags: ๐ป ai highlighted
- As you can clearly see, these official definitions are not the way to go. So he's going to use another separate one. A language is a programming language if it's Turing complete. Oh god, so markdown is definitely a programming language. I write JavaScript for a living, so we're not going to get into EBNF and context-free languages. Articles in the description if you're the type that cares about these depths to Turing completeness things. God, none of these words are in the Bible. The thing separating a set of mathematical axioms from provability to non-provability is the want of recursion self-reference, which manifests itself ([View Highlight](https://read.readwise.io/read/01kq7w821fjbhc266wq87bdq5s))
- Tags: ๐ป ai highlighted