-- | Parse a value, complete with brackets.
-- 
-- This is a bit tricky as there are escape sequences to take into account.
--
-- We'll use a simple folder with one bit of state: whether the last
val :: Parser Text
val = char '[' *> worker [] False
  where
    -- 'bs' = previous character was a backslash
    worker acc bs = do
        c <- anyChar
        case c of
            ']'  | not bs    -> return . T.pack . reverse $ acc
            '\\' | not bs    -> worker acc True
            '\n' | bs        -> worker acc False -- remove soft newline
            _    | isSpace c -> worker (' ' : acc) False
            _                -> worker (c : acc) False

-- | Create an 'SgfTree' from a list of nodes and subtrees.
--
-- This does the expansion of a ";n1;n2;n3(;n4)(;n5)" node list to
-- a tree structure with depth 4 where the n3 tree node has two children
-- and the n1 and n2 node each have one child.
val :: Parser Text
val = char '[' *> worker [] False
  where
    -- 'bs' = previous character was a backslash
    worker acc bs = do
        c <- anyChar
        case c of
            ']'  | not bs    -> return . T.pack . reverse $ acc
            '\\' | not bs    -> worker acc True
            '\n' | bs        -> worker acc False -- remove soft newline
            _    | isSpace c -> worker (' ' : acc) False
            _                -> worker (c : acc) False

-- | Create an 'SgfTree' from a list of nodes and subtrees.
--
-- This does the expansion of a ";n1;n2;n3(;n4)(;n5)" node list to
-- a tree structure with depth 4 where the n3 tree node has two children
-- and the n1 and n2 node each have one child.
val = char '[' *> worker [] False
  where
    -- 'bs' = previous character was a backslash
    worker acc bs = do
        c <- anyChar
        case c of
            ']'  | not bs    -> return . T.pack . reverse $ acc
            '\\' | not bs    -> worker acc True
            '\n' | bs        -> worker acc False -- remove soft newline
            _    | isSpace c -> worker (' ' : acc) False
            _                -> worker (c : acc) False

-- | Create an 'SgfTree' from a list of nodes and subtrees.
--
-- This does the expansion of a ";n1;n2;n3(;n4)(;n5)" node list to
-- a tree structure with depth 4 where the n3 tree node has two children
-- and the n1 and n2 node each have one child.