sparx 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +358 -215
- data/lib/sparx/inline_processor.rb +3 -8
- data/lib/sparx/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8f518f3aeb2b3852e7935856bdebd43e66ae4708f9590532103d754f83bb547e
|
|
4
|
+
data.tar.gz: 49e1c604b1b2621ca57541ec7cb8a6fcd48ca88f58f89b9e810b173168f813d2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 67ed5bd703ed56fd478e6787acd6434b70f2aa81ea8f28b9e193485ff6e585089054695a113f651f18c5008ac965019d706b795fac64b93e43e9c04c424f0cf0
|
|
7
|
+
data.tar.gz: 822a37e85beb6c34c4742adb2028abf06b32a3619a2bbda3a4ebf85d6ae881293974f25b1cfe7ce95071a6ae498a96043ac17eb52f9f5e12f27afb9790b4f337
|
data/README.md
CHANGED
|
@@ -1,28 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
# Sparx - Markup That Sparks Joy ⚡
|
|
2
5
|
|
|
3
6
|
**Markdown was revolutionary in 2004. It's 2025. Time for the next evolution.**
|
|
4
7
|
|
|
5
|
-
Born from the same "spark joy" philosophy as the **[Joys](https://github.com/activestylus/joys)** view engine, Sparx eliminates the daily frustrations that developers
|
|
8
|
+
Born from the same "spark joy" philosophy as the **[Joys](https://github.com/activestylus/joys)** view engine, Sparx eliminates the daily frustrations that make developers want to scream at their markup. Clean syntax. Semantic HTML. Zero compromise.
|
|
6
9
|
|
|
7
10
|
---
|
|
8
11
|
|
|
9
|
-
##
|
|
12
|
+
## ⚡ Why Sparx Exists
|
|
13
|
+
|
|
14
|
+
### The Problem With Markdown
|
|
10
15
|
|
|
11
16
|
After 20 years, we're still fighting the same battles:
|
|
17
|
+
|
|
12
18
|
- `**bold**` vs `__bold__` vs `*italic*` confusion
|
|
13
|
-
- Broken nesting
|
|
19
|
+
- Broken nesting: `[link with **bold**](url)` → broken markup
|
|
14
20
|
- HTML soup whenever you need anything semantic
|
|
15
|
-
-
|
|
21
|
+
- Copy-pasting URLs everywhere like it's 1999
|
|
16
22
|
- Zero support for modern responsive images
|
|
23
|
+
- Tables that require ASCII art skills
|
|
17
24
|
- Academic citations? Good luck.
|
|
18
25
|
|
|
19
|
-
**Sparx
|
|
20
|
-
|
|
21
|
-
---
|
|
26
|
+
**Sparx solves every single one of these problems.**
|
|
22
27
|
|
|
23
|
-
|
|
28
|
+
### Quick Taste: Before & After
|
|
24
29
|
|
|
25
|
-
|
|
30
|
+
**Markdown:**
|
|
26
31
|
```markdown
|
|
27
32
|
**Bold** and *italic* with [broken **nesting**](https://example.com).
|
|
28
33
|
|
|
@@ -34,8 +39,8 @@ More HTML soup when you need structure.
|
|
|
34
39
|
</details>
|
|
35
40
|
```
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
```
|
|
42
|
+
**Sparx:**
|
|
43
|
+
```markdown
|
|
39
44
|
*[Bold] and /[italic] with perfect */[nesting]https://example.com.
|
|
40
45
|
|
|
41
46
|
i[Image]@cdn/image.jpg
|
|
@@ -47,294 +52,453 @@ i[Image]@cdn/image.jpg
|
|
|
47
52
|
@cdn: https://cdn.example.com/very/long/path/
|
|
48
53
|
```
|
|
49
54
|
|
|
50
|
-
|
|
55
|
+
```html
|
|
56
|
+
<strong>Bold</strong> and <em>italic</em> with <strong><em><a href="https://example.com">nesting</a></em></strong>.
|
|
57
|
+
|
|
58
|
+
<img src="https://cdn.example.com/very/long/path/image.jpg" alt="Image">
|
|
59
|
+
|
|
60
|
+
<details>
|
|
61
|
+
<summary>Advanced Content</summary>
|
|
62
|
+
<p>Clean structure without HTML soup.</p>
|
|
63
|
+
</details>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Same result. 17% fewer characters. Semantic HTML throughout. URLs defined once.**
|
|
51
67
|
|
|
52
68
|
---
|
|
53
69
|
|
|
54
|
-
##
|
|
70
|
+
## 🎯 Quick Reference
|
|
71
|
+
|
|
72
|
+
### Text Formatting
|
|
73
|
+
```markdown
|
|
74
|
+
*[bold] /[italic] -[strikethrough] `code`
|
|
75
|
+
s[small text] .highlight[styled span]
|
|
76
|
+
*/[bold italic] -[strikethrough *[with bold]] # Perfect nesting!
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Links (So Much Better!)
|
|
80
|
+
```markdown
|
|
81
|
+
[Simple link]https://example.com
|
|
82
|
+
[Link with title|Hover text]https://example.com
|
|
83
|
+
[External link]https://example.com^
|
|
84
|
+
*/[Bold italic link]https://example.com # Formatted links!
|
|
85
|
+
[Call us]tel:+1-555-0123 # Protocol links
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Media & Code
|
|
89
|
+
```markdown
|
|
90
|
+
i[Alt text]image.jpg
|
|
91
|
+
i[Alt|Title]image.jpg=300x200
|
|
55
92
|
|
|
56
|
-
### With Joys Framework
|
|
57
93
|
```ruby
|
|
58
|
-
|
|
94
|
+
def hello = "Multiline Code"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`One line of code`
|
|
98
|
+
```
|
|
59
99
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
100
|
+
### Containers & Structure
|
|
101
|
+
```markdown
|
|
102
|
+
$[section-id]{ content } # Sections
|
|
103
|
+
.[class-name]{ content } # Divs
|
|
104
|
+
>{ content } # Blockquotes
|
|
105
|
+
+[Summary]{ content } # Details/Summary
|
|
106
|
+
:term: definition # Definition lists
|
|
107
|
+
```
|
|
64
108
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
109
|
+
### References
|
|
110
|
+
```markdown
|
|
111
|
+
[Link text]@reference # URL references
|
|
112
|
+
[Citation]:1 # Numbered citations
|
|
113
|
+
@reference: https://example.com "Title" # Define once
|
|
114
|
+
1[Source]https://example.com "Description" # Citation definition
|
|
71
115
|
```
|
|
72
116
|
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 🚀 Installation & Usage
|
|
120
|
+
|
|
73
121
|
### Standalone
|
|
122
|
+
|
|
74
123
|
```ruby
|
|
75
124
|
gem install sparx
|
|
76
125
|
require 'sparx'
|
|
77
126
|
|
|
78
127
|
html = Sparx.parse(your_content)
|
|
128
|
+
# Use safe mode for user-generated content:
|
|
129
|
+
html = Sparx.parse(user_content, safe: true)
|
|
79
130
|
```
|
|
80
131
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
132
|
+
### With Joys Framework
|
|
133
|
+
```ruby
|
|
134
|
+
gem install sparx
|
|
84
135
|
|
|
85
|
-
|
|
136
|
+
Joys::Config.markup_parser = ->(content) {
|
|
137
|
+
Sparx.parse(content, safe: true)
|
|
138
|
+
}
|
|
86
139
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
*/[bold italic] -*[bold deleted]
|
|
140
|
+
# In your template:
|
|
141
|
+
div? "This is *[awesome]!"
|
|
142
|
+
# Adding ? to any DOM method enables automatic parsing!
|
|
91
143
|
```
|
|
92
144
|
|
|
93
|
-
**
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
145
|
+
**Love Ruby templates?** You're in for a treat! **[Joys](https://github.com/activestylus/joys)** is the view engine that renders 100x faster than ERB and makes building UI components an absolute joy.
|
|
146
|
+
|
|
147
|
+
### Command Line
|
|
148
|
+
```bash
|
|
149
|
+
sparx convert document.sparx
|
|
150
|
+
sparx convert document.sparx --safe
|
|
151
|
+
sparx convert input.sparx output.html
|
|
97
152
|
```
|
|
98
153
|
|
|
99
|
-
|
|
154
|
+
**File extensions:** `.sparx` or `.sx`
|
|
100
155
|
|
|
101
|
-
|
|
156
|
+
---
|
|
102
157
|
|
|
103
|
-
|
|
104
|
-
```
|
|
105
|
-
[GitHub]https://github.com
|
|
106
|
-
[Docs|Complete documentation]@docs^
|
|
107
|
-
[Call us]tel:+1-555-0199
|
|
158
|
+
## 📝 Core Syntax Deep Dive
|
|
108
159
|
|
|
109
|
-
|
|
160
|
+
### Text Formatting That Makes Sense
|
|
161
|
+
Every formatting element follows the same pattern: `symbol[content]`. No exceptions. No edge cases.
|
|
162
|
+
|
|
163
|
+
```markdown
|
|
164
|
+
*[bold text]
|
|
165
|
+
/[italic text]
|
|
166
|
+
-[strikethrough text]
|
|
167
|
+
s[small text]
|
|
168
|
+
.[class-name][styled text]
|
|
169
|
+
`inline code`
|
|
110
170
|
```
|
|
111
171
|
|
|
112
|
-
**Output:**
|
|
113
172
|
```html
|
|
114
|
-
<
|
|
115
|
-
<
|
|
116
|
-
<
|
|
173
|
+
<strong>bold text</strong>
|
|
174
|
+
<em>italic text</em>
|
|
175
|
+
<del>strikethrough text</del>
|
|
176
|
+
<small>small text</small>
|
|
177
|
+
<span class="class-name">styled text</span>
|
|
178
|
+
<code>inline code</code>
|
|
117
179
|
```
|
|
118
180
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
181
|
+
### The Magic of Perfect Nesting
|
|
182
|
+
```markdown
|
|
183
|
+
*/[bold italic] -[strikethrough *[with bold]]
|
|
184
|
+
```
|
|
122
185
|
|
|
123
|
-
|
|
186
|
+
```html
|
|
187
|
+
<strong><em>bold italic</em></strong> <del><strong>with bold</strong></del>
|
|
188
|
+
```
|
|
124
189
|
|
|
125
|
-
|
|
190
|
+
No more broken `[link with **bold**](url)` - it just works!
|
|
126
191
|
|
|
127
|
-
|
|
192
|
+
### Links That Don't Break Your Flow
|
|
193
|
+
```markdown
|
|
194
|
+
[Simple link]https://example.com
|
|
195
|
+
[Link with title|Hover text]https://example.com
|
|
196
|
+
[External link]https://example.com^
|
|
197
|
+
[Custom target]https://example.com^myframe
|
|
198
|
+
*/[Bold italic link]https://example.com
|
|
128
199
|
```
|
|
129
|
-
|
|
200
|
+
|
|
201
|
+
```html
|
|
202
|
+
<a href="https://example.com">Simple link</a>
|
|
203
|
+
<a href="https://example.com" title="Hover text">Link with title</a>
|
|
204
|
+
<a href="https://example.com" target="_blank">External link</a>
|
|
205
|
+
<a href="https://example.com" target="myframe">Custom target</a>
|
|
206
|
+
<strong><em><a href="https://example.com">Bold italic link</a></em></strong>
|
|
130
207
|
```
|
|
131
208
|
|
|
132
|
-
|
|
209
|
+
### Protocol Links Built-In
|
|
210
|
+
```markdown
|
|
211
|
+
[Call us]tel:+1-555-0123
|
|
212
|
+
[Email team]mailto:dev@example.com
|
|
213
|
+
[Text us]sms:+1-555-0123
|
|
214
|
+
[Location]geo:40.7128,-74.0060
|
|
215
|
+
[Open in VS Code]vscode://file/path
|
|
133
216
|
```
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
217
|
+
|
|
218
|
+
**Supported protocols:** `tel:`, `mailto:`, `sms:`, `facetime:`, `skype:`, `whatsapp:`, `zoom:`, `spotify:`, `vscode:`, `geo:`
|
|
219
|
+
|
|
220
|
+
### URL References (DRY Principle)
|
|
221
|
+
Define once, use everywhere:
|
|
222
|
+
|
|
223
|
+
```markdown
|
|
224
|
+
[Documentation]@docs and [API Reference]@docs/api
|
|
225
|
+
|
|
226
|
+
@docs: https://sparkdown.dev/docs "Complete Documentation"
|
|
137
227
|
```
|
|
138
228
|
|
|
139
|
-
**Output:**
|
|
140
229
|
```html
|
|
141
|
-
<
|
|
142
|
-
<source srcset="desktop.webp" type="image/webp" media="(min-width: 800px)">
|
|
143
|
-
<source srcset="desktop.jpg" type="image/jpeg" media="(min-width: 800px)">
|
|
144
|
-
<source srcset="tablet.webp" type="image/webp" media="(min-width: 400px)">
|
|
145
|
-
<source srcset="tablet.jpg" type="image/jpeg" media="(min-width: 400px)">
|
|
146
|
-
<img src="mobile.jpg" alt="Hero">
|
|
147
|
-
</picture>
|
|
230
|
+
<a href="https://sparkdown.dev/docs" title="Complete Documentation">Documentation</a> and <a href="https://sparkdown.dev/docs/api">API Reference</a>
|
|
148
231
|
```
|
|
149
232
|
|
|
150
|
-
|
|
233
|
+
Change your domain? Update one line. It's that simple.
|
|
151
234
|
|
|
152
|
-
|
|
235
|
+
---
|
|
153
236
|
|
|
154
|
-
|
|
237
|
+
## 🏗️ Building Blocks
|
|
155
238
|
|
|
156
|
-
|
|
239
|
+
### Sections with Automatic IDs
|
|
240
|
+
```markdown
|
|
241
|
+
$[introduction]{
|
|
242
|
+
# Welcome to Sparx
|
|
243
|
+
|
|
244
|
+
This content is in a semantic section.
|
|
245
|
+
}
|
|
157
246
|
|
|
158
|
-
|
|
247
|
+
[Jump to intro]#introduction
|
|
159
248
|
```
|
|
160
|
-
$[hero]{
|
|
161
|
-
# Welcome to */[the future]@site
|
|
162
|
-
|
|
163
|
-
>{
|
|
164
|
-
Finally, markup that doesn't make me want to scream.
|
|
165
|
-
- Every developer who tries Sparx
|
|
166
|
-
}
|
|
167
249
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
250
|
+
```html
|
|
251
|
+
<section id="introduction">
|
|
252
|
+
<h1>Welcome to Sparx</h1>
|
|
253
|
+
<p>This content is in a semantic section.</p>
|
|
254
|
+
</section>
|
|
255
|
+
<a href="#introduction">Jump to intro</a>
|
|
256
|
+
```
|
|
171
257
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
258
|
+
### Blockquotes with Citations
|
|
259
|
+
```markdown
|
|
260
|
+
>{
|
|
261
|
+
This is a simple blockquote.
|
|
177
262
|
}
|
|
178
263
|
|
|
179
|
-
|
|
264
|
+
>[https://source.com]{
|
|
265
|
+
This blockquote has a semantic citation.
|
|
266
|
+
}
|
|
180
267
|
```
|
|
181
268
|
|
|
182
|
-
**Output:**
|
|
183
269
|
```html
|
|
184
|
-
<section id="hero">
|
|
185
|
-
<h1>Welcome to <strong><em><a href="https://sparx.dev">the future</a></em></strong></h1>
|
|
186
270
|
<blockquote>
|
|
187
|
-
<p>
|
|
188
|
-
<p>- Every developer who tries Sparx</p>
|
|
271
|
+
<p>This is a simple blockquote.</p>
|
|
189
272
|
</blockquote>
|
|
190
|
-
<div class="warning">
|
|
191
|
-
<p>This will change how you think about markup.</p>
|
|
192
|
-
</div>
|
|
193
|
-
<details>
|
|
194
|
-
<summary>Technical Details</summary>
|
|
195
|
-
<dl>
|
|
196
|
-
<dt>Performance</dt><dd>100x faster parsing than traditional regex approaches</dd>
|
|
197
|
-
<dt>Output</dt><dd>Clean, semantic HTML5 throughout</dd>
|
|
198
|
-
<dt>DRY</dt><dd>URL references eliminate repetition</dd>
|
|
199
|
-
</dl>
|
|
200
|
-
</details>
|
|
201
|
-
</section>
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
Every element generates proper semantic HTML. Your accessibility audits will love you.
|
|
205
273
|
|
|
206
|
-
|
|
274
|
+
<blockquote cite="https://source.com">
|
|
275
|
+
<p>This blockquote has a semantic citation.</p>
|
|
276
|
+
</blockquote>
|
|
277
|
+
```
|
|
207
278
|
|
|
208
|
-
|
|
279
|
+
### Styled Divs
|
|
280
|
+
```markdown
|
|
281
|
+
.highlight{
|
|
282
|
+
This content is in a highlighted div.
|
|
283
|
+
}
|
|
209
284
|
|
|
210
|
-
|
|
285
|
+
.warning[This is a short warning]
|
|
286
|
+
```
|
|
211
287
|
|
|
212
|
-
|
|
288
|
+
```html
|
|
289
|
+
<div class="highlight">
|
|
290
|
+
<p>This content is in a highlighted div.</p>
|
|
291
|
+
</div>
|
|
213
292
|
|
|
214
|
-
|
|
293
|
+
<div class="warning">This is a short warning</div>
|
|
294
|
+
```
|
|
215
295
|
|
|
216
|
-
|
|
296
|
+
### Semantic Asides
|
|
217
297
|
```markdown
|
|
218
|
-
|
|
298
|
+
~{
|
|
299
|
+
This is aside content, properly marked up for screen readers.
|
|
300
|
+
}
|
|
301
|
+
```
|
|
219
302
|
|
|
220
|
-
|
|
303
|
+
```html
|
|
304
|
+
<aside>
|
|
305
|
+
<p>This is aside content, properly marked up for screen readers.</p>
|
|
306
|
+
</aside>
|
|
307
|
+
```
|
|
221
308
|
|
|
222
|
-
|
|
223
|
-
[API docs](https://docs.example.com/api).
|
|
309
|
+
---
|
|
224
310
|
|
|
225
|
-
|
|
226
|
-
<summary>Troubleshooting</summary>
|
|
311
|
+
## 📚 Advanced Content Structures
|
|
227
312
|
|
|
228
|
-
|
|
229
|
-
- Check for whitespace
|
|
230
|
-
- Verify token type
|
|
313
|
+
### Lists That Actually Work
|
|
231
314
|
|
|
232
|
-
**
|
|
233
|
-
|
|
234
|
-
-
|
|
315
|
+
**Simple Lists:**
|
|
316
|
+
```markdown
|
|
317
|
+
- Item one
|
|
318
|
+
- Item two
|
|
319
|
+
- Item three
|
|
235
320
|
|
|
236
|
-
|
|
321
|
+
+ First item
|
|
322
|
+
+ Second item
|
|
323
|
+
+ Third item
|
|
324
|
+
```
|
|
237
325
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
326
|
+
**Complex List Items:**
|
|
327
|
+
```markdown
|
|
328
|
+
- Simple item
|
|
329
|
+
-{
|
|
330
|
+
## Complex item with full power
|
|
331
|
+
|
|
332
|
+
Complete *[markup support], [links]@docs, and more.
|
|
333
|
+
|
|
334
|
+
>{
|
|
335
|
+
Even blockquotes work perfectly inside lists.
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
- Back to simple
|
|
241
339
|
```
|
|
242
340
|
|
|
243
|
-
|
|
341
|
+
```html
|
|
342
|
+
<ul>
|
|
343
|
+
<li>Simple item</li>
|
|
344
|
+
<li>
|
|
345
|
+
<h2>Complex item with full power</h2>
|
|
346
|
+
<p>Complete <strong>markup support</strong>, <a href="https://sparkdown.dev/docs">links</a>, and more.</p>
|
|
347
|
+
<blockquote>
|
|
348
|
+
<p>Even blockquotes work perfectly inside lists.</p>
|
|
349
|
+
</blockquote>
|
|
350
|
+
</li>
|
|
351
|
+
<li>Back to simple</li>
|
|
352
|
+
</ul>
|
|
244
353
|
```
|
|
245
|
-
## API Authentication
|
|
246
354
|
|
|
247
|
-
|
|
248
|
-
|
|
355
|
+
### Definition Lists
|
|
356
|
+
```markdown
|
|
357
|
+
:HTML: HyperText Markup Language
|
|
358
|
+
:CSS: Cascading Style Sheets
|
|
359
|
+
:JavaScript:{
|
|
360
|
+
A programming language for interactive web content.
|
|
361
|
+
|
|
362
|
+
Used by *[billions] of websites worldwide.
|
|
249
363
|
}
|
|
364
|
+
```
|
|
250
365
|
|
|
251
|
-
|
|
366
|
+
```html
|
|
367
|
+
<dl>
|
|
368
|
+
<dt>HTML</dt>
|
|
369
|
+
<dd>HyperText Markup Language</dd>
|
|
370
|
+
<dt>CSS</dt>
|
|
371
|
+
<dd>Cascading Style Sheets</dd>
|
|
372
|
+
<dt>JavaScript</dt>
|
|
373
|
+
<dd>
|
|
374
|
+
<p>A programming language for interactive web content.</p>
|
|
375
|
+
<p>Used by <strong>billions</strong> of websites worldwide.</p>
|
|
376
|
+
</dd>
|
|
377
|
+
</dl>
|
|
378
|
+
```
|
|
252
379
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
380
|
+
### Details/Summary
|
|
381
|
+
```markdown
|
|
382
|
+
+[Click to expand]{
|
|
383
|
+
This content is hidden by default.
|
|
384
|
+
|
|
385
|
+
- List items work
|
|
386
|
+
- *[Formatting] works
|
|
387
|
+
- [Links]https://example.com work
|
|
262
388
|
}
|
|
389
|
+
```
|
|
263
390
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
391
|
+
```html
|
|
392
|
+
<details>
|
|
393
|
+
<summary>Click to expand</summary>
|
|
394
|
+
<p>This content is hidden by default.</p>
|
|
395
|
+
<ul>
|
|
396
|
+
<li>List items work</li>
|
|
397
|
+
<li><strong>Formatting</strong> works</li>
|
|
398
|
+
<li><a href="https://example.com">Links</a> work</li>
|
|
399
|
+
</ul>
|
|
400
|
+
</details>
|
|
401
|
+
```
|
|
268
402
|
|
|
269
|
-
|
|
270
|
-
|
|
403
|
+
### Figures with Captions
|
|
404
|
+
```markdown
|
|
405
|
+
f[Figure 1: Architecture Diagram]{
|
|
406
|
+
i[System components]diagram.png
|
|
407
|
+
|
|
408
|
+
The diagram shows our microservices architecture
|
|
409
|
+
and how they communicate via REST APIs.
|
|
410
|
+
}
|
|
271
411
|
```
|
|
272
412
|
|
|
273
|
-
|
|
413
|
+
```html
|
|
414
|
+
<figure>
|
|
415
|
+
<img src="diagram.png" alt="System components">
|
|
416
|
+
<p>The diagram shows our microservices architecture and how they communicate via REST APIs.</p>
|
|
417
|
+
<figcaption>Figure 1: Architecture Diagram</figcaption>
|
|
418
|
+
</figure>
|
|
419
|
+
```
|
|
274
420
|
|
|
275
421
|
---
|
|
276
422
|
|
|
277
|
-
##
|
|
423
|
+
## 🖼️ Responsive Images Made Simple
|
|
278
424
|
|
|
279
|
-
###
|
|
425
|
+
### Basic Responsive Images
|
|
426
|
+
```markdown
|
|
427
|
+
i[Hero]hero.jpg 400w|hero@2x.jpg 800w|hero@3x.jpg 1200w
|
|
280
428
|
```
|
|
281
|
-
Research shows[significant performance gains]:1 in modern applications.
|
|
282
429
|
|
|
283
|
-
|
|
430
|
+
```html
|
|
431
|
+
<img src="hero.jpg"
|
|
432
|
+
srcset="hero.jpg 400w, hero@2x.jpg 800w, hero@3x.jpg 1200w"
|
|
433
|
+
alt="Hero">
|
|
284
434
|
```
|
|
285
435
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
436
|
+
### Art Direction
|
|
437
|
+
```markdown
|
|
438
|
+
src[>1024px]desktop.jpg
|
|
439
|
+
src[>768px]tablet.jpg
|
|
440
|
+
i[Hero]mobile.jpg
|
|
289
441
|
```
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
Even blockquotes work perfectly inside lists.
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
- Back to simple
|
|
442
|
+
|
|
443
|
+
```html
|
|
444
|
+
<picture>
|
|
445
|
+
<source srcset="desktop.jpg" media="(min-width: 1024px)">
|
|
446
|
+
<source srcset="tablet.jpg" media="(min-width: 768px)">
|
|
447
|
+
<img src="mobile.jpg" alt="Hero">
|
|
448
|
+
</picture>
|
|
301
449
|
```
|
|
302
450
|
|
|
303
|
-
|
|
451
|
+
### Format Switching
|
|
452
|
+
```markdown
|
|
453
|
+
src[>800px]image.{webp,jpg}
|
|
454
|
+
i[Fallback]image.jpg
|
|
455
|
+
```
|
|
304
456
|
|
|
305
|
-
|
|
457
|
+
```html
|
|
458
|
+
<picture>
|
|
459
|
+
<source srcset="image.webp" type="image/webp" media="(min-width: 800px)">
|
|
460
|
+
<source srcset="image.jpg" type="image/jpeg" media="(min-width: 800px)">
|
|
461
|
+
<img src="image.jpg" alt="Fallback">
|
|
462
|
+
</picture>
|
|
306
463
|
```
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## 📚 Academic Features
|
|
468
|
+
|
|
469
|
+
### Citations
|
|
470
|
+
```markdown
|
|
471
|
+
Research indicates[performance improvements]:1 in modern systems.
|
|
472
|
+
|
|
473
|
+
1[Important Study]https://journal.com/study "Peer-reviewed research"
|
|
312
474
|
```
|
|
313
475
|
|
|
314
|
-
|
|
476
|
+
```html
|
|
477
|
+
<p>Research indicates<a href="#cite-1">performance improvements<sup>1</sup></a> in modern systems.</p>
|
|
315
478
|
|
|
316
|
-
|
|
479
|
+
<section class="citations">
|
|
480
|
+
<cite id="cite-1"><span class="cite-number">1</span> <a href="https://journal.com/study" title="Peer-reviewed research">Important Study</a></cite>
|
|
481
|
+
</section>
|
|
482
|
+
```
|
|
317
483
|
|
|
318
|
-
|
|
484
|
+
---
|
|
319
485
|
|
|
320
|
-
|
|
486
|
+
## 🛡️ Security
|
|
321
487
|
|
|
322
488
|
```ruby
|
|
323
|
-
# Safe mode
|
|
489
|
+
# Safe mode for user-generated content
|
|
324
490
|
html = Sparx.parse(user_content, safe: true)
|
|
325
|
-
|
|
326
|
-
# Safe mode OFF - for trusted content
|
|
327
|
-
html = Sparx.parse(trusted_content)
|
|
328
491
|
```
|
|
329
492
|
|
|
330
|
-
|
|
493
|
+
**Safe mode automatically:**
|
|
494
|
+
- Escapes HTML tags (`<script>` → `<script>`)
|
|
495
|
+
- Blocks dangerous protocols (`javascript:`, `data:`, `vbscript:`)
|
|
496
|
+
- Sanitizes attribute values
|
|
497
|
+
- Preserves code blocks exactly as written
|
|
331
498
|
|
|
332
499
|
---
|
|
333
|
-
## Performance
|
|
334
500
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
### Performance Benchmarks
|
|
501
|
+
## ⚡ Performance
|
|
338
502
|
|
|
339
503
|
Sparx balances speed with advanced functionality. While pure Markdown parsers prioritize raw throughput, Sparx generates semantic HTML5 with features impossible in traditional markup languages.
|
|
340
504
|
|
|
@@ -389,31 +553,10 @@ Sparx balances speed with advanced functionality. While pure Markdown parsers pr
|
|
|
389
553
|
| Definition Lists | ❌ | ✅ | ❌ | **✅** |
|
|
390
554
|
| Perfect Nesting | ❌ | ❌ | ❌ | **✅** |
|
|
391
555
|
|
|
392
|
-
### Real-World Performance
|
|
393
|
-
|
|
394
|
-
For typical use cases, Sparx's parsing time is negligible:
|
|
395
|
-
|
|
396
|
-
- **Blog post** (746 chars): **0.22ms** to parse
|
|
397
|
-
- **Documentation** (2.3K chars): **0.69ms** to parse
|
|
398
|
-
- **Long content** (27K chars): **2.19ms** to parse
|
|
399
|
-
|
|
400
|
-
The development time saved by consistent syntax and semantic output far outweighs the microseconds spent parsing.
|
|
401
|
-
|
|
402
|
-
## Bottom Line
|
|
403
|
-
|
|
404
|
-
**Choose based on your needs:**
|
|
405
|
-
|
|
406
|
-
- **Need raw speed only?** Redcarpet is unbeatable for basic Markdown
|
|
407
|
-
- **Need features + reasonable speed?** Sparx delivers 2x better performance than Kramdown with 10x more functionality
|
|
408
|
-
- **Building semantic, accessible content?** Sparx is the only option that generates proper HTML5 throughout
|
|
409
|
-
|
|
410
|
-
*Performance measured in iterations per second. Higher is better. Memory usage measured as RSS delta during parsing.*
|
|
411
|
-
|
|
412
|
-
Conclusion: For most real-world use cases, the parsing time is negligible compared to the development time saved by cleaner syntax and semantic output.
|
|
413
556
|
|
|
414
557
|
---
|
|
415
558
|
|
|
416
|
-
## When to Use Sparx
|
|
559
|
+
## 🎯 When to Use Sparx
|
|
417
560
|
|
|
418
561
|
**Perfect for:**
|
|
419
562
|
- Technical documentation requiring semantic structure
|
|
@@ -429,7 +572,7 @@ Conclusion: For most real-world use cases, the parsing time is negligible compar
|
|
|
429
572
|
|
|
430
573
|
---
|
|
431
574
|
|
|
432
|
-
## The Bottom Line
|
|
575
|
+
## 🎊 The Bottom Line
|
|
433
576
|
|
|
434
577
|
Markdown taught us that writing shouldn't require thinking about HTML. Sparx teaches us that **developers** shouldn't need to compromise on semantic markup quality.
|
|
435
578
|
|
|
@@ -443,4 +586,4 @@ gem install sparx
|
|
|
443
586
|
|
|
444
587
|
---
|
|
445
588
|
|
|
446
|
-
*Sparx is part of the [Joys](https://github.com/activestylus/joys) ecosystem - Ruby tools that spark joy for developers.*
|
|
589
|
+
*Sparx is part of the [Joys](https://github.com/activestylus/joys) ecosystem - Ruby tools that spark joy for developers.*
|
|
@@ -4,7 +4,7 @@ module Sparx
|
|
|
4
4
|
ESCAPE_ATTR = {'"' => '"', "'" => ''', '<' => '<', '>' => '>'}.freeze
|
|
5
5
|
STANDALONE = /([*\/-]+)\[([^\[\]]*)\]/.freeze
|
|
6
6
|
HEADING = /^(\#{1,6})(?!\#)\s+(.+)$/.freeze
|
|
7
|
-
LINK_FORMAT =/([*\/-]*)\[([^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*?)\](
|
|
7
|
+
LINK_FORMAT =/([*\/-]*)\[([^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*?)\](\/|[a-zA-Z0-9]+:\/\/|www\.|@|#|(?:tel|mailto|sms|facetime|skype|whatsapp|geo|zoom|spotify|vscode):)([^\s\[\]^]*)(\^[a-zA-Z0-9_]*)?/.freeze
|
|
8
8
|
BRACKETS1 = /([*\/-]+)\[([^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*)\]/.freeze
|
|
9
9
|
BRACKETS2 = /([*\/-]+)\[([^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*)\]/.freeze
|
|
10
10
|
CITATIONS = /([*\/-]*)\[([^\[\]]+?)\]@([a-zA-Z0-9_-]+)/.freeze
|
|
@@ -49,14 +49,9 @@ def self.process_links_with_formatting(content, citations, numbered_citations, r
|
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
def self.valid_url?(url_prefix, url_suffix)
|
|
52
|
-
return
|
|
52
|
+
return !url_suffix.match(/^[.,;!?]/) if url_prefix == "/" # Remove length check
|
|
53
53
|
full_url = "#{url_prefix}#{url_suffix}"
|
|
54
|
-
|
|
55
|
-
if full_url =~ /^([a-zA-Z]+):/i
|
|
56
|
-
return SAFE_PROTOCOLS.include?($1.downcase)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
true
|
|
54
|
+
full_url.length > 1
|
|
60
55
|
end
|
|
61
56
|
def self.process_standalone_formatting(content, recursive_processor = nil)
|
|
62
57
|
content.gsub(STANDALONE) do
|
data/lib/sparx/version.rb
CHANGED