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
|
---@class markdown
local mt = {}
mt.__index = mt
mt.__name = 'markdown'
mt._splitLine = false
function mt:__tostring()
return self:string()
end
---@param language string
---@param text? string|markdown
function mt:add(language, text)
if not text then
return self
end
self._cacheResult = nil
if type(text) == 'table' then
self[#self+1] = {
type = 'markdown',
markdown = text,
}
else
text = tostring(text)
self[#self+1] = {
type = 'text',
language = language,
text = text,
}
end
return self
end
function mt:splitLine()
self._cacheResult = nil
self[#self+1] = {
type = 'splitline',
}
return self
end
function mt:emptyLine()
self._cacheResult = nil
self[#self+1] = {
type = 'emptyline',
}
return self
end
---@return string
function mt:string(nl)
if self._cacheResult then
return self._cacheResult
end
local lines = {}
local language = 'md'
local function concat(markdown)
for _, obj in ipairs(markdown) do
if obj.type == 'splitline' then
if language ~= 'md' then
lines[#lines+1] = '```'
language = 'md'
end
if #lines > 0
and lines[#lines] ~= '---' then
lines[#lines+1] = ''
lines[#lines+1] = '---'
end
elseif obj.type == 'emptyline' then
if #lines > 0
and lines[#lines] ~= '' then
if language ~= 'md' then
language = 'md'
lines[#lines+1] = '```'
end
lines[#lines+1] = ''
end
elseif obj.type == 'markdown' then
concat(obj.markdown)
else
if obj.language ~= language then
if language ~= 'md' then
lines[#lines+1] = '```'
end
if #lines > 0 then
lines[#lines+1] = ''
end
if obj.language ~= 'md' then
lines[#lines+1] = '```' .. obj.language
end
end
if obj.language == 'md' and #lines > 0 then
local last = lines[#lines]
if obj.text:sub(1, 1) == '@'
or last:sub(1, 1) == '@' then
if lines[#lines] ~= '' then
lines[#lines+1] = ''
end
elseif last == '---' then
if lines[#lines] ~= '' then
lines[#lines+1] = ''
end
end
end
lines[#lines+1] = obj.text
language = obj.language
end
end
end
concat(self)
if language ~= 'md' then
lines[#lines+1] = '```'
end
while true do
if lines[#lines] == '---'
or lines[#lines] == '' then
lines[#lines] = nil
else
break
end
end
local result = table.concat(lines, nl or '\n')
self._cacheResult = result
return result
end
return function ()
return setmetatable({}, mt)
end
|