Sort an outline at every level: Difference between revisions

Content added Content deleted
m (→‎{{header|Phix}}: added syntax colouring the hard way)
Line 1,489: Line 1,489:


=={{header|Phix}}==
=={{header|Phix}}==
<!--<lang Phix>(notonline)-->
<lang Phix>procedure print_children(sequence lines, children, string indent, bool bRev)
<span style="color: #008080;">procedure</span> <span style="color: #000000;">print_children</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: #000000;">children</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">indent</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">bRev</span><span style="color: #0000FF;">)</span>
sequence tags = custom_sort(lines,children)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tags</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">children</span><span style="color: #0000FF;">)</span>
if bRev then tags = reverse(tags) end if
<span style="color: #008080;">if</span> <span style="color: #000000;">bRev</span> <span style="color: #008080;">then</span> <span style="color: #000000;">tags</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tags</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for i=1 to length(tags) do
<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;">tags</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
integer ti = tags[i]
<span style="color: #004080;">integer</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
printf(1,"%s%s\n",{indent,lines[ti][1]})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">indent</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]})</span>
print_children(lines,lines[ti][$],lines[ti][2],bRev)
<span style="color: #000000;">print_children</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">][$],</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],</span><span style="color: #000000;">bRev</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>

constant spaced = """
<span style="color: #008080;">constant</span> <span style="color: #000000;">spaced</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
zeta
zeta
beta
gamma
beta
lambda
gamma
kappa
lambda
mu
kappa
delta
mu
delta
alpha
alpha
theta
iota
theta
epsilon
iota
epsilon
""",
"""</span><span style="color: #0000FF;">,</span>
tabbed = substitute(spaced," ","\t"),
<span style="color: #000000;">tabbed</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">spaced</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\t"</span><span style="color: #0000FF;">),</span>
confused = substitute_all(spaced,{" gamma"," kappa"},{"gamma","\t kappa"}),
<span style="color: #000000;">confused</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">(</span><span style="color: #000000;">spaced</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">" gamma"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" kappa"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"gamma"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\t kappa"</span><span style="color: #0000FF;">}),</span>
ragged = substitute_all(spaced,{" gamma","kappa"},{"gamma"," kappa"}),
<span style="color: #000000;">ragged</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">(</span><span style="color: #000000;">spaced</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">" gamma"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"kappa"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"gamma"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" kappa"</span><span style="color: #0000FF;">}),</span>
tests = {spaced,tabbed,confused,ragged},
<span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">spaced</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tabbed</span><span style="color: #0000FF;">,</span><span style="color: #000000;">confused</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ragged</span><span style="color: #0000FF;">},</span>
names = "spaced,tabbed,confused,ragged"
<span style="color: #000000;">names</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"spaced,tabbed,confused,ragged"</span>

procedure test(sequence lines)
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span>
sequence pi = {-1}, -- indents (to locate parents)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">pi</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- indents (to locate parents)</span>
pdx = {0}, -- indexes for ""
<span style="color: #000000;">pdx</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- indexes for ""</span>
children = {},
<span style="color: #000000;">children</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
roots = {}
<span style="color: #000000;">roots</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
for i=1 to length(lines) do
<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>
string line = trim_tail(lines[i]),
<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>
text = trim_head(line)
<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>
integer indent = length(line)-length(text)
<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>
-- remove any completed parents
<span style="color: #000080;font-style:italic;">-- remove any completed parents</span>
while length(pi) and indent<=pi[$] do
<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>
pi = pi[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>
pdx = pdx[1..$-1]
<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>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
integer parent = 0
<span style="color: #004080;">integer</span> <span style="color: #000000;">parent</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
if length(pi) then
<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>
parent = pdx[$]
<span style="color: #000000;">parent</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pdx</span><span style="color: #0000FF;">[$]</span>
if parent=0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">parent</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
if indent!=0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">indent</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
printf(1,"**invalid indent** (%s, line %d)\n\n",{text,i})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"**invalid indent** (%s, line %d)\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">text</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">})</span>
return
end if
<span style="color: #008080;">return</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
roots &= i
<span style="color: #000000;">roots</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">i</span>
else
if lines[parent][$]={} then
<span style="color: #008080;">else</span>
<span style="color: #008080;">if</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: #008080;">then</span>
lines[parent][2] = line[1..indent]
<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: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">line</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">indent</span><span style="color: #0000FF;">]</span>
elsif lines[parent][2]!=line[1..indent] then
<span style="color: #008080;">elsif</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: #000000;">2</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">line</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">indent</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
printf(1,"**inconsistent indent** (%s, line %d)\n\n",{text,i})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"**inconsistent indent** (%s, line %d)\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">text</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">})</span>
return
end if
<span style="color: #008080;">return</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
lines[parent][$] &= i -- (update children)
<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>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
pi &= indent
<span style="color: #000000;">pi</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">indent</span>
pdx &= i
<span style="color: #000000;">pdx</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">i</span>
lines[i] = {text,"",children}
<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;">text</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">children</span><span style="color: #0000FF;">}</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
printf(1,"ascending:\n")
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ascending:\n"</span><span style="color: #0000FF;">)</span>
print_children(lines,roots,"",false)
<span style="color: #000000;">print_children</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">roots</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
printf(1,"\ndescending:\n")
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\ndescending:\n"</span><span style="color: #0000FF;">)</span>
print_children(lines,roots,"",true)
<span style="color: #000000;">print_children</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">roots</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
printf(1,"\n")
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>

for t=1 to length(tests) do
<span style="color: #008080;">for</span> <span style="color: #000000;">t</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;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
string name = split(names,",")[t]
<span style="color: #004080;">string</span> <span style="color: #000000;">name</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">names</span><span style="color: #0000FF;">,</span><span style="color: #008000;">","</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">t</span><span style="color: #0000FF;">]</span>
-- printf(1,"Test %d (%s):\n%s\n",{t,name,tests[t]})
printf(1,"Test %d (%s):\n",{t,name})
<span style="color: #000080;font-style:italic;">-- printf(1,"Test %d (%s):\n%s\n",{t,name,tests[t]})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Test %d (%s):\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">name</span><span style="color: #0000FF;">})</span>
sequence lines = split(tests[t],"\n",no_empty:=true)
<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;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t</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>
test(lines)
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span>
end for</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</lang>-->
{{out}}
{{out}}
<pre>
<pre>