-
Notifications
You must be signed in to change notification settings - Fork 5
/
marky-mark.red
196 lines (174 loc) · 3.58 KB
/
marky-mark.red
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
Red [
Title: "Marky Mark"
Author: "Boleslav Březovský"
File: %marky-mark.red
Rights: "Copyright (C) 2019 Boleslav Březovský. All rights reserved."
License: 'BSD
Date: "23-10-2016"
Note: {
This is very basic MarkDown parser just for use in the Red Gitter client.
It will be rewritten later based onRebol version of Marky-Mark.
}
]
marky-mark: func [
data
] [
out: make block! 5'000
text: make string! 2'000
value: make string! 500
stack: make block! 20
; ---
store: [
(
unless empty? text [
append out copy text
clear text
]
)
]
digits: charset [#"0" - #"9"]
letters: charset [#"a" - #"z" #"A" - #"Z"]
alphanum: union digits letters
symbols: charset "@#$~&-/*%()[]{}=+<>,."
alphanumsym: union alphanum symbols
; ---
temp: []
temp-pos: temp
mark-stack: []
select-command: func [mark] [
print ["select-command from" mark]
case [
find ["**" "__"] mark ('bold)
find ["*" "_"] mark ('italic)
equal? "`" mark ('code)
]
]
mark-rule: [
(temp-pos: clear temp)
copy mark ["**" | "__" | "*" | "_" | "`"]
(insert mark-stack mark)
(repend temp-pos reduce [quote select-command mark copy []])
(temp-pos: last temp)
some [
mark-rule
| [(mark: first mark-stack) ahead mark break]
| content-rule
]
(mark: take mark-stack)
mark
(if empty? mark-stack [append out temp])
]
content-rule: [
(unless string? temp-pos [temp-pos: first append temp-pos copy ""])
set value skip
(append temp-pos value)
]
; ---
code-rule: [
copy mark ["```" | #"`"] copy value to mark thru mark (
repend out [copy text 'code value]
clear text
)
]
fenced-code-rule: [
0 3 space
copy mark ["```" | "~~~"]
; TODO: info string ignored for now
thru newline
copy value
to mark
thru mark
(
repend out [copy text 'code value]
clear text
)
]
link-rule: [
#"["
copy value
to #"]" ; TODO: should be much less forgiving
skip
(append stack value)
#"("
copy value
to ")" ; TODO: see above
skip
(
append out reduce [copy text 'link take/last stack to url! copy value]
clear text
)
]
auto-link-rule: [
copy value [
["https" | "http"] "://"
some [some alphanum dot]
some alphanum
any alphanumsym
] (
append out reduce [copy text 'link copy value to url! value]
clear text
)
]
nick-rule: [
copy value [#"@" copy value to space] (
repend out [copy text 'nick copy value]
clear text
)
]
em-rule: [
#"*" copy value to #"*" skip (
repend out [copy text 'italic copy value]
clear text
)
]
strong-rule: [
"**" copy value to "**" 2 skip (
repend out [copy text 'bold copy value]
clear text
)
]
para-char-rule: [
char-rule (append text value)
]
char-rule: [ ; rule [value]
tab
| set value skip
]
rules: [
some [
; mark-rule
nick-rule
| fenced-code-rule
| code-rule
| link-rule
| auto-link-rule
| strong-rule
| em-rule
| para-char-rule
]
]
out: make block! 1000
clear text
parse data rules
unless empty? text [append out copy text]
copy out
]
; ---
emit-rich: function [
data
] [
value: none
stack: make block! 20
out: make block! 2 * length? data
parse data [
some [
set value string! (repend out ['font 'fonts/text value])
| 'bold set value string! (repend out ['font 'fonts/bold value])
| 'italic set value string! (repend out ['font 'fonts/italic value])
| 'code set value string! (repend out ['font 'fonts/fixed value])
| 'nick set value string! (repend out ['font 'fonts/underline value])
| 'link set value string! (append stack value) set value url! (repend out ['link take/last stack value])
]
]
out
]