Display an outline as a nested table: Difference between revisions

New post.
m (→‎Python: Functional: On slight simplification by generalisation)
(New post.)
(9 intermediate revisions by 5 users not shown)
Line 82:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">outline2table(db, Delim:= "`t"){
oNum:=[], oMID:=[], oNod := [], oKid := [], oPnt := [], oMbr := [], oLvl := []
oCrl := ["#ffffe6;", "#ffebd2;", "#f0fff0;", "#e6ffff;", "#ffeeff;"]
Line 211:
return [html, wTable]
}
</syntaxhighlight>
</lang>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">db =
(
Display an outline as a nested table.
Line 233:
Gui, Show
MsgBox % "HTML:`n" result.1 "`n`nWikitable:`n" result.2
return</langsyntaxhighlight>
{{out}}
HTML:
Line 292:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 445:
toNest(iNodes2, 0, 0, &n2)
fmt.Println(toMarkup(n2, cols2, 4))
}</langsyntaxhighlight>
 
{{out}}
Line 503:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">{-# LANGUAGE TupleSections #-}
 
module OutlineTree where
Line 531:
. paintedTree colorSwatch
. widthLabelledTree
. (paddedTree []"" =<<*> treeDepth)
 
--------------------------- TEST -------------------------
Line 576:
---------------- TREE PADDED TO EVEN DEPTH ---------------
 
paddedTree :: a -> IntTree a -> Tree aInt -> Tree a
paddedTree padValue = go
where
go n tree n
| 1 >= n = tree
| otherwise =
Node
(rootLabel tree)
( (`go` (pred n)
<$> bool nest [Node padValue []] (null nest)
)
Line 644:
<> "style=\"text-align: center;\"\n|-\n"
<> intercalate "|-\n" (wikiRow <$> rows)
<> "|}"</langsyntaxhighlight>
{{Out}}
{| class="wikitable" style="text-align: center;"
Line 669:
| |
| |
|}
 
=={{header|J}}==
 
Implementation:
 
<syntaxhighlight lang="j">depth=: (i.~ ~.)@(0 i."1~' '=];._2)
tree=: (i: 0>.<:@{:)\
width=: {{NB. y is tree
c=. *i.#y NB. children
NB. sum of children, inductively
y (+//. c&*)`(~.@[)`]}^:_ c
}}
 
NB. avoid dark colors
NB. avoid dark colors
NB. avoid dark colors
pastel=: {{256#.192+?y$,:3#64}}
 
task=: {{
depths=: depth y NB. outline structure
t=: tree depths NB. outline as tree
pad=: (i.#depths) -. t,I.(=>./)depths
tr=: t,pad NB. outline as constant depth tree
dr=: depths,1+pad{depths
lines=:(#dr){.<@dlb;._2 y
widths=. width tr NB. column widths
top=. I.2>dr
color=.<"1 hfd 8421504 (I.tr e.pad)} (top top} tr)&{^:_ (<:2^24),pastel<:#dr
r=.'{| class="wikitable" style="text-align: center;"',LF
for_d.~.dr do. NB. descend through the depths
k=.I.d=dr NB. all lines at this depth
p=. |:({:,~{&tr)^:d ,:k
j=. k/:p NB. order padding to fit parents
r=. r,'|-',LF
r=. r,;'| style="background: #',L:0 (j{color),L:0'" colspan=',L:0(j{widths),&":each' | ',L:0 (j{lines),L:0 LF
end.
r=.r,'|}',LF
}}</syntaxhighlight>
 
Given the task example outline:
 
<syntaxhighlight lang="j">outline=:{{)n
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.
}}</syntaxhighlight>
 
Generated output from <tt>task outline</tt> was:
 
{| class="wikitable" style="text-align: center;"
|-
| style="background: #ffffff" colspan=7 | Display an outline as a nested table.
|-
| style="background: #e7d7cd" colspan=3 | Parse the outline to a tree,
| style="background: #e9c5d1" colspan=2 | count the leaves descending from each node,
| style="background: #d8e9f4" colspan=2 | and write out a table with 'colspan' values
|-
| style="background: #e7d7cd" colspan=1 | measuring the indent of each line,
| style="background: #e7d7cd" colspan=1 | translating the indentation to a nested structure,
| style="background: #e7d7cd" colspan=1 | and padding the tree to even depth.
| style="background: #e9c5d1" colspan=1 | defining the width of a leaf as 1,
| style="background: #e9c5d1" colspan=1 | and the width of a parent node as a sum.
| style="background: #d8e9f4" colspan=1 | either as a wiki table,
| style="background: #d8e9f4" colspan=1 | or as HTML.
|-
| style="background: #808080" colspan=1 |
| style="background: #808080" colspan=1 |
| style="background: #808080" colspan=1 |
| style="background: #808080" colspan=1 |
| style="background: #e9c5d1" colspan=1 | (The sum of the widths of its children)
| style="background: #808080" colspan=1 |
| style="background: #808080" colspan=1 |
|}
 
=={{header|Java}}==
<syntaxhighlight lang="java">
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Deque;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
public final class DisplayAnOutlineAsANestedTable {
 
public static void main(String[] args) {
String outline = """
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.
""";
Node tree = parse(outline);
colourTree(tree);
String htmlCode = htmlTable(tree);
System.out.println(htmlCode);
String wikiCode = wikiTable(tree);
System.out.println(wikiCode);
}
// Return the HTML code for the display of the given Node as a table.
private static String htmlTable(Node tree) {
final int tableColumnCount = tree.colspan();
 
int rowColumn = 0;
StringBuilder builder = new StringBuilder("<table style='text-align: center;' >\n");
 
// Breadth first traversal of 'tree'.
Deque<Node> queue = new ArrayDeque<Node>();
Set<Node> explored = new HashSet<Node>();
queue.offer(tree);
while ( ! queue.isEmpty() ) {
Node currentNode = queue.poll();
if ( explored.contains(currentNode) ) {
continue;
}
if ( rowColumn == 0 ) {
builder.append(" <tr>\n");
}
 
builder.append(htmlTableData(currentNode));
rowColumn += currentNode.colspan();
 
if ( rowColumn == tableColumnCount ) {
builder.append(" </tr>\n");
rowColumn = 0;
}
for ( Node child : currentNode.children ) {
queue.offer(child);
}
explored.add(currentNode);
}
 
builder.append("</table>\n");
return builder.toString();
}
// Return the code for the display of the given Node as a table in Wikipedia.
private static String wikiTable(Node tree) {
final int tableColumnCount = tree.colspan();
int rowColumn = 0;
 
StringBuilder builder = new StringBuilder();
builder.append("{| class=\"" + "wikitable" + "\"" + " style=\"" + "text-align: center;" + "\"" + "\n");
 
// Breadth first traversal of 'tree'.
Deque<Node> queue = new ArrayDeque<Node>();
Set<Node> explored = new HashSet<Node>();
queue.offer(tree);
while ( ! queue.isEmpty() ) {
Node currentNode = queue.poll();
if ( explored.contains(currentNode) ) {
continue;
}
if ( rowColumn == 0 ) {
builder.append("|-\n");
}
builder.append(wikiTableData(currentNode));
rowColumn += currentNode.colspan();
if ( rowColumn == tableColumnCount ) {
rowColumn = 0;
}
for ( Node child : currentNode.children ) {
queue.offer(child);
}
explored.add(currentNode);
}
 
builder.append("|}\n");
return builder.toString();
}
// Return an HTML table data element for the given Node.
private static String htmlTableData(Node node) {
String indent = " ";
String colspan = " colspan=\"" + node.colspan() + "\"";
String style = "style=\"" + "background-color: " + node.colour + "\"";
String attributes = colspan + " " + style;
return indent + "<td" + attributes + " >" + node.text + "</td>\n";
}
// Return a Wikipedia table data element for the given Node.
private static String wikiTableData(Node node) {
if ( node.text.isBlank() ) {
return "| |\n";
}
 
String style = "style=\"" + "background: " + node.colour + " \"";
String colspan = " colspan=" + node.colspan();
String attributes = style + colspan;
return "| " + attributes + " | " + node.text + "\n";
}
// Return the given outline as a tree of Node.
private static Node parse(String outline) {
List<Token> tokens = tokenise(outline);
Node temporaryTree = new Node("", -1, null);
parse(tokens, 0, temporaryTree);
Node tree = temporaryTree.children.getFirst();
padTree(tree, tree.height());
return tree;
}
// Recursively build a tree of Node.
private static void parse(List<Token> tokens, int index, Node node) {
if ( index == tokens.size() ) {
return;
}
 
Token token = tokens.get(index);
if ( token.indent == node.indent ) { // A sibling of node
Node current = new Node(token.text, token.indent, node.parent);
node.parent.children.addLast(current);
parse(tokens, index + 1, current);
} else if ( token.indent > node.indent ) { // A child of node
Node current = new Node(token.text, token.indent, node);
node.children.addLast(current);
parse(tokens, index + 1, current);
} else if ( token.indent < node.indent ) { // Try the node's parent until a sibling is found
parse(tokens, index, node.parent);
}
}
// Pad the tree with blank nodes so that all branches have the same depth.
private static void padTree(Node node, int height) {
if ( node.isLeaf() && node.depth() < height ) {
Node padNode = new Node("", node.indent + 1, node);
node.children.addLast(padNode);
}
 
for ( Node child : node.children ) {
padTree(child, height);
}
}
private static void colourTree(Node node) {
if ( node.text.isBlank() ) {
node.colour = Colour.blank();
} else if ( node.depth() <= 1 ) {
node.colour = Colour.next();
} else {
node.colour = node.parent.colour;
}
 
for ( Node child : node.children ) {
colourTree(child);
}
}
private static List<Token> tokenise(String outline) {
List<Token> tokens = new ArrayList<Token>();
for ( String line : outline.split("\n") ) {
String lineTrimmed = line.trim();
final int indent = line.length() - lineTrimmed.length();
tokens.addLast( new Token(lineTrimmed, indent) );
}
 
return tokens;
}
private static final class Node {
public Node (String aText, int aIndent, Node aParent) {
text = aText;
indent = aIndent;
parent = aParent;
children = new ArrayList<Node>();
}
public int depth() {
return ( parent != null ) ? parent.depth() + 1 : -1;
}
 
public int height() {
if ( isLeaf() ) {
return 0;
}
return children.stream().map( child -> child.height() ).max(Comparator.naturalOrder()).get() + 1;
}
 
public int colspan() {
if ( isLeaf() ) {
return 1;
}
 
return children.stream().map( child -> child.colspan() ).mapToInt(Integer::intValue).sum();
}
 
public boolean isLeaf() {
return children.isEmpty();
}
private String text;
private int indent;
private Node parent;
private List<Node> children;
private String colour;
}
private static final class Colour {
public static String next() {
index = ( index + 1 ) % colours.size();
return colours.get(index);
}
public static String blank() {
return "#cccccc;";
}
private static int index = -1;
private static final List<String> colours = List.of( "#ffff66;", "#ffcc66;", "#ccffcc;", "#ccccff;",
"#ffcccc;", "#00cccc;", "#cc9966;", "#ffccff;" );
}
 
private record Token(String text, int indent) { }
 
}
</syntaxhighlight>
{{ out }}
HTML Table
 
<table style='text-align: center;' >
<tr>
<td colspan="9" style="background-color: #ffff66;" >Display an outline as a nested table.</td>
</tr>
<tr>
<td colspan="3" style="background-color: #ffcc66;" >Parse the outline to a tree,</td>
<td colspan="3" style="background-color: #ccffcc;" >count the leaves descending from each node,</td>
<td colspan="2" style="background-color: #ccccff;" >and write out a table with 'colspan' values</td>
<td colspan="1" style="background-color: #ffcccc;" >Optionally add color to the nodes.</td>
</tr>
<tr>
<td colspan="1" style="background-color: #ffcc66;" >measuring the indent of each line,</td>
<td colspan="1" style="background-color: #ffcc66;" >translating the indentation to a nested structure,</td>
<td colspan="1" style="background-color: #ffcc66;" >and padding the tree to even depth.</td>
<td colspan="1" style="background-color: #ccffcc;" >defining the width of a leaf as 1,</td>
<td colspan="2" style="background-color: #ccffcc;" >and the width of a parent node as a sum.</td>
<td colspan="1" style="background-color: #ccccff;" >either as a wiki table,</td>
<td colspan="1" style="background-color: #ccccff;" >or as HTML.</td>
<td colspan="1" style="background-color: #cccccc;" ></td>
</tr>
<tr>
<td colspan="1" style="background-color: #cccccc;" ></td>
<td colspan="1" style="background-color: #cccccc;" ></td>
<td colspan="1" style="background-color: #cccccc;" ></td>
<td colspan="1" style="background-color: #cccccc;" ></td>
<td colspan="1" style="background-color: #ccffcc;" >(The sum of the widths of its children)</td>
<td colspan="1" style="background-color: #ccffcc;" >Propagating the sums upward as necessary.</td>
<td colspan="1" style="background-color: #cccccc;" ></td>
<td colspan="1" style="background-color: #cccccc;" ></td>
<td colspan="1" style="background-color: #cccccc;" ></td>
</tr>
</table>
 
 
Wiki Table
 
{| class="wikitable" style="text-align: center;"
|-
| style="background: #ffff66; " colspan=9 | Display an outline as a nested table.
|-
| style="background: #ffcc66; " colspan=3 | Parse the outline to a tree,
| style="background: #ccffcc; " colspan=3 | count the leaves descending from each node,
| style="background: #ccccff; " colspan=2 | and write out a table with 'colspan' values
| style="background: #ffcccc; " colspan=1 | Optionally add color to the nodes.
|-
| style="background: #ffcc66; " colspan=1 | measuring the indent of each line,
| style="background: #ffcc66; " colspan=1 | translating the indentation to a nested structure,
| style="background: #ffcc66; " colspan=1 | and padding the tree to even depth.
| style="background: #ccffcc; " colspan=1 | defining the width of a leaf as 1,
| style="background: #ccffcc; " colspan=2 | and the width of a parent node as a sum.
| style="background: #ccccff; " colspan=1 | either as a wiki table,
| style="background: #ccccff; " colspan=1 | or as HTML.
| |
|-
| |
| |
| |
| |
| style="background: #ccffcc; " colspan=1 | (The sum of the widths of its children)
| style="background: #ccffcc; " colspan=1 | Propagating the sums upward as necessary.
| |
| |
| |
|}
 
=={{header|JavaScript}}==
<langsyntaxhighlight lang="javascript">(() => {
"use strict";
 
Line 1,217 ⟶ 1,647:
// MAIN ---
return main();
})();</langsyntaxhighlight>
{{Out}}
{| class="wikitable" style="text-align:center;"
Line 1,245 ⟶ 1,675:
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">using DataFrames
 
text = """
Line 1,322 ⟶ 1,752:
textplus = text * " Optionally add color to the nodes."
htmlfromdataframe(processtable(textplus))
</langsyntaxhighlight>{{out}}
<h4>A Rosetta Code Nested Table</h4><table style="width:100%" class="wikitable" >
<tr>
Line 1,397 ⟶ 1,827:
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">s = "Display an outline as a nested table.
Parse the outline to a tree,
measuring the indent of each line,
Line 1,516 ⟶ 1,946:
]
AppendTo[str, "</table>"];
StringRiffle[str, "\n"]</langsyntaxhighlight>
{{out}}
<pre><table style='text-align: center;'>
Line 1,549 ⟶ 1,979:
=={{header|Nim}}==
 
<langsyntaxhighlight Nimlang="nim">import strutils
 
const Outline = """Display an outline as a nested table.
Line 1,718 ⟶ 2,148:
nodelists.writeWikiTable()
echo "HTML:"
nodelists.writeHtml()</langsyntaxhighlight>
 
{{out}}
Line 1,777 ⟶ 2,207:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict;
Line 1,831 ⟶ 2,261:
and write out a table with 'colspan' values
either as a wiki table,
or as HTML.</langsyntaxhighlight>
{{out}}
<table border=1 cellspacing=0>
Line 1,864 ⟶ 2,294:
=={{header|Phix}}==
Can output in either html or wikitable markup
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant html = false,
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
outlines = {"""
<span style="color: #008080;">constant</span> <span style="color: #000000;">html</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span><span style="color: #0000FF;">,</span>
Display an outline as a nested table.
<span style="color: #000000;">outlines</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"""
Parse the outline to a tree,
Display an outline as a nested table.
measuring the indent of each line,
translatingParse the indentationoutline to a nested structuretree,
and paddingmeasuring the treeindent toof eveneach depth.line,
translating the indentation to a nested structure,
count the leaves descending from each node,
defining theand widthpadding ofthe atree leafto aseven 1,depth.
andcount the widthleaves ofdescending afrom parenteach node as a sum.,
defining the (The sumwidth of thea widths ofleaf itsas children)1,
and writethe outwidth of a tableparent withnode 'colspan'as a valuessum.
(The sum of the widths of its children)
either as a wiki table,
and write out ora astable HTML.""", """with 'colspan' values
Display an outline either as a nestedwiki table.,
or as HTML."""</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"""
Parse the outline to a tree,
Display an outline as a nested table.
measuring the indent of each line,
translatingParse the indentationoutline to a nested structuretree,
and paddingmeasuring the treeindent toof even depth.each line,
translating the indentation to a nested structure,
count the leaves descending from each node,
defining theand widthpadding the oftree ato leafeven asdepth. 1,
andcount the widthleaves ofdescending afrom parenteach node as a sum.,
defining the (The sumwidth of thea widths ofleaf itsas children)1,
and the width Propagatingof thea sumsparent upwardnode as necessary.a sum.
(The sum of the widths of its children)
and write out a table with 'colspan' values
Propagating the sums upward as necessary.
either as a wiki table,
and write out ora astable HTML.with 'colspan' values
either as a wiki table,
Optionally add color to the nodes."""}
or as HTML.
 
Optionally add color to the nodes."""</span><span style="color: #0000FF;">}</span>
constant yellow = "#ffffe6;",
orange = "#ffebd2;",
<span style="color: #008080;">constant</span> <span style="color: #000000;">yellow</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"#ffffe6;"</span><span style="color: #0000FF;">,</span>
green = "#f0fff0;",
<span style="color: #000000;">orange</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"#ffebd2;"</span><span style="color: #0000FF;">,</span>
blue = "#e6ffff;",
<span style="color: #000000;">green</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"#f0fff0;"</span><span style="color: #0000FF;">,</span>
pink = "#ffeeff;",
<span style="color: #000000;">blue</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"#e6ffff;"</span><span style="color: #0000FF;">,</span>
colours = {{yellow, orange, green, blue, pink},
<span style="color: #000000;">pink</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"#ffeeff;"</span><span style="color: #0000FF;">,</span>
{blue, yellow, orange, green, pink}}
<span style="color: #000000;">colours</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">yellow</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">orange</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">green</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">blue</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pink</span><span style="color: #0000FF;">},</span>
 
<span style="color: #0000FF;">{</span><span style="color: #000000;">blue</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">yellow</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">orange</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">green</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pink</span><span style="color: #0000FF;">}}</span>
function calc_spans(sequence lines, integer ldx)
sequence children = lines[ldx][$]
<span style="color: #008080;">function</span> <span style="color: #000000;">calc_spans</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">ldx</span><span style="color: #0000FF;">)</span>
if length(children)!=0 then
<span style="color: #004080;">sequence</span> <span style="color: #000000;">children</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ldx</span><span style="color: #0000FF;">][$]</span>
integer span = 0
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">children</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
for i=1 to length(children) do
<span style="color: #004080;">integer</span> <span style="color: #000000;">span</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
integer child = children[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">children</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
lines = calc_spans(lines,child)
<span style="color: #004080;">integer</span> <span style="color: #000000;">child</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">children</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
span += lines[child][4]
<span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">calc_spans</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">child</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #000000;">span</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">child</span><span style="color: #0000FF;">][</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]</span>
lines[ldx][4] = span
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
-- else -- (span already 1)
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ldx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">span</span>
end if
<span style="color: #000080;font-style:italic;">-- else -- (span already 1)</span>
return lines
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">lines</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
procedure markup(string outline, sequence colours)
sequence lines = split(outline,"\n",no_empty:=true),
<span style="color: #008080;">procedure</span> <span style="color: #000000;">markup</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">outline</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">colours</span><span style="color: #0000FF;">)</span>
pi = {}, -- indents (to locate parents)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">outline</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">no_empty</span><span style="color: #0000FF;">:=</span><span style="color: #004600;">true</span><span style="color: #0000FF;">),</span>
pdx = {}, -- indexes for ""
<span style="color: #000000;">pi</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000080;font-style:italic;">-- indents (to locate parents)</span>
children = {}
<span style="color: #000000;">pdx</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000080;font-style:italic;">-- indexes for ""</span>
string text
<span style="color: #000000;">children</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
integer maxdepth = 0,
<span style="color: #004080;">string</span> <span style="color: #000000;">text</span>
parent, depth, span
<span style="color: #004080;">integer</span> <span style="color: #000000;">maxdepth</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
for i=1 to length(lines) do
<span style="color: #000000;">parent</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">depth</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">span</span>
string line = trim_tail(lines[i])
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
text = trim_head(line)
<span style="color: #004080;">string</span> <span style="color: #000000;">line</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim_tail</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
integer indent = length(line)-length(text)
<span style="color: #000000;">text</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim_head</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)</span>
-- remove any completed parents
<span style="color: #004080;">integer</span> <span style="color: #000000;">indent</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">text</span><span style="color: #0000FF;">)</span>
while length(pi) and indent<=pi[$] do
<span style="color: #000080;font-style:italic;">-- remove any completed parents</span>
pi = pi[1..$-1]
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">indent</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">[$]</span> <span style="color: #008080;">do</span>
pdx = pdx[1..$-1]
<span style="color: #000000;">pi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pi</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
end while
<span style="color: #000000;">pdx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pdx</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
parent = 0
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
if length(pi) then
<span style="color: #000000;">parent</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
parent = pdx[$]
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
lines[parent][$] &= i -- (update children)
<span style="color: #000000;">parent</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pdx</span><span style="color: #0000FF;">[$]</span>
end if
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">parent</span><span style="color: #0000FF;">][$]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">parent</span><span style="color: #0000FF;">][$])</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">i</span> <span style="color: #000080;font-style:italic;">-- (update children)</span>
pi &= indent
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
pdx &= i
<span style="color: #000000;">pi</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">indent</span>
depth = length(pi)
<span style="color: #000000;">pdx</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">i</span>
span = 1 -- (default/assume no children[=={}])
<span style="color: #000000;">depth</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">)</span>
lines[i] = {i,depth,indent,span,parent,text,children}
<span style="color: #000000;">span</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> <span style="color: #000080;font-style:italic;">-- (default/assume no children[=={}])</span>
maxdepth = max(maxdepth,depth)
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">depth</span><span style="color: #0000FF;">,</span><span style="color: #000000;">indent</span><span style="color: #0000FF;">,</span><span style="color: #000000;">span</span><span style="color: #0000FF;">,</span><span style="color: #000000;">parent</span><span style="color: #0000FF;">,</span><span style="color: #000000;">text</span><span style="color: #0000FF;">,</span><span style="color: #000000;">children</span><span style="color: #0000FF;">}</span>
end for
<span style="color: #000000;">maxdepth</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">maxdepth</span><span style="color: #0000FF;">,</span><span style="color: #000000;">depth</span><span style="color: #0000FF;">)</span>
lines = calc_spans(lines,1)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">calc_spans</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
string res = iff(html?"<table class=\"wikitable\" style=\"text-align: center;\">\n"
:"{| class=\"wikitable\" style=\"text-align: center;\"\n")
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">html</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"&lt;table class=\"wikitable\" style=\"text-align: center;\"&gt;\n"</span>
for d=1 to maxdepth do
<span style="color: #0000FF;">:</span><span style="color: #008000;">"{| class=\"wikitable\" style=\"text-align: center;\"\n"</span><span style="color: #0000FF;">)</span>
res &= iff(html?"<tr>\n"
<span style="color: #008080;">for</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">maxdepth</span> <span style="color: #008080;">do</span>
:"|-\n")
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">html</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"&lt;tr&gt;\n"</span>
integer cdx = 1
<span style="color: #0000FF;">:</span><span style="color: #008000;">"|-\n"</span><span style="color: #0000FF;">)</span>
for i=1 to length(lines) do
<span style="color: #004080;">integer</span> <span style="color: #000000;">cdx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lii</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lident</span>
{{},depth,{},span,parent,text,children} = lines[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
if depth=2 then cdx += 1 end if
<span style="color: #0000FF;">{</span><span style="color: #000000;">lii</span><span style="color: #0000FF;">,</span><span style="color: #000000;">depth</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lident</span><span style="color: #0000FF;">,</span><span style="color: #000000;">span</span><span style="color: #0000FF;">,</span><span style="color: #000000;">parent</span><span style="color: #0000FF;">,</span><span style="color: #000000;">text</span><span style="color: #0000FF;">,</span><span style="color: #000000;">children</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
string style = sprintf(`style="background: %s"`,{colours[cdx]})
<span style="color: #008080;">if</span> <span style="color: #000000;">depth</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span> <span style="color: #000000;">cdx</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if depth=d then
<span style="color: #004080;">string</span> <span style="color: #000000;">style</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`style="background: %s"`</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">colours</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cdx</span><span style="color: #0000FF;">]})</span>
if span!=1 then style &= sprintf(` colspan="%d"`,span) end if
<span style="color: #008080;">if</span> <span style="color: #000000;">depth</span><span style="color: #0000FF;">=</span><span style="color: #000000;">d</span> <span style="color: #008080;">then</span>
res &= sprintf(iff(html?"<td %s>%s</td>\n"
<span style="color: #008080;">if</span> <span style="color: #000000;">span</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #000000;">style</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">` colspan="%d"`</span><span style="color: #0000FF;">,</span><span style="color: #000000;">span</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
:"| %s | %s\n"),{style,text})
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">html</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"&lt;td %s&gt;%s&lt;/td&gt;\n"</span>
elsif depth<d and children={} then
<span style="color: #0000FF;">:</span><span style="color: #008000;">"| %s | %s\n"</span><span style="color: #0000FF;">),{</span><span style="color: #000000;">style</span><span style="color: #0000FF;">,</span><span style="color: #000000;">text</span><span style="color: #0000FF;">})</span>
-- res &= iff(html?"<td></td>\n"
<span style="color: #008080;">elsif</span> <span style="color: #000000;">depth</span><span style="color: #0000FF;"><</span><span style="color: #000000;">d</span> <span style="color: #008080;">and</span> <span style="color: #000000;">children</span><span style="color: #0000FF;">={}</span> <span style="color: #008080;">then</span>
-- :"| |\n")
<span style="color: #000080;font-style:italic;">-- res &= sprintf(iff(html?"<&lt;td %s><&gt;&lt;/td>&gt;\n"
-- :"| %s |\n"),{style})</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">html</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"&lt;td %s&gt;&lt;/td&gt;\n"</span>
end if
<span style="color: #0000FF;">:</span><span style="color: #008000;">"| %s |\n"</span><span style="color: #0000FF;">),{</span><span style="color: #000000;">style</span><span style="color: #0000FF;">})</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if html then
<span style="color: #008080;">end</span> res<span &style="color: #008080;">for</trspan>\n"
<span style="color: #008080;">if</span> <span style="color: #000000;">html</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">"&lt;/tr&gt;\n"</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
res &= iff(html?"</table>\n"
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
:"|}\n")
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">html</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"&lt;/table&gt;\n"</span>
puts(1,res)
<span style="color: #0000FF;">:</span><span style="color: #008000;">"|}\n"</span><span style="color: #0000FF;">)</span>
end procedure
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
for i=1 to length(outlines) do
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
markup(outlines[i],colours[i])
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">outlines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
end for</lang>
<span style="color: #000000;">markup</span><span style="color: #0000FF;">(</span><span style="color: #000000;">outlines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">colours</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
in html:
Line 2,099 ⟶ 2,532:
=={{header|Python}}==
===Python: Procedural===
<langsyntaxhighlight lang="python">"""Display an outline as a nested table. Requires Python >=3.6."""
 
import itertools
Line 2,367 ⟶ 2,800:
table_format = "wiki"
 
example(table_format)</langsyntaxhighlight>
{{out}}
 
Line 2,429 ⟶ 2,862:
 
===Python: Functional===
<langsyntaxhighlight lang="python">'''Display an outline as a nested table'''
 
from itertools import chain, cycle, takewhile
Line 2,601 ⟶ 3,034:
the same color as their non-root ancestor.
'''
colors = cycle(swatch + [""])
 
def go(tree):
Line 2,792 ⟶ 3,225:
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
{| class="wikitable" style="text-align: center;"
Line 2,826 ⟶ 3,259:
Strictly speaking, this is not a nested table. It is just a single level table that has some column spans > 1. For an example of using actual nested tables, see the task entry: [[Rosetta_Code/List_authors_of_task_descriptions#Raku|List_authors_of_task_descriptions#Raku]], [[Rosetta_Code/List_authors_of_task_descriptions/Full_list|(and full output)]].
 
<syntaxhighlight lang="raku" perl6line>my $outline = q:to/END/;
Display an outline as a nested table.
Parse the outline to a tree,
Line 2,970 ⟶ 3,403:
}
( $r, $g, $b ).map( ((*+$m) * 255).Int)».base(16).join
}</langsyntaxhighlight>
 
{{out}}
Line 3,038 ⟶ 3,471:
{{libheader|Wren-dynamic}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./dynamic" for Struct
import "./fmt" for Fmt
 
var NNode = Struct.create("NNode", ["name", "children"])
Line 3,186 ⟶ 3,619:
var iNodes2 = makeIndent.call(outline2, 4)
toNest.call(iNodes2, 0, 0, n2)
System.print(toMarkup.call(n2, cols2, 4))</langsyntaxhighlight>
 
{{out}}
Line 3,244 ⟶ 3,677:
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn parseOutline(outline){ //--> "tree" annotated with spans
var [const] indent=" "*100; // no tabs
 
Line 3,307 ⟶ 3,740:
out.writeln("|}");
out.text
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">outlineText:=Data(Void,
#<<<
"Display an outline as a nested table.
Line 3,326 ⟶ 3,759:
 
rows,cols,title,trees := parseOutline(outlineText);
makeMarkup(rows,cols,title,trees).println();</langsyntaxhighlight>
{{out}}
{| class="wikitable" style="text-align: center;"
Line 3,352 ⟶ 3,785:
 
And the Raku example:
<langsyntaxhighlight lang="zkl">outlineText:=Data(Void,
#<<<
"Display an outline as a nested table.
Line 3,372 ⟶ 3,805:
 
rows,cols,title,trees := parseOutline(outlineText);
makeMarkup(rows,cols,title,trees).println();</langsyntaxhighlight>
{{out}}
{| class="wikitable" style="text-align: center;"
908

edits