-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathclaude_chat.lua
More file actions
80 lines (68 loc) · 2.23 KB
/
claude_chat.lua
File metadata and controls
80 lines (68 loc) · 2.23 KB
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
--[[
wrap_turns.lua — Pandoc Lua filter
Wraps each chat turn (h2 speaker heading + following content up to the
next hr or h2) in a <div class="turn frank|claude"> block.
Structure in the flat AST:
HorizontalRule
Header 2 "Frank" ← speaker
Para ... ← content
HorizontalRule
Header 2 "Claude" ← speaker
Para / BulletList / CodeBlock / Table ...
HorizontalRule
...
]]
function Pandoc(doc)
local blocks = doc.blocks
local out = {}
local i = 1
local n = #blocks
while i <= n do
local blk = blocks[i]
-- Detect a speaker heading: level-2 header whose text is Frank or Claude
if blk.t == "Header" and blk.level == 2 then
local text = pandoc.utils.stringify(blk)
local speaker = text:match("^(Frank)") or text:match("^(Claude)")
if speaker then
local cls = speaker:lower() -- "frank" or "claude"
-- Build the label span (replaces the bare h2)
local label = pandoc.Div(
{ pandoc.Para({ pandoc.Str(text) }) },
pandoc.Attr("", {"turn-label"})
)
-- Collect content blocks until the next hr or level-2 header
local content = {}
i = i + 1
while i <= n do
local cb = blocks[i]
if cb.t == "HorizontalRule" then
break -- end of this turn (consume the hr below)
elseif cb.t == "Header" and cb.level == 2 then
break -- next speaker starts (don't consume)
else
content[#content + 1] = cb
i = i + 1
end
end
-- Wrap label + content in div.turn.(frank|claude)
local bubble = pandoc.Div(content, pandoc.Attr("", {"bubble"}))
local turn = pandoc.Div({label, bubble},
pandoc.Attr("", {"turn", cls}))
out[#out + 1] = turn
-- Skip the trailing hr if present
if i <= n and blocks[i].t == "HorizontalRule" then
i = i + 1
end
else
-- Non-speaker h2: pass through unchanged
out[#out + 1] = blk
i = i + 1
end
else
-- Everything before the first speaker (title para, leading hr, etc.)
out[#out + 1] = blk
i = i + 1
end
end
return pandoc.Pandoc(out, doc.meta)
end