How to resolve the algorithm Display an outline as a nested table step by step in the AutoHotkey programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Display an outline as a nested table step by step in the AutoHotkey programming language

Table of Contents

Problem Statement

The graphic representation of outlines is a staple of mind-mapping and the planning of papers, reports, and speeches. Given a outline with at least 3 levels of indentation, for example: 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: 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.

Display your nested table on this page.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Display an outline as a nested table step by step in the AutoHotkey programming language

Source code in the autohotkey programming language

outline2table(db, Delim:= "`t"){
	oNum:=[], oMID:=[], oNod := [], oKid := [], oPnt := [], oMbr := [], oLvl := []
	oCrl := ["#ffffe6;", "#ffebd2;", "#f0fff0;", "#e6ffff;", "#ffeeff;"]
	col := 0, out := "", anc := ""
	
	; create numerical index for each line
	for i, line in StrSplit(db, "`n", "`r")
	{
		RegExMatch(line, "^(\t*)(.*)$", m)
		out .= m1 . i "`n"
		oNum[i] := m2
	}
	db := Trim(out, "`n")

	; create list of members, parents, kids and their ancestors
	for i, mbr in StrSplit(db, "`n", "`r")
	{
		lvl := 1
		While (SubStr(mbr, 1, 1) = Delim)
			lvl++,	mbr := SubStr(mbr, 2)
		
		if (pLvl >= lvl) && pMbr
			col++
			, oMbr[pLvl, pMbr] .=  "col:" col ",anc:" anc
			, oKid[pLvl, pMbr] .=  "col:" col ",anc:" anc
		
		if (pLvl > lvl) && pMbr
			loop % pLvl - lvl
				anc := RegExReplace(anc, "\d+_?$")
		
		if (pLvl < lvl) && pMbr
			anc .= pMbr "_"
			, oMbr[pLvl, pMbr] .= "col:" col+1 ",anc:" anc
			, oPnt[pLvl, pMbr] .= "col:" col+1 ",anc:" anc
		
		pLvl	:= lvl
		pMbr	:= mbr
		;~ oMID[lvl] := TV_Add(mbr, oMID[lvl-1], "Expand")
	}
	; last one on the list
	col++
	oMbr[pLvl, pMbr] .= "col:" col ",anc:" anc
	oKid[pLvl, pMbr] .= "col:" col ",anc:" anc

	; setup node color
	clr := 1
	for lvl, obj in oMbr
		for node, str in obj
			if (lvl <= 2)
				oNod[node, "clr"] := clr++
			else
				oNod[node, "clr"] := oNod[StrSplit(str, "_").2, "clr"]
		
	; setup node level/column/width
	for lvl, obj in oKid
		for node, str in obj
		{
			x := StrSplit(str, ",")
			col := StrReplace(x.1, "col:")
			anc := Trim(StrReplace(x.2, "anc:"), "_")
			for j, a in StrSplit(anc, "_")
				oNod[a, "wid"] := (oNod[a, "wid"]?oNod[a, "wid"]:0) + 1
				
			oNod[node, "lvl"] := lvl
			oNod[node, "col"] := col
			oNod[node, "wid"] := 1
		}
		
	for lvl, obj in oPnt
		for node, str in obj
		{
			x := StrSplit(str, ",")
			col := StrReplace(x.1, "col:")
			anc := Trim(StrReplace(x.2, "anc:"), "_")
			oNod[node, "lvl"] := lvl
			oNod[node, "col"] := col
		}
	
	; setup members by level
	for node, obj in oNod
		oLvl[obj["lvl"], node] := 1
	
	maxW := 0
	for node in oLvl[1]
		maxW += oNod[node, "wid"]
		
	; setup HTML
	html := "<table class=""wikitable"" style=""text-align: center;"">`n"
	for lvl, obj in oLvl
	{
		pCol := 1
		html .= "<tr>`n"
		for node, bool in obj
		{
			while (oNod[node, "col"] <> pCol)
				pCol++, html .= "`t<td style=""background: #F9F9F9;""></td>`n"
			pCol += oNod[node, "wid"]
			if !cNum := Mod(oNod[node, "clr"], 5)
				cNum := 5
			html .= "`t<td style=""background: " oCrl[cNum] """ colspan=""" oNod[node, "wid"] """>" oNum[node] "</td>`n"
		}
		while (pCOl <= maxW)
			pCol++, html .= "`t<td style=""background: #F9F9F9;""></td>`n"
		html .= "</tr>`n"
	}
	html .= "</table>"
	
	; setup wikitable
	wTable := "{| class=""wikitable"" style=""text-align: center;""`n"
	for lvl, obj in oLvl
	{
		pCol := 1
		wTable .= "|-`n"
		for node, bool in obj
		{
			while (oNod[node, "col"] <> pCol)
				pCol++, wTable .= "|  | `n"
			pCol += oNod[node, "wid"]
			if !cNum := Mod(oNod[node, "clr"], 5)
				cNum := 5
			wTable .= "| style=""background: " oCrl[cNum] """ colspan=""" oNod[node, "wid"] " |" oNum[node] "`n"
		}
		while (pCOl <= maxW)
			pCol++, wTable .= "|  | `n"
		
	}
	wTable .= "|}`n"
	return [html, wTable]
}


db =
(
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.
)

Gui, add, ActiveX, vDocument w1000 r14, HTMLFile
result := outline2table(db)
Document.Write(result.1)
Gui, Show
MsgBox % "HTML:`n" result.1 "`n`nWikitable:`n" result.2
return


  

You may also check:How to resolve the algorithm Count occurrences of a substring step by step in the Draco programming language
You may also check:How to resolve the algorithm Function prototype step by step in the PureBasic programming language
You may also check:How to resolve the algorithm Variables step by step in the AWK programming language
You may also check:How to resolve the algorithm Top rank per group step by step in the PL/SQL programming language
You may also check:How to resolve the algorithm Solve a Hopido puzzle step by step in the AutoHotkey programming language