

 Display an outline as a nested table.


 Parse the outline to a tree,

 count the leaves descending from each node,

 and write out a table with 'colspan' values


 measuring the indent of each line,

 translating the indentation to a nested structure,

 and padding the tree to even depth.

 defining the width of a leaf as 1,

 and the width of a parent node as a sum.

 either as a wiki table,

 or as HTML.










 (The sum of the widths of its children)





The graphic representation of outlines is a staple of mind-mapping and the planning of papers, reports, and speeches.

Task

Given a outline with at least 3 levels of indentation, for example:

Display an outline as a nested table.
    Parse the outline to a tree,
        measuring the indent of each line,
        translating the indentation to a nested structure,
        and padding the tree to even depth.
    count the leaves descending from each node,
        defining the width of a leaf as 1,
        and the width of a parent node as a sum.
            (The sum of the widths of its children)
    and write out a table with 'colspan' values
        either as a wiki table,
        or as HTML.
write a program in your language which translates your outline into a nested table, with WikiTable or HTML colspan values attached (where needed) to parent nodes in the nested table.

The WikiTable at the top of this page was generated from the indented outline shown above, producing the following markup string:

{| class="wikitable" style="text-align: center;"
|-
| style="background: #ffffe6; " colspan=7 | Display an outline as a nested table.
|-
| style="background: #ffebd2; " colspan=3 | Parse the outline to a tree,
| style="background: #f0fff0; " colspan=2 | count the leaves descending from each node,
| style="background: #e6ffff; " colspan=2 | and write out a table with 'colspan' values
|-
| style="background: #ffebd2; " | measuring the indent of each line,
| style="background: #ffebd2; " | translating the indentation to a nested structure,
| style="background: #ffebd2; " | and padding the tree to even depth.
| style="background: #f0fff0; " | defining the width of a leaf as 1,
| style="background: #f0fff0; " | and the width of a parent node as a sum.
| style="background: #e6ffff; " | either as a wiki table,
| style="background: #e6ffff; " | or as HTML.
|-
|  | 
|  | 
|  | 
|  | 
| style="background: #f0fff0; " | (The sum of the widths of its children)
|  | 
|  | 
|}
Extra credit

Use background color to distinguish the main stages of your outline, so that the subtree of each node at level two is consistently colored, and the edges between adjacent subtrees are immediately revealed.



Output

Display your nested table on this page.



with javascript_semantics
constant html = false,
         outlines = {"""
Display an outline as a nested table.
    Parse the outline to a tree,
        measuring the indent of each line,
        translating the indentation to a nested structure,
        and padding the tree to even depth.
    count the leaves descending from each node,
        defining the width of a leaf as 1,
        and the width of a parent node as a sum.
            (The sum of the widths of its children)
    and write out a table with 'colspan' values
        either as a wiki table,
        or as HTML.""",			"""
Display an outline as a nested table.
    Parse the outline to a tree,
        measuring the indent of each line,
        translating the indentation to a nested structure,
        and padding the tree to even depth. 
    count the leaves descending from each node,
        defining the width of a leaf as 1,
        and the width of a parent node as a sum.
            (The sum of the widths of its children)
            Propagating the sums upward as necessary. 
    and write out a table with 'colspan' values
        either as a wiki table,
        or as HTML.
    Optionally add color to the nodes."""}
 
constant yellow = "#ffffe6;",
         orange = "#ffebd2;",
         green  = "#f0fff0;",
         blue   = "#e6ffff;",
         pink   = "#ffeeff;",
         colours = {{yellow, orange, green, blue, pink},
                    {blue, yellow, orange, green, pink}}
 
function calc_spans(sequence lines, integer ldx)
    sequence children = lines[ldx][$]
    if length(children)!=0 then
        integer span = 0
        for i=1 to length(children) do
            integer child = children[i]
            lines = calc_spans(lines,child)
            span += lines[child][4]
        end for
        lines[ldx][4] = span
--  else -- (span already 1)
    end if
    return lines
end function
 
procedure markup(string outline, sequence colours)
    sequence lines = split(outline,"\n",no_empty:=true),
             pi = {},   -- indents (to locate parents)
             pdx = {},  -- indexes for ""
             children = {}
    string text
    integer maxdepth = 0,
            parent, depth, span
    for i=1 to length(lines) do
        string line = trim_tail(lines[i])
        text = trim_head(line)
        integer indent = length(line)-length(text)
        -- remove any completed parents
        while length(pi) and indent<=pi[$] do
            pi = pi[1..$-1]
            pdx = pdx[1..$-1]
        end while
        parent = 0
        if length(pi) then
            parent = pdx[$]
            lines[parent][$] = deep_copy(lines[parent][$]) & i -- (update children)
        end if
        pi &= indent
        pdx &= i
        depth = length(pi)
        span = 1 -- (default/assume no children[=={}])
        lines[i] = {i,depth,indent,span,parent,text,children}
        maxdepth = max(maxdepth,depth)
    end for
    lines = calc_spans(lines,1)
 
    string res = iff(html?"<table class=\"wikitable\" style=\"text-align: center;\">\n"
                         :"{| class=\"wikitable\" style=\"text-align: center;\"\n")
    for d=1 to maxdepth do
        res &= iff(html?"<tr>\n"
                       :"|-\n")
        integer cdx = 1, lii, lident
        for i=1 to length(lines) do
            {lii,depth,lident,span,parent,text,children} = lines[i]
            if depth=2 then cdx += 1 end if
            string style = sprintf(`style="background: %s"`,{colours[cdx]})
            if depth=d then
                if span!=1 then style &= sprintf(` colspan="%d"`,span) end if
                res &= sprintf(iff(html?"<td %s>%s</td>\n"
                                       :"| %s | %s\n"),{style,text})
            elsif depth<d and children={} then
--              res &= iff(html?"<td></td>\n"
--                             :"|	|\n")
                res &= sprintf(iff(html?"<td %s></td>\n"
                                       :"| %s |\n"),{style})
            end if
        end for
        if html then
            res &= "</tr>\n"
        end if
    end for
    res &= iff(html?"</table>\n"
                   :"|}\n")
    puts(1,res)
end procedure
for i=1 to length(outlines) do
    markup(outlines[i],colours[i])
end for
