-
-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathblock.ts
87 lines (81 loc) · 2.28 KB
/
block.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import { Action, Handler } from '.'
import { BlockBegin, BlockEnd } from '../types'
const block: Action = (begin: BlockBegin, context): Handler => {
context.save()
const contentStart = begin.position.end
const blockName = begin.name.toLowerCase()
const block = context.enter({
type: 'block',
name: begin.name,
params: begin.params,
value: '',
attributes: { ...context.attributes },
children: [],
})
context.push(context.lexer.eat())
/*
* find the indentation of the block and apply it to
* the rest of the block.
*
* The indentation of the first non-blank line is used as standard.
* The following lines use the lesser one between its own
* indentation and the standard. Leading and trailing blank lines
* are omitted.
*/
const align = (content: string) => {
let indent = -1
return content
.trimRight()
.split('\n')
.map((line) => {
const _indent = line.search(/\S/)
if (indent === -1) {
indent = _indent
}
if (indent === -1) return ''
let result = line.substring(Math.min(_indent, indent))
// remove escaping char ,
if (block.name.toLowerCase() === 'src' && block.params[0] === 'org') {
result = result.replace(/^(\s*),/, '$1')
}
return result
})
.join('\n')
.trim()
}
return {
name: 'block',
rules: [
{
test: 'block.end',
action: (token: BlockEnd, context) => {
if (token.name.toLowerCase() !== blockName) return 'next'
block.value = align(
context.lexer.substring({
start: contentStart,
end: token.position.start,
})
)
context.push(context.lexer.eat())
context.lexer.eat('newline')
context.exit('block')
return 'break'
},
},
{
test: ['stars', 'EOF'],
action: (_, context) => {
context.restore()
context.lexer.modify((t) => ({
type: 'text',
value: context.lexer.substring(t.position),
position: t.position,
}))
return 'break'
},
},
{ test: /./, action: (_, context) => context.push(context.lexer.eat()) },
],
}
}
export default block