tangled
alpha
login
or
join now
ansxor.ca
/
markup2
0
fork
atom
this repo has no description
0
fork
atom
overview
issues
1
pulls
pipelines
new table dividers, fix `` parsing
12Me21
3 years ago
62b1cd34
f4677d09
+138
-76
3 changed files
expand all
collapse all
unified
split
markup.css
parse.js
render.js
+87
-64
markup.css
···
15
15
16
16
*:not(*>*) { /* this selects :root with 0 specificity */
17
17
/* normal colors */
18
18
-
--T-color: black;
19
18
--T-bg: white;
20
19
21
20
--T-link-color: #056;
···
24
23
--T-custom-link-decoration: underline blue;
25
24
26
25
--T-border-color: gray; /* nnnnn... */
27
27
-
/* these are transparent, so they should work with both dark and light */
26
26
+
28
27
--T-image-border: 1px solid var(--T-border-color);
29
28
30
30
-
--T-box-bg: #AAA2;
29
29
+
--T-embed-height: 10vh;
31
30
32
32
-
--T-red-bg: #F888;
33
33
-
--T-green-bg: #FA08;
34
34
-
--T-yellow-bg: #FF08;
35
35
-
--T-orange-bg: #0F08;
36
36
-
--T-blue-bg: #08F8;
37
37
-
--T-purple-bg: #C0F8;
38
38
-
--T-gray-bg: #AAA8;
39
39
-
40
40
-
--T-link-bg: #5CE5; /* for links w/ custom text */
31
31
+
/* for colored table cells, etc. */
32
32
+
/* these are transparent, so they should work with both dark and light */
33
33
+
888;
34
34
+
#0F08;
35
35
+
#FF08;
36
36
+
#FA08;
37
37
+
08F8;
38
38
+
#C0F8;
39
39
+
AAA8;
41
40
42
42
-
43
43
-
--T-tab-size: 2.5;
44
44
-
--T-embed-height: 10vh;
41
41
+
--T-box-bg: #AAA2;
45
42
46
46
-
--T-font: 1em sans-serif;
47
47
-
--T-monospace-font: 0.8128em consolas, monospace;
43
43
+
/* other values used :
44
44
+
--T-tab-size
45
45
+
--T-monospace-font
46
46
+
47
47
+
--T-table-border
48
48
+
--T-table-outer-border
49
49
+
--T-table-thick-border
50
50
+
51
51
+
--T-code-color
52
52
+
--T-code-bg
53
53
+
54
54
+
--T-red-bg:
55
55
+
--T-green-bg:
56
56
+
--T-yellow-bg:
57
57
+
--T-orange-bg:
58
58
+
--T-blue-bg:
59
59
+
--T-purple-bg:
60
60
+
--T-gray-bg:
61
61
+
*/
48
62
}
49
63
50
64
/** aa */
51
65
52
66
.Markup {
53
53
-
color: var(--T-color);
54
67
background: var(--T-bg);
55
55
-
font: var(--T-font); /* this is kinda bad.. maybe there should be a --T-markup-font ? or something separate for the main site and markup. then you can set --T-markup-font to "inherit" */
68
68
+
font-family: inherit;
56
69
font-variant-ligatures: none;
57
57
-
-moz-tab-size: var(--T-tab-size);
58
58
-
tab-size: var(--T-tab-size);
70
70
+
-moz-tab-size: var(--T-tab-size, 2.5); tab-size: var(--T-tab-size, 2.5);
59
71
}
60
72
61
73
.Markup * {
···
108
120
.Markup img[data-state="loaded"] {
109
121
height: auto;
110
122
}
111
111
-
.Markup img[data-state="size"] {
112
112
-
}
113
123
114
124
/* ruby text doesn't work if set to white-space: pre */
115
125
.Markup rt {
···
121
131
background: #F888;
122
132
}
123
133
124
124
-
/*** keyboard key ***/
125
125
-
.Markup kbd {
126
126
-
display: inline-block;
127
127
-
128
128
-
background: var(--T-box-bg);
129
129
-
border: 1px solid var(--T-border-color);
130
130
-
border-radius: 3px;
131
131
-
padding: 0.1875rem 0.375rem;
132
132
-
font: var(--T-monospace-font);
133
133
-
vertical-align: middle;
134
134
-
}
135
135
-
136
134
/*** divider ***/
137
135
.Markup hr {
138
136
margin: 0.5rem 0;
139
137
}
140
138
141
141
-
/**********/
142
142
-
/** Code **/
143
143
-
/**********/
144
144
-
.Markup pre, .Markup code {
145
145
-
font: var(--T-monospace-font);
139
139
+
.Markup pre, .Markup code, .Markup kbd {
140
140
+
font-family: var(--T-monospace-font, "Cascadia Code", consolas, monospace);
141
141
+
font-size: 0.8125em;
146
142
}
147
147
-
/* inline */
143
143
+
/*** Inline Code ***/
144
144
+
/*** ` ***/
148
145
.Markup code {
149
146
line-break: anywhere;
150
150
-
vertical-align: 1px;
151
151
-
background: #9996;
147
147
+
background: #9995;
152
148
padding: 0 0.1875em;
153
149
border-radius: 4px;
154
150
margin: 0 0.1em;
151
151
+
vertical-align: 1px;
155
152
}
156
156
-
/* block */
153
153
+
.Markup th code {
154
154
+
white-space: pre-wrap;
155
155
+
line-break: unset;
156
156
+
word-break: normal; overflow-wrap: break-word;
157
157
+
}
158
158
+
/*** Code Block ***/
159
159
+
/*** ``` ***/
157
160
.Markup pre {
158
158
-
color: white;
159
159
-
background: black;
161
161
+
color: var(--T-code-color, white);
162
162
+
background: var(--T-code-bg, black);
160
163
border: 1px solid black;
161
164
padding: 0.5em;
162
165
margin: 0.25em 0;
163
166
line-break: anywhere;
164
167
}
168
168
+
/*** Keyboard Key ***/
169
169
+
/*** \kbd ***/
170
170
+
.Markup kbd {
171
171
+
display: inline-block;
172
172
+
173
173
+
background: var(--T-box-bg);
174
174
+
border: 1px solid var(--T-border-color);
175
175
+
border-radius: 3px;
176
176
+
padding: 0.1875rem 0.375rem;
177
177
+
vertical-align: middle;
178
178
+
}
165
179
166
166
-
/*************/
167
167
-
/** Spoiler **/
168
168
-
/*************/
180
180
+
/*** Spoiler ***/
181
181
+
/*** \spoiler \h ***/
169
182
.M-spoiler-label {
170
183
display: table; /* width... */
171
184
background: var(--T-box-bg);
···
224
237
.M-table-outer {
225
238
overflow-x: auto;
226
239
}
227
227
-
.Markup table, .Markup td, .Markup th {
228
228
-
border: 1px solid var(--T-color);
240
240
+
.Markup table, .Markup tr > * {
229
241
border-collapse: collapse;
230
242
}
231
231
-
.Markup td, .Markup th {
243
243
+
.Markup table {
244
244
+
border: var(--T-table-outer-border, 3px solid #222);
245
245
+
}
246
246
+
.Markup tr > * {
232
247
padding: 0.1875em 0.3125em;
233
248
/* alternate text wrap mode, produces better table widths (somewhat) */
234
249
word-break: normal; overflow-wrap: break-word;
250
250
+
border: var(--T-table-border, 1px solid #222);
251
251
+
}
252
252
+
.Markup tr > .M-wall-top {
253
253
+
border-top: var(--T-table-thick-border, 4px solid #222);
254
254
+
}
255
255
+
.Markup tr > .M-wall-right {
256
256
+
border-right: var(--T-table-thick-border, 4px solid #222);
235
257
}
236
258
237
259
/**********************/
238
260
/** Background Color **/
239
261
/**********************/
240
240
-
.Markup [data-bgcolor="red"] { background: var(--T-red-bg) }
241
241
-
.Markup [data-bgcolor="orange"] { background: var(--T-orange-bg) }
242
242
-
.Markup [data-bgcolor="yellow"] { background: var(--T-yellow-bg) }
243
243
-
.Markup [data-bgcolor="green"] { background: var(--T-green-bg) }
244
244
-
.Markup [data-bgcolor="blue"] { background: var(--T-blue-bg) }
245
245
-
.Markup [data-bgcolor="purple"] { background: var(--T-purple-bg) }
246
246
-
.Markup [data-bgcolor="gray"] { background: var(--T-gray-bg) }
262
262
+
.Markup [data-bgcolor="red"] { background: var(--T-red-bg, #F888) }
263
263
+
.Markup [data-bgcolor="orange"] { background: var(--T-orange-bg, #FA08) }
264
264
+
.Markup [data-bgcolor="yellow"] { background: var(--T-yellow-bg, #FF08) }
265
265
+
.Markup [data-bgcolor="green"] { background: var(--T-green-bg, #0F08) }
266
266
+
.Markup [data-bgcolor="blue"] { background: var(--T-blue-bg, #08F8) }
267
267
+
.Markup [data-bgcolor="purple"] { background: var(--T-purple-bg, #C0F8) }
268
268
+
.Markup [data-bgcolor="gray"] { background: var(--T-gray-bg, #AAA8) }
247
269
.Markup table { background: var(--T-bg); } /* reset */
248
270
249
271
/***********/
250
272
/** Links **/
251
273
/***********/
252
274
.M-link {
253
253
-
color: var(--T-link-color);
254
254
-
text-decoration: var(--T-link-decoration);
255
255
-
-webkit-text-decoration: var(--T-link-decoration);
275
275
+
color: var(--T-link-color, #056);
276
276
+
text-decoration: underline;
277
277
+
text-decoration: var(--T-link-decoration, underline #AAAA);
278
278
+
-webkit-text-decoration: var(--T-link-decoration, underline #AAAA);
256
279
}
257
280
.M-link:hover {
258
281
color: var(--T-link-hover-color);
···
281
304
padding-left: 1em;
282
305
}
283
306
284
284
-
.Markup li:last-child {
285
285
-
margin-bottom: 0.25em;
307
307
+
.Markup li {
308
308
+
margin: 0.25em 0;
286
309
}
287
310
288
311
/*************/
+45
-11
parse.js
···
41
41
`{BOL}[\`]{3}(?!.*?[\`])${'CODE_BLOCK'}`
42
42
`[\`][^\`\n]*([\`]{2}[^\`\n]*)*[\`]?${'INLINE_CODE'}`
43
43
`([!]${'EMBED'})?\b(https?://|sbs:){URL_CHARS}{URL_FINAL}([(]{URL_CHARS}[)]({URL_CHARS}{URL_FINAL})?)?${'LINK'}`
44
44
+
`{BOL}[|][-][-+]*[-][|]{EOL}${'TABLE_DIVIDER'}` // `{BOL}[|][|][|]{EOL}${'TABLE_DIVIDER'}`
44
45
`{BOL} *[|]${'TABLE_START'}`
45
45
-
` *[|]${'TABLE_CELL'}`
46
46
+
` *[|][|]?${'TABLE_CELL'}`
46
47
`{BOL} *[-]${'LIST_ITEM'}`
47
48
()
48
49
···
56
57
// creates 2 cells, with 2 lines each, rather than 2 rows.
57
58
// i.e: each added row will just append its contents to the cells
58
59
// of the previous row.
60
60
+
// maybe this should be an arg instead? on a row, to merge it with prev or etc..
59
61
60
62
61
63
// all state is stored in these vars (and REGEX.lastIndex)
···
63
65
64
66
// About __proto__ in object literals:
65
67
// https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-runtime-semantics-propertydefinitionevaluation
66
66
-
const IS_BLOCK = {__proto__:null, code:1, divider:1, ROOT:1, heading:1, quote:1, table:1, table_cell:1, image:1, video:1, audio:1, spoiler:1, align:1, list:1, list_item:1, youtube:1, anchor:1}
68
68
+
const IS_BLOCK = {__proto__:null, code:1, divider:1, ROOT:1, heading:1, quote:1, table:1, table_cell:1, image:1, video:1, audio:1, spoiler:1, align:1, list:1, list_item:1, youtube:1, anchor:1, table_divider:1}
67
69
68
70
69
71
// argument processing //
···
132
134
let m
133
135
if ("*"===arg || "#"===arg)
134
136
args.header = true
137
137
+
else if ("-div"===arg)
138
138
+
args.div = true
135
139
else if (is_color(arg))
136
140
args.color = arg
137
141
else if (m = /^(\d*)x(\d*)$/.exec(arg)) {
···
194
198
}
195
199
} break; case 'null_env': {
196
200
current.content.push(...o.content)
201
201
+
} break; case 'table_divider': {
202
202
+
let above = get_last(current)
203
203
+
if (above && 'table'===above.type) {
204
204
+
above.args = {divider:true}
205
205
+
}
197
206
} break; case 'table_cell': {
198
207
// push cell if not empty
199
208
if (!cancel || o.content.length) {
···
234
243
push(dest, type, null, o.content)
235
244
} break; case 'table_row': {
236
245
let dest = get_last(current)
237
237
-
if (!dest || 'table'!==dest.type)
246
246
+
if (!dest || 'table'!==dest.type) {
238
247
dest = push(current, 'table', null, [])
248
248
+
} else {
249
249
+
if (dest.args && dest.args.divider) {
250
250
+
delete dest.args.divider
251
251
+
o.args.divider = true
252
252
+
}
253
253
+
}
239
254
push(dest, type, o.args, o.content)
240
255
} }
241
256
···
269
284
// parsing //
270
285
271
286
const STYLE_START
272
272
-
= /^[\s][^\s,]|^['"}{(>][^\s,'"]/
287
287
+
= /^[\s][^\s,]|^['"}{(>|][^\s,'"]/
273
288
const STYLE_END
274
274
-
= /^[^\s,][-\s.,:;!?'"}{)<\\]/
289
289
+
= /^[^\s,][-\s.,:;!?'"}{)<\\|]/
275
290
const ITALIC_START
276
276
-
= /^[\s][^\s,/]|^['"}{(>][^\s,'"/]/
291
291
+
= /^[\s][^\s,/]|^['"}{(>|][^\s,'"/]/
277
292
const ITALIC_END
278
278
-
= /^[^\s,/][-\s.,:;!?'"}{)<\\]/
293
293
+
= /^[^\s,/][-\s.,:;!?'"}{)<\\|]/
279
294
280
295
const find_style=(token)=>{
281
296
for (let c=current; 'style'===c.type; c=c.parent)
···
366
381
367
382
let match
368
383
let last = REGEX.lastIndex = 0
369
369
-
const NEVERMIND=()=>{
370
370
-
REGEX.lastIndex = match.index+1
384
384
+
const NEVERMIND=(index=match.index+1)=>{
385
385
+
REGEX.lastIndex = index
371
386
}
372
387
const ACCEPT=()=>{
373
388
TEXT(text.substring(last, match.index))
···
493
508
while (current!==c)
494
509
CLOSE(true)
495
510
CLOSE() // cell
511
511
+
// TODO: HACK
512
512
+
if (/^ *[|][|]/.test(token)) {
513
513
+
let last = current.content[current.content.length-1]
514
514
+
last.args.div = true
515
515
+
}
496
516
// we don't know whether these are row args or cell args,
497
517
// so just pass the raw args directly, and parse them later.
498
518
OPEN('table_cell', rargs)
499
519
break
500
520
}
501
521
if ('style'!==c.type) {
502
502
-
NEVERMIND()
522
522
+
// normally NEVERMIND skips one char,
523
523
+
// e.g. if we parse "abc" and that matches but gets rejected, it'll try parsing at "bc".
524
524
+
// but table cell tokens can look like this: " ||"
525
525
+
// if we skip 1 char (a space), it would try to parse a table cell again several times.
526
526
+
// so instead we skip to the end of the token because we know it's safe in this case.
527
527
+
NEVERMIND(REGEX.lastIndex)
503
528
continue main
504
529
}
505
530
}
531
531
+
} break; case 'TABLE_DIVIDER': {
532
532
+
//skip_spaces()
533
533
+
let tbl = get_last(current)
534
534
+
if (!tbl || 'table'!==tbl.type) {
535
535
+
NEVERMIND()
536
536
+
continue main
537
537
+
}
538
538
+
ACCEPT()
539
539
+
OPEN('table_divider')
506
540
} break; case 'TABLE_START': {
507
541
read_args()
508
542
skip_spaces()
···
578
612
BLOCK('code', {text:code, lang})
579
613
} break; case 'INLINE_CODE': {
580
614
ACCEPT()
581
581
-
BLOCK('icode', {text: token.replace(/`(`)?/g, "$1")})
615
615
+
BLOCK('icode', {text: token.replace(/^`|`$/g, "").replace(/``/g, "`")})
582
616
} break; case 'EMBED': {
583
617
read_args()
584
618
ACCEPT()
+6
-1
render.js
···
251
251
252
252
table_row: 𐀶`<tr>`,
253
253
254
254
-
table_cell: function({header, color, truecolor, colspan, rowspan, align}, row_args) {
254
254
+
table_cell: function({header, color, truecolor, colspan, rowspan, align, div}, row_args) {
255
255
let e = this[header||row_args.header ? 1 : 0]()
256
256
if (color) e.dataset.bgcolor = color
257
257
if (truecolor) e.style.backgroundColor = truecolor
258
258
if (colspan) e.colSpan = colspan
259
259
if (rowspan) e.rowSpan = rowspan
260
260
if (align) e.style.textAlign = align
261
261
+
// todo: better way of representing this?
262
262
+
if (div)
263
263
+
e.classList.add('M-wall-right')
264
264
+
if (row_args.divider)
265
265
+
e.classList.add('M-wall-top')
261
266
return e
262
267
}.bind([𐀶`<td>`, 𐀶`<th>`]),
263
268