|
| 1 | +# Why Djot? Upgrading from Markdown |
| 2 | + |
| 3 | +Djot was created by John MacFarlane (creator of Pandoc and CommonMark) to address Markdown's accumulated quirks and limitations. This document explains why you might want to upgrade. |
| 4 | + |
| 5 | +## The Problem with Markdown |
| 6 | + |
| 7 | +Markdown was designed in 2004 as a simple format for writing blog posts. Twenty years later, it's used everywhere - but with significant problems: |
| 8 | + |
| 9 | +1. **No single specification** - CommonMark, GFM, MultiMarkdown, PHP Markdown Extra, and dozens more |
| 10 | +2. **Ambiguous syntax** - `_` and `*` behave differently based on context |
| 11 | +3. **Limited features** - no highlighting, attributes, or consistent extensions |
| 12 | +4. **HTML dependency** - raw HTML is the escape hatch for everything |
| 13 | + |
| 14 | +## Side-by-Side Comparison |
| 15 | + |
| 16 | +### Emphasis and Strong |
| 17 | + |
| 18 | +| Feature | Markdown | Djot | |
| 19 | +|---------|----------|------| |
| 20 | +| Emphasis | `*text*` or `_text_` | `_text_` | |
| 21 | +| Strong | `**text**` or `__text__` | `*text*` | |
| 22 | + |
| 23 | +Djot uses single characters consistently: `_` for emphasis, `*` for strong. No ambiguity. |
| 24 | + |
| 25 | +### Text Formatting |
| 26 | + |
| 27 | +| Feature | Markdown | Djot | |
| 28 | +|---------|----------|------| |
| 29 | +| Highlight | Not supported | `{=highlighted=}` | |
| 30 | +| Insert | Not standard | `{+inserted+}` | |
| 31 | +| Delete | `~~text~~` (GFM only) | `{-deleted-}` | |
| 32 | +| Superscript | Not standard | `{^superscript^}` | |
| 33 | +| Subscript | Not standard | `{~subscript~}` | |
| 34 | + |
| 35 | +### Attributes |
| 36 | + |
| 37 | +Markdown has no standard way to add classes, IDs, or attributes. |
| 38 | + |
| 39 | +**Markdown (with non-standard extensions):** |
| 40 | +```markdown |
| 41 | +# Heading {#my-id .my-class} |
| 42 | +<!-- Depends on parser, often not supported --> |
| 43 | +``` |
| 44 | + |
| 45 | +**Djot:** |
| 46 | +```djot |
| 47 | +# Heading {#my-id .my-class} |
| 48 | +
|
| 49 | +A paragraph with [styled text]{.highlight} inline. |
| 50 | +
|
| 51 | +{width=300} |
| 52 | +``` |
| 53 | + |
| 54 | +Djot attributes work on any element - headings, paragraphs, spans, images, code blocks, and more. |
| 55 | + |
| 56 | +### Code Blocks |
| 57 | + |
| 58 | +**Markdown:** |
| 59 | +````markdown |
| 60 | +```javascript |
| 61 | +const x = 1; |
| 62 | +``` |
| 63 | +```` |
| 64 | + |
| 65 | +**Djot:** |
| 66 | +````djot |
| 67 | +``` javascript |
| 68 | +const x = 1; |
| 69 | +``` |
| 70 | +{#example-code .highlighted linenos=true} |
| 71 | +```` |
| 72 | + |
| 73 | +Djot allows attributes on code blocks for syntax highlighting configuration, line numbers, etc. |
| 74 | + |
| 75 | +### Links and Images |
| 76 | + |
| 77 | +| Feature | Markdown | Djot | |
| 78 | +|---------|----------|------| |
| 79 | +| Basic link | `[text](url)` | `[text](url)` | |
| 80 | +| Basic image | `` | `` | |
| 81 | +| Link with title | `[text](url "title")` | `[text](url "title")` | |
| 82 | +| Link with attributes | Not supported | `[text](url){target=_blank}` | |
| 83 | +| Image with size | Not standard | `{width=300}` | |
| 84 | + |
| 85 | +### Footnotes |
| 86 | + |
| 87 | +**Markdown (extension, varies by parser):** |
| 88 | +```markdown |
| 89 | +Here's a footnote[^1]. |
| 90 | + |
| 91 | +[^1]: The footnote content. |
| 92 | +``` |
| 93 | + |
| 94 | +**Djot (built-in, consistent):** |
| 95 | +```djot |
| 96 | +Here's a footnote[^1]. |
| 97 | +
|
| 98 | +[^1]: The footnote content. |
| 99 | +``` |
| 100 | + |
| 101 | +Same syntax, but Djot guarantees it works everywhere. |
| 102 | + |
| 103 | +### Math |
| 104 | + |
| 105 | +**Markdown:** Depends entirely on the parser. Some use `$...$`, others `\(...\)`, many don't support it. |
| 106 | + |
| 107 | +**Djot:** |
| 108 | +```djot |
| 109 | +Inline math: $E = mc^2$ |
| 110 | +
|
| 111 | +Display math: |
| 112 | +$$ |
| 113 | +\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2} |
| 114 | +$$ |
| 115 | +``` |
| 116 | + |
| 117 | +### Raw Content |
| 118 | + |
| 119 | +**Markdown:** Only raw HTML is supported. |
| 120 | + |
| 121 | +**Djot:** |
| 122 | +```djot |
| 123 | +`<b>raw html</b>`{=html} |
| 124 | +
|
| 125 | +`\textbf{raw latex}`{=latex} |
| 126 | +
|
| 127 | +``` =html |
| 128 | +<div class="custom"> |
| 129 | + Raw HTML block |
| 130 | +</div> |
| 131 | +``` |
| 132 | +``` |
| 133 | +
|
| 134 | +Output to any format, not just HTML. |
| 135 | +
|
| 136 | +### Divs and Spans |
| 137 | +
|
| 138 | +**Markdown:** Not supported. Must use raw HTML. |
| 139 | +
|
| 140 | +**Djot:** |
| 141 | +```djot |
| 142 | +::: warning |
| 143 | +This is a warning div. |
| 144 | +::: |
| 145 | +
|
| 146 | +This has a [styled span]{.highlight} inline. |
| 147 | +``` |
| 148 | + |
| 149 | +### Symbols |
| 150 | + |
| 151 | +**Markdown:** Not supported. |
| 152 | + |
| 153 | +**Djot:** |
| 154 | +```djot |
| 155 | +I :heart: Djot! The weather is :sunny: today. |
| 156 | +``` |
| 157 | + |
| 158 | +Symbols can be rendered as emoji, HTML entities, or custom output. |
| 159 | + |
| 160 | +### Definition Lists |
| 161 | + |
| 162 | +**Markdown:** Non-standard extension with varying syntax. |
| 163 | + |
| 164 | +**Djot:** |
| 165 | +```djot |
| 166 | +: Term |
| 167 | + Definition of the term. |
| 168 | +
|
| 169 | +: Another term |
| 170 | + Another definition. |
| 171 | +``` |
| 172 | + |
| 173 | +### Tables |
| 174 | + |
| 175 | +Both support tables, but Djot tables are more consistent: |
| 176 | + |
| 177 | +**Djot:** |
| 178 | +```djot |
| 179 | +| Header 1 | Header 2 | |
| 180 | +|----------|----------| |
| 181 | +| Cell 1 | Cell 2 | |
| 182 | +{.striped .bordered} |
| 183 | +``` |
| 184 | + |
| 185 | +Attributes on tables! |
| 186 | + |
| 187 | +## Migration Path |
| 188 | + |
| 189 | +This library provides tools for gradual migration: |
| 190 | + |
| 191 | +### 1. Convert Existing Content |
| 192 | + |
| 193 | +```php |
| 194 | +use Djot\Converter\MarkdownToDjot; |
| 195 | + |
| 196 | +$converter = new MarkdownToDjot(); |
| 197 | +$djot = $converter->convert($markdownContent); |
| 198 | +``` |
| 199 | + |
| 200 | +### 2. Output to Markdown if Needed |
| 201 | + |
| 202 | +```php |
| 203 | +use Djot\DjotConverter; |
| 204 | +use Djot\Renderer\MarkdownRenderer; |
| 205 | + |
| 206 | +$converter = new DjotConverter(); |
| 207 | +$doc = $converter->parse($djotContent); |
| 208 | + |
| 209 | +$renderer = new MarkdownRenderer(); |
| 210 | +$markdown = $renderer->render($doc); |
| 211 | +``` |
| 212 | + |
| 213 | +### 3. Accept Both Formats |
| 214 | + |
| 215 | +```php |
| 216 | +// Detect and convert Markdown on input |
| 217 | +if (containsMarkdownPatterns($input)) { |
| 218 | + $input = (new MarkdownToDjot())->convert($input); |
| 219 | +} |
| 220 | + |
| 221 | +$html = (new DjotConverter())->convert($input); |
| 222 | +``` |
| 223 | + |
| 224 | +## When to Stick with Markdown |
| 225 | + |
| 226 | +Markdown may still be the right choice when: |
| 227 | + |
| 228 | +- Your content is very simple (just paragraphs and basic formatting) |
| 229 | +- You're locked into a Markdown-only ecosystem (GitHub issues, etc.) |
| 230 | +- Your team is familiar with Markdown and change is costly |
| 231 | +- You don't need any of Djot's additional features |
| 232 | + |
| 233 | +## When to Choose Djot |
| 234 | + |
| 235 | +Djot is the better choice when: |
| 236 | + |
| 237 | +- You need consistent, predictable parsing |
| 238 | +- You want attributes on elements (classes, IDs, custom data) |
| 239 | +- You need features like highlighting, super/subscript, or symbols |
| 240 | +- You're building a new system without legacy constraints |
| 241 | +- You want a single specification, not "which Markdown flavor?" |
| 242 | +- You need to output to formats other than HTML |
| 243 | + |
| 244 | +## Learn More |
| 245 | + |
| 246 | +- [Official Djot Syntax Reference](https://djot.net/) |
| 247 | +- [Djot Playground](https://djot.net/playground/) |
| 248 | +- [Syntax Guide](syntax.md) - This library's syntax documentation |
| 249 | +- [Converters](converters.md) - Migration tools |
0 commit comments