mirror of
https://github.com/Oreolek/ink-instead.git
synced 2024-05-13 06:28:24 +03:00
Merge pull request #4 from premek/flatparse
Flat parser refactor - parsed table is now flat, not nested - e.g. knot content is not inside the knot node but following the knot node. the same for options. Simpler parser, runtime not much more complicated
This commit is contained in:
commit
faedb6a3be
|
@ -4,11 +4,6 @@ local S,C,Ct,Cc,Cg,Cb,Cf,Cmt,P,V =
|
|||
lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg, lpeg.Cb, lpeg.Cf, lpeg.Cmt,
|
||||
lpeg.P, lpeg.V
|
||||
|
||||
local concat = function (p)
|
||||
return Cf(p, function (a,b) return a..b end)
|
||||
end
|
||||
|
||||
local parserLogger = print
|
||||
local eof = -1
|
||||
local sp = S" \t" ^0 + eof
|
||||
local wh = S" \t\r\n" ^0 + eof
|
||||
|
@ -16,68 +11,52 @@ local nl = S"\r\n" ^1 + eof
|
|||
local id = (lpeg.alpha + '_') * (lpeg.alnum + '_')^0
|
||||
local addr = C(id) * ('.' * C(id))^-1
|
||||
|
||||
local todo = sp * 'TODO:' * sp * (1-nl)^0 / parserLogger * wh -- TODO log location
|
||||
local commOL = sp * '//' * sp * (1-nl)^0 * wh
|
||||
local commML = sp * '/*' * wh * (P(1)-'*/')^0 * '*/' * wh
|
||||
local todo = Ct(sp * 'TODO:'/"todo" * sp * C((1-nl)^0)) * wh
|
||||
local commOL = Ct(sp * '//'/"comment" * sp * C((1-nl)^0)) * wh
|
||||
local commML = Ct(sp * '/*'/"comment" * wh * C((P(1)-'*/')^0)) * '*/' * wh
|
||||
local comm = commOL + commML + todo
|
||||
|
||||
local glue = P'<>'/'glue' *wh -- FIXME do not consume spaces after glue
|
||||
local glue = Ct(P'<>'/'glue') *wh -- FIXME do not consume spaces after glue
|
||||
|
||||
local divertSym = '->' *wh
|
||||
local divertEndSym = C('END') *wh
|
||||
local divertEnd = divertSym * divertEndSym
|
||||
local divertEnd = Ct(divertSym/'end' * 'END' * wh)
|
||||
local divertJump = Ct(divertSym/'divert' * addr * wh)
|
||||
local divert = divertEnd + divertJump
|
||||
|
||||
local knotHead = P('=')^2/'knot' * wh * C(id) * wh * P('=')^0 * wh
|
||||
local stitchHead = P('=')^1/'stitch' * wh * C(id) * wh * P('=')^0 * wh
|
||||
local knot = Ct(P('=')^2/'knot' * wh * C(id) * wh * P('=')^0) * wh
|
||||
local stitch = Ct(P('=')^1/'stitch' * wh * C(id) * wh * P('=')^0) * wh
|
||||
|
||||
local optDiv = '[' * C((P(1) - ']')^0) * ']'
|
||||
|
||||
local optStars = concat(wh * C(P'*') * (sp * C'*')^0)
|
||||
local optStarsSameIndent = Cmt(Cb("indent") * optStars,
|
||||
function (s, i, a, b) return a == b end)
|
||||
local optStarsLEIndent = Cmt(Cb("indent") * optStars,
|
||||
function (s, i, backtrack, this)
|
||||
return string.len(this) <= string.len(backtrack)
|
||||
end)
|
||||
|
||||
|
||||
local tag = Ct(wh * P('#')/'tag' * wh * V'text' * wh)
|
||||
|
||||
local optStars = wh * Ct(C'*' * (sp * C'*')^0)/table.getn
|
||||
|
||||
local hash = P('#')
|
||||
local tag = hash * wh * V'text'
|
||||
local tagGlobal = Ct(Cc'tag' * Cc'global' * tag * wh)
|
||||
local tagAbove = Ct(Cc'tag' * Cc'above' * tag * wh)
|
||||
local tagEnd = Ct(Cc'tag' * Cc'end' * tag * sp)
|
||||
|
||||
local ink = P({
|
||||
"lines",
|
||||
|
||||
knotKnot = Ct(knotHead * (V'line'-knotHead)^0 * wh),
|
||||
knotStitch = Ct(stitchHead * (V'line'-stitchHead)^0 * wh),
|
||||
knot = V'knotKnot' + V'knotStitch',
|
||||
stmt = glue + divert + knot + stitch + V'option' + optDiv + comm + V'include',
|
||||
text = C((1-nl-V'stmt'-hash)^1),
|
||||
textEmptyCapt = C((1-nl-V'stmt'-hash)^0),
|
||||
|
||||
stmt = glue + divert + V'knot' + optDiv + comm + V'include' + tag,
|
||||
text = C((1-nl-V'stmt')^1) *wh,
|
||||
textE = C((1-nl-V'stmt')^0) *wh,
|
||||
|
||||
optAnsWithDiv = V'textE' * optDiv * V'textE' * wh,
|
||||
optAnsWithoutDiv = V'textE' * Cc ''* Cc ''* wh, -- huh?
|
||||
optAnsWithDiv = V'textEmptyCapt' * sp * optDiv * V'text'^0 * wh,
|
||||
optAnsWithoutDiv = V'textEmptyCapt' * sp * Cc '' * Cc '' * wh, -- huh?
|
||||
optAns = V'optAnsWithDiv' + V'optAnsWithoutDiv',
|
||||
|
||||
-- TODO clean this
|
||||
opt = Cg(optStars,'indent') *
|
||||
Ct(Cc'option' * sp * V'optAns' * (V'line'-V'optLEIndent'-V'knot')^0 * wh), --TODO which can by toplevel only?
|
||||
optSameIndent = Ct(Cc'option' * optStarsSameIndent * sp * V'optAns' * (V'line'-V'optLEIndent'-V'knot')^0 * wh),
|
||||
optLEIndent = Ct(Cc'option' * optStarsLEIndent * sp * V'optAns' * (V'line'-V'optLEIndent'-V'knot')^0 * wh),
|
||||
option = Ct(Cc'option' * optStars * sp * V'optAns'),
|
||||
|
||||
opts = (V'opt'*V'optSameIndent'^0),
|
||||
|
||||
choice = Ct(Cc'choice' * V'opts')/function(t) t.indent=nil; return t end,
|
||||
|
||||
|
||||
include = Ct(P('INCLUDE')/'include' * wh * V'text' * wh),
|
||||
|
||||
para = Ct(Cc'para' * V'text'),
|
||||
para = tagAbove^0 * Ct(Cc'para' * V'text') * tagEnd^0 * wh + tagGlobal,
|
||||
|
||||
line = V'stmt' + V'choice' + V'para',
|
||||
line = V'stmt' + V'para',
|
||||
lines = Ct(V'line'^0)
|
||||
})
|
||||
|
||||
|
|
171
pink/runtime.lua
171
pink/runtime.lua
|
@ -1,104 +1,158 @@
|
|||
local debug = function(x) print( require('test/luaunit').prettystr(x) ) end
|
||||
|
||||
local is = function (what, node)
|
||||
return node ~= nil
|
||||
and (type(node) == "table" and node[1] == what)
|
||||
or (type(node) == "string" and node == what)
|
||||
end
|
||||
|
||||
local getPara = function (node)
|
||||
if is('para', node) then return node[2] end
|
||||
end
|
||||
|
||||
return function (tree)
|
||||
local s = {}
|
||||
|
||||
local pointer = nil
|
||||
local tab = {}
|
||||
|
||||
local knots = {}
|
||||
|
||||
-- TODO state should contain tab/pointer to be able to save / load
|
||||
s.state = {
|
||||
visitCount = {}
|
||||
local s = {
|
||||
globalTags = {},
|
||||
state = {
|
||||
visitCount = {},
|
||||
}
|
||||
}
|
||||
|
||||
local process = function ()
|
||||
for _, v in ipairs(tree) do
|
||||
if is('knot', v) then
|
||||
knots[v[2]] = v
|
||||
local pointer = 1
|
||||
local knots = {}
|
||||
local tags = {} -- maps (pointer to para) -> (list of tags)
|
||||
local tagsForContentAtPath = {}
|
||||
local currentChoicesPointers = {}
|
||||
|
||||
-- TODO state should contain tree/pointer to be able to save / load
|
||||
|
||||
local preProcess = function ()
|
||||
|
||||
local aboveTags = {}
|
||||
local lastPara = {}
|
||||
local lastKnotName
|
||||
|
||||
for p, n in ipairs(tree) do
|
||||
if is('knot', n) then -- FIXME stitches
|
||||
knots[n[2]] = p
|
||||
--print(v[2],k)
|
||||
end
|
||||
|
||||
if is('tag', n) then
|
||||
if n[2] == 'global' then
|
||||
table.insert(s.globalTags, n[3])
|
||||
end
|
||||
if n[2] == 'above' then
|
||||
if lastKnotName then table.insert(tagsForContentAtPath[lastKnotName], n[3]) end
|
||||
table.insert(aboveTags, n[3])
|
||||
end
|
||||
if n[2] == 'end' then
|
||||
table.insert(tags[lastPara], n[3])
|
||||
end
|
||||
end
|
||||
|
||||
if is('knot', n) or is('stitch', n) then
|
||||
lastKnotName = n[2]
|
||||
tagsForContentAtPath[lastKnotName] = {}
|
||||
end
|
||||
|
||||
if is('para', n) then
|
||||
tags[p] = aboveTags
|
||||
aboveTags = {}
|
||||
lastPara = p
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
local goToKnot = function(knotName)
|
||||
if knots[knotName] then
|
||||
s.state.visitCount[knotName] = (s.state.visitCount[knotName] or 0) + 1
|
||||
tab = knots[knotName]
|
||||
pointer = 3
|
||||
return tab[pointer]
|
||||
s.state.visitCount[knotName] = s.state.visitCountAtPathString(knotName) + 1
|
||||
pointer = knots[knotName] + 1 -- go to the line after the knot
|
||||
else
|
||||
print('unknown knot', knotName)
|
||||
end
|
||||
end
|
||||
|
||||
local update = function ()
|
||||
local next = tab[pointer]
|
||||
local isNext = function (what)
|
||||
return is(what, tree[pointer])
|
||||
end
|
||||
|
||||
if is('knot', next) then
|
||||
local getPara = function ()
|
||||
if isNext('para') then return tree[pointer][2] end
|
||||
end
|
||||
|
||||
local update
|
||||
update = function ()
|
||||
|
||||
if isNext('knot') then
|
||||
-- FIXME: we shouldn't continue to next knot automatically probably - how about stitches?
|
||||
--next = goToKnot(next[2])
|
||||
end
|
||||
|
||||
if is('divert', next) then next = goToKnot(next[2]) end
|
||||
if isNext('divert') then
|
||||
goToKnot(tree[pointer][2])
|
||||
update()
|
||||
return
|
||||
end
|
||||
|
||||
s.canContinue = is('para', next)
|
||||
if isNext('tag') then
|
||||
|
||||
pointer = pointer + 1
|
||||
update()
|
||||
return
|
||||
end
|
||||
|
||||
s.canContinue = isNext('para')
|
||||
|
||||
s.currentChoices = {}
|
||||
if is('choice', next) then
|
||||
for i=2, #next do
|
||||
--print(to_string(next[i]))
|
||||
currentChoicesPointers = {}
|
||||
|
||||
if isNext('option') then
|
||||
local choiceDepth = tree[pointer][2]
|
||||
-- find all choices on the same level in the same knot and in the same super-choice
|
||||
for p=pointer, #tree do
|
||||
local n = tree[p]
|
||||
--print('looking for options', choiceDepth, n[1], n[2])
|
||||
if is('knot', n) or is('stitch', n) or (is('option', n) and n[2] < choiceDepth) then
|
||||
--print('stop looking for options');
|
||||
break
|
||||
end
|
||||
|
||||
if is('option', n) and n[2] == choiceDepth then
|
||||
-- print('adding', p, n[3])
|
||||
table.insert(currentChoicesPointers, p)
|
||||
table.insert(s.currentChoices, {
|
||||
text = (next[i][2] or '') .. (next[i][3] or ''),
|
||||
choiceText = next[i][2] .. (next[i][4] or ''),
|
||||
text = (n[3] or '') .. (n[4] or ''),
|
||||
choiceText = n[3] .. (n[5] or ''),
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local step = function ()
|
||||
pointer = pointer + 1
|
||||
update()
|
||||
return tab[pointer]
|
||||
end
|
||||
|
||||
local stepTo = function (table, pos)
|
||||
tab = table
|
||||
pointer = pos
|
||||
update()
|
||||
return tab[pointer]
|
||||
local step = function ()
|
||||
end
|
||||
|
||||
s.canContinue = nil
|
||||
|
||||
s.continue = function()
|
||||
local res = getPara(tab[pointer])
|
||||
local next = step()
|
||||
|
||||
if is('glue', next) then
|
||||
step()
|
||||
local res = getPara()
|
||||
s.currentTags = tags[pointer] or {}
|
||||
|
||||
pointer = pointer + 1
|
||||
update()
|
||||
|
||||
if isNext('glue') then
|
||||
pointer = pointer + 1
|
||||
update()
|
||||
res = res .. s.continue()
|
||||
end
|
||||
|
||||
return res;
|
||||
end
|
||||
|
||||
s.currentChoices = nil
|
||||
s.currentChoices = {}
|
||||
|
||||
s.chooseChoiceIndex = function(index)
|
||||
s.currentChoices = {}
|
||||
local choice = tab[pointer]
|
||||
local option = choice[1 + index]
|
||||
stepTo(option, 5)
|
||||
pointer = currentChoicesPointers[index]+1
|
||||
update()
|
||||
end
|
||||
|
||||
s.choosePathString = function(knotName)
|
||||
|
@ -110,14 +164,21 @@ return function (tree)
|
|||
return s.state.visitCount[knotName] or 0
|
||||
end
|
||||
|
||||
s.tagsForContentAtPath = function(knotName)
|
||||
return tagsForContentAtPath[knotName] or {}
|
||||
end
|
||||
|
||||
s.currentTags = {}
|
||||
|
||||
s.variablesState = {}
|
||||
-- s.state.ToJson();s.state.LoadJson(savedJson);
|
||||
|
||||
stepTo(tree, 1)
|
||||
process()
|
||||
preProcess()
|
||||
--debug(tree)
|
||||
--debug(tags)
|
||||
|
||||
-- debug
|
||||
s._tree = tree
|
||||
|
||||
return s
|
||||
end
|
||||
|
|
|
@ -2,21 +2,10 @@ return {
|
|||
ink=[[
|
||||
Hello, world!
|
||||
Hello?
|
||||
//TODO: this is a test todo-item
|
||||
|
||||
"What do you make of this?" she asked.
|
||||
|
||||
// Something unprintable...
|
||||
|
||||
"I couldn't possibly comment," I replied.
|
||||
|
||||
/*
|
||||
... or an unlimited block of text
|
||||
*/
|
||||
we <> /* he
|
||||
asdf
|
||||
*/ hurr ied-> to_savile_row // comm
|
||||
|
||||
we <>
|
||||
hurr ied-> to_savile_row
|
||||
|
||||
=== to_savile_row ===
|
||||
|
||||
|
@ -33,14 +22,14 @@ expected= {
|
|||
{"para", '"What do you make of this?" she asked.'},
|
||||
{"para", "\"I couldn't possibly comment,\" I replied."},
|
||||
{"para", "we "},
|
||||
"glue",
|
||||
{"glue"},
|
||||
{"para", "hurr ied"},
|
||||
{"divert", "to_savile_row"},
|
||||
{
|
||||
"knot",
|
||||
"to_savile_row",
|
||||
{"knot", "to_savile_row"},
|
||||
{"para", "to Savile Row"},
|
||||
{"stitch", "st", {"para", "stiiii"}},
|
||||
{"stitch", "st2", {"para", "222stiiii "}, "END"}
|
||||
}
|
||||
{"stitch", "st"},
|
||||
{"para", "stiiii"},
|
||||
{"stitch", "st2"},
|
||||
{"para", "222stiiii "},
|
||||
{"end"}
|
||||
}}
|
||||
|
|
|
@ -27,46 +27,27 @@ He insisted that we hurried home to Savile Row
|
|||
<> as fast as we could.
|
||||
]],
|
||||
expected= {
|
||||
{
|
||||
"knot",
|
||||
"back_in_london",
|
||||
{"knot", "back_in_london"},
|
||||
{"para", "We arrived into London at 9.45pm exactly."},
|
||||
{
|
||||
"choice",
|
||||
{
|
||||
"option",
|
||||
'"There is not a moment to lose!"',
|
||||
"",
|
||||
" I declared.",
|
||||
{"divert", "hurry_outside"}
|
||||
},
|
||||
{
|
||||
"option",
|
||||
'"Monsieur, let us savour this moment!"',
|
||||
"",
|
||||
" I declared.",
|
||||
{"option", 1, '"There is not a moment to lose!"', "", " I declared."},
|
||||
{"divert", "hurry_outside"},
|
||||
{"option", 1, '"Monsieur, let us savour this moment!"', "", " I declared."},
|
||||
{
|
||||
"para",
|
||||
"My master clouted me firmly around the head and dragged me out of the door."
|
||||
},
|
||||
'glue',
|
||||
{"divert", "dragged_outside"}
|
||||
},
|
||||
{"option", "", "We hurried home", " ", {"divert", "hurry_outside"}}
|
||||
}
|
||||
},
|
||||
{
|
||||
"knot",
|
||||
"hurry_outside",
|
||||
{"glue"},
|
||||
{"divert", "dragged_outside"},
|
||||
{"option", 1, "", "We hurried home", " "},
|
||||
{"divert", "hurry_outside"},
|
||||
{"knot", "hurry_outside"},
|
||||
{"para", "We hurried home to Savile Row "},
|
||||
{"divert", "as_fast_as_we_could"}
|
||||
},
|
||||
{
|
||||
"knot",
|
||||
"dragged_outside",
|
||||
{"divert", "as_fast_as_we_could"},
|
||||
{"knot", "dragged_outside"},
|
||||
{"para", "He insisted that we hurried home to Savile Row"},
|
||||
{"divert", "as_fast_as_we_could"}
|
||||
},
|
||||
{"knot", "as_fast_as_we_could", "glue", {"para", "as fast as we could."}}
|
||||
{"divert", "as_fast_as_we_could"},
|
||||
{"knot", "as_fast_as_we_could"},
|
||||
{"glue"},
|
||||
{"para", "as fast as we could."}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,30 +12,16 @@ ink=[[
|
|||
== finale ==
|
||||
]],
|
||||
expected= {
|
||||
{
|
||||
"knot",
|
||||
"start",
|
||||
{
|
||||
"choice",
|
||||
{"option", "I dont know", "", ""},
|
||||
{
|
||||
"option",
|
||||
'"I am somewhat tired',
|
||||
'."',
|
||||
'," I repeated.',
|
||||
{"knot", "start"},
|
||||
{"option", 1, "I dont know", "", ""},
|
||||
{"option", 1, '"I am somewhat tired', '."', '," I repeated.'},
|
||||
{"para", '"Really," he responded.'},
|
||||
{"para", '"How deleterious."'}
|
||||
},
|
||||
{
|
||||
"option",
|
||||
'"Nothing, Monsieur!"',
|
||||
"",
|
||||
" I replied.",
|
||||
{"para", '"Very good, *then."'}
|
||||
},
|
||||
{"option", "I said no more", "", "", {"para", '"Ah,". "I see you"'}}
|
||||
}
|
||||
},
|
||||
{"para", '"How deleterious."'},
|
||||
{"option", 1, '"Nothing, Monsieur!"', "", " I replied."},
|
||||
{"para", '"Very good,'},
|
||||
{"option", 1, 'then."', "", ""},
|
||||
{"option", 1, "I said no more", "", ""},
|
||||
{"para", '"Ah,". "I see you"'},
|
||||
{"knot", "finale"}
|
||||
}
|
||||
}
|
||||
|
|
34
test/parser/comments.lua
Normal file
34
test/parser/comments.lua
Normal file
|
@ -0,0 +1,34 @@
|
|||
return {
|
||||
ink=[[
|
||||
Hello?
|
||||
TODO: this is a test todo-item
|
||||
|
||||
"What do you make of this?" she asked.
|
||||
|
||||
// Something unprintable...
|
||||
|
||||
"I couldn't possibly comment," I replied.
|
||||
|
||||
/*
|
||||
... or an unlimited block of text
|
||||
*/
|
||||
we <> /* he
|
||||
asdf
|
||||
*/ hurr ied-> to_savile_row // comm
|
||||
|
||||
|
||||
]],
|
||||
expected= {
|
||||
{"para", "Hello?"},
|
||||
{"todo", "this is a test todo-item"},
|
||||
{"para", '"What do you make of this?" she asked.'},
|
||||
{"comment", "Something unprintable..."},
|
||||
{"para", "\"I couldn't possibly comment,\" I replied."},
|
||||
{"comment", "... or an unlimited block of text\n"},
|
||||
{"para", "we "},
|
||||
{"glue"},
|
||||
{"comment", "he\nasdf\n"},
|
||||
{"para", "hurr ied"},
|
||||
{"divert", "to_savile_row"},
|
||||
{"comment", "comm"},
|
||||
}}
|
|
@ -9,22 +9,14 @@ ink=[[
|
|||
|
||||
]],
|
||||
expected={
|
||||
{
|
||||
"choice",
|
||||
{
|
||||
"option",
|
||||
'"Monsieur, let us savour this moment!"',
|
||||
"",
|
||||
" I declared.",
|
||||
{
|
||||
"para",
|
||||
"My master clouted me firmly around the head and dragged me out of the door. "
|
||||
},
|
||||
"glue",
|
||||
{"divert", "dragged_outside"}
|
||||
},
|
||||
{"option", "", "We hurried home", " ", {"divert", "hurry_outside"}}
|
||||
},
|
||||
{"knot", "as_fast_as_we_could", "glue", {"para", "as fast as we could."}} -- TODO should be space before 'as'
|
||||
{"option", 1, '"Monsieur, let us savour this moment!"', "", " I declared."},
|
||||
{"para", "My master clouted me firmly around the head and dragged me out of the door. " },
|
||||
{"glue"},
|
||||
{"divert", "dragged_outside"},
|
||||
{"option", 1, "", "We hurried home", " "},
|
||||
{"divert", "hurry_outside"},
|
||||
{"knot", "as_fast_as_we_could"},
|
||||
{"glue"},
|
||||
{"para", "as fast as we could."} -- TODO should be space before 'as'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,15 +16,18 @@ ink=[[
|
|||
|
||||
]],
|
||||
expected={
|
||||
{
|
||||
"knot",
|
||||
"the_orient_express",
|
||||
{"stitch", "in_first_class", {"para", "..."}},
|
||||
{"stitch", "in_third_class", {"para", "..."}},
|
||||
{"stitch", "in_the_guards_van", {"para", "..."}, {"para", "..."}},
|
||||
{"stitch", "missed_the_train", {"para", "..."}}
|
||||
},
|
||||
{ "knot", "the_orient_express"},
|
||||
{"stitch", "in_first_class"},
|
||||
{"para", "..."},
|
||||
{"stitch", "in_third_class"},
|
||||
{"para", "..."},
|
||||
{"stitch", "in_the_guards_van"},
|
||||
{"para", "..."},
|
||||
{"para", "..."},
|
||||
{"stitch", "missed_the_train"},
|
||||
{"para", "..."},
|
||||
{"knot", "the_orient_express"},
|
||||
{"knot", "the_orient_express", {"stitch", "stitch"}}
|
||||
{"knot", "the_orient_express"},
|
||||
{"stitch", "stitch"}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,18 +2,14 @@ return {
|
|||
ink=[[
|
||||
* "Murder!"
|
||||
** A
|
||||
* * A
|
||||
* "Suicide!"
|
||||
]], expected= {
|
||||
{
|
||||
"choice",
|
||||
{
|
||||
"option",
|
||||
'"Murder!"',
|
||||
"",
|
||||
"",
|
||||
{"choice", {"option", "A", "", ""}}
|
||||
},
|
||||
{"option", '"Suicide!"', "", ""}
|
||||
}
|
||||
|
||||
{"option", 1, '"Murder!"', "", ""},
|
||||
{"option", 2, "A", "", ""},
|
||||
{"option", 2, "A", "", ""},
|
||||
{"option", 1, '"Suicide!"', "", ""}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,22 +10,11 @@ ink=[[
|
|||
]],
|
||||
expected = {
|
||||
{"para", '"Well, Poirot? Murder or suicide?"'},
|
||||
{
|
||||
"choice",
|
||||
{
|
||||
"option",
|
||||
'"Murder"',
|
||||
"",
|
||||
"",
|
||||
{"option", 1, '"Murder"', "", ""},
|
||||
{"para", '"And who did it?"'},
|
||||
{
|
||||
"choice",
|
||||
{"option", '"Detective-Inspector Japp!"', "", ""},
|
||||
{"option", '"Captain Hastings!"', "", ""},
|
||||
{"option", '"Myself!"', "", ""}
|
||||
}
|
||||
},
|
||||
{"option", '"Suicide"', "", ""}
|
||||
}
|
||||
{"option", 2, '"Detective-Inspector Japp!"', "", ""},
|
||||
{"option", 2, '"Captain Hastings!"', "", ""},
|
||||
{"option", 2, '"Myself!"', "", ""},
|
||||
{"option", 1, '"Suicide"', "", ""}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,10 +9,21 @@ ink=[[
|
|||
# require: Train ticket
|
||||
|
||||
This is the line of content. # the third tag # really_monsieur.ogg
|
||||
|
||||
#tag
|
||||
aaa
|
||||
]],
|
||||
expected={
|
||||
{"tag", "global", "author: Joseph Humfrey"},
|
||||
{"tag", "global", "title: My Wonderful Ink Story"},
|
||||
{"knot", "content"},
|
||||
{"tag", "above", "location: Germany"},
|
||||
{"tag", "above", "overview: munich.ogg"},
|
||||
{"tag", "above", "require: Train ticket"},
|
||||
{"para", "This is the line of content. "},
|
||||
{"tag", "end", "the third tag "},
|
||||
{"tag", "end", "really_monsieur.ogg"},
|
||||
{"tag", "above", "tag"},
|
||||
{"para", "aaa"}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
=== back_in_london ===
|
||||
|
||||
We arrived into London at 9.45pm exactly.
|
||||
We arrived into London at 9.45pm
|
||||
exactly
|
||||
|
||||
* "There is not a moment to lose!"[] I declared.
|
||||
-> hurry_outside
|
||||
|
||||
* "Monsieur, let us savour this moment!"[] I declared.
|
||||
My master clouted me firmly around the head and dragged me out of the door.<>
|
||||
-> dragged_outside
|
||||
|
||||
My master clouted me firmly around the head
|
||||
** ugh?
|
||||
no thanks
|
||||
** hug
|
||||
huhu
|
||||
* [We hurried home] -> hurry_outside
|
||||
|
||||
|
||||
|
|
|
@ -3,15 +3,11 @@
|
|||
|
||||
->content
|
||||
=== content
|
||||
A line of normal game-text. # colour it blue
|
||||
|
||||
Passepartout: Really, Monsieur. # surly
|
||||
|
||||
Passepartout: Really, Monsieur. # surly # really_monsieur.ogg
|
||||
|
||||
# the first tag
|
||||
# the second tag
|
||||
This is the line of content. # the third tag
|
||||
#not this one
|
||||
that to this
|
||||
|
||||
=== Munich ==
|
||||
# location: Germany
|
||||
|
|
|
@ -15,13 +15,10 @@ function testText() doTestS(
|
|||
{{"para", "Hello world"}}
|
||||
) end
|
||||
|
||||
function testOpt1() doTestS(
|
||||
'* "I am somewhat tired[."]," I repeated.',
|
||||
{{'choice', {"option", '"I am somewhat tired', '."', '," I repeated.'}}}
|
||||
) end
|
||||
|
||||
|
||||
function testBasic() doTest('basic') end
|
||||
function testComments() doTest('comments') end
|
||||
function testChoices() doTest('choices') end
|
||||
function testNest() doTest('nested') end
|
||||
function testNest2() doTest('nested2') end
|
||||
|
@ -29,12 +26,34 @@ function testKnot() doTest('knot') end
|
|||
function testBranching() doTest('branching') end
|
||||
function testGlue() doTest('glue') end
|
||||
function testInclude() doTest('include') end
|
||||
function testInclude() doTest('tags') end
|
||||
function testTags() doTest('tags') end
|
||||
|
||||
|
||||
--- runtime ---
|
||||
|
||||
function testVisitCount()
|
||||
function testRBasic()
|
||||
local story = pink.getStory('test/runtime/hello.ink')
|
||||
luaunit.assertEquals(story.continue(), 'hello world')
|
||||
luaunit.assertFalse(story.canContinue)
|
||||
end
|
||||
|
||||
|
||||
function testRChoices()
|
||||
local story = pink.getStory('test/runtime/branching.ink')
|
||||
story.choosePathString('back_in_london');
|
||||
story.continue()
|
||||
luaunit.assertEquals(story.continue(), 'exactly')
|
||||
luaunit.assertFalse(story.canContinue)
|
||||
luaunit.assertEquals(#story.currentChoices, 3)
|
||||
story.chooseChoiceIndex(2)
|
||||
luaunit.assertEquals(story.continue(), 'My master clouted me firmly around the head')
|
||||
luaunit.assertEquals(#story.currentChoices, 2)
|
||||
story.chooseChoiceIndex(2)
|
||||
luaunit.assertEquals(story.continue(), 'huhu')
|
||||
end
|
||||
|
||||
|
||||
function testRVisitCount()
|
||||
local story = pink.getStory('test/runtime/branching.ink')
|
||||
story.choosePathString('hurry_outside');
|
||||
luaunit.assertEquals(story.state.visitCountAtPathString('as_fast_as_we_could'), 0)
|
||||
|
@ -46,22 +65,26 @@ function testVisitCount()
|
|||
luaunit.assertEquals(story.state.visitCountAtPathString('as_fast_as_we_could'), 2)
|
||||
end
|
||||
|
||||
function testIncludeR()
|
||||
function testRInclude()
|
||||
local story = pink.getStory('test/runtime/include.ink')
|
||||
luaunit.assertEquals(story.continue(), 'hello world')
|
||||
luaunit.assertEquals(story.continue(), 'hello again')
|
||||
luaunit.assertFalse(story.canContinue)
|
||||
end
|
||||
|
||||
function testTags()
|
||||
function testRTags()
|
||||
local story = pink.getStory('test/runtime/tags.ink')
|
||||
luaunit.assertEquals(story.continue(), '')
|
||||
luaunit.assertEquals(story.continue(), '')
|
||||
luaunit.assertEquals(story.globalTags, {""})
|
||||
luaunit.assertEquals(story.globalTags, {"author: Joseph Humfrey", "title: My Wonderful Ink Story"})
|
||||
story.choosePathString('content');
|
||||
luaunit.assertEquals(story.continue(), 'This is the line of content. ')
|
||||
luaunit.assertEquals(story.currentTags, {"the first tag", "the second tag", "the third tag"})
|
||||
story.continue()
|
||||
luaunit.assertEquals(story.currentTags, {"not this one"})
|
||||
luaunit.assertFalse(story.canContinue)
|
||||
luaunit.assertEquals(story.tagsForContentAtPath('Munich'), {"location: Germany", "overview: munich.ogg", "require: Train ticket"})
|
||||
end
|
||||
|
||||
function testInvisibleDiverts()
|
||||
function testRInvisibleDiverts()
|
||||
local story = pink.getStory('test/runtime/branching.ink')
|
||||
story.choosePathString('hurry_outside')
|
||||
luaunit.assertEquals(story.continue(), "We hurried home to Savile Row as fast as we could.")
|
||||
|
|
Loading…
Reference in a new issue