Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- param(
- [Parameter(Mandatory=$true)]$File
- )
- $lines = foreach($ln in Get-Content $File) {
- if($ln -match '^(\t*)(.+)$') {
- @{
- originalText = $ln
- text = $Matches[2]
- indentLevel = $Matches[1].Length
- }
- }
- }
- $lines = $lines | ? { $_.text -and $_.text.Trim() }
- function create-Indents($count) {
- return ([System.Linq.Enumerable]::Range(0, $count) | % { " " }) -join ''
- }
- function parse-Tree($currentLine, $lines) {
- function writein($text) {
- # Write-Host "$(create-Indents $currentLine.indentLevel)$text" -ForegroundColor Cyan
- }
- writein $currentLine.text
- writein "- $($lines.Count) remaining"
- $nextLine, $otherLines = $lines
- if(-not $currentLine) {
- return @{
- nodes = @()
- remaining = @()
- }
- }
- $node = @{
- line = $currentLine
- indentLevel = $currentLine.indentLevel
- text = $currentLine.text
- }
- if(-not $nextLine -or $nextLine.indentLevel -lt $currentLine.indentLevel) {
- $node.children = @()
- writein "- done"
- return @{
- nodes = @($node)
- remaining = $lines
- }
- }
- if($nextLine.indentLevel -eq $currentLine.indentLevel) {
- writein "- going over"
- $siblingsTree = parse-Tree $nextLine $otherLines
- writein "- adding $($siblingsTree.nodes.Count) siblings to $($node.text)"
- return @{
- nodes = @($node) + $siblingsTree.nodes
- remaining = $siblingsTree.remaining
- }
- }
- if($nextLine.indentLevel -gt $currentLine.indentLevel) {
- writein "- going down"
- $nextTree = parse-Tree $nextLine $otherLines
- writein "- adding $($nextTree.nodes.Count) children to $($node.text)"
- $node.children = $nextTree.nodes
- #todo - this can be slicker as it basically just repeats the above
- $nextLine, $otherLines = $nextTree.remaining
- if($nextLine.indentLevel -eq $currentLine.indentLevel){
- writein "- going over"
- $siblingsTree = parse-Tree $nextLine $otherLines
- writein "- adding $($siblingsTree.nodes.Count) siblings to $($node.text)"
- return @{
- nodes = @($node) + $siblingsTree.nodes
- remaining = $siblingsTree.remaining
- }
- }
- if(-not $nextLine -or $nextLine.indentLevel -lt $currentLine.indentLevel) {
- writein "- done"
- return @{
- nodes = @($node)
- remaining = @($nextLine) + $otherLines
- }
- }
- }
- }
- function visitLast($node, [scriptblock]$fn) {
- if(-not $node) {
- return
- }
- foreach($child in $node.children){
- visitLast $child $fn
- }
- &$fn $node
- }
- function visitFirst($node, [scriptblock]$fn, $acc) {
- if(-not $node) {
- return
- }
- &$fn $node $acc
- foreach($child in $node.children){
- visitFirst $child $fn $acc
- }
- }
- $head, $tail = $lines
- $parsed = parse-Tree $head $tail
- function parse-nodeText($node) {
- $parts = @( $node.text -split ',' | % { $_.Trim() } )
- if($parts[0] -match '^(\d+)\s*(-\s*(\d+))?') {
- $node.item = $parts[1]
- $node.description = $parts[2]
- if($node.children) {
- Write-Warning "Line has an estimate and children - ignoring children sum. '$($node.line.text)'"
- }
- $node.estimate = [int]$matches[1],[int]$matches[1]
- if($matches.Count -eq 4) {
- $node.estimate[1] = [int]$matches[3]
- }
- } else {
- $node.item = $parts[0]
- $node.description = $parts[1]
- $node.estimate = $null,$null
- if(-not $node.children) {
- Write-Warning "no estimate on leaf '$($node.text)'"
- }
- foreach($child in $node.children) {
- $node.estimate[0] += $child.estimate[0]
- $node.estimate[1] += $child.estimate[1]
- }
- }
- }
- foreach($node in $parsed.nodes) {
- visitLast $node ${function:parse-nodeText}
- }
- function create-OutputItem($node, $acc) {
- $hash = [ordered]@{
- min = $node.estimate[0]
- max = $node.estimate[1]
- item = "$(create-Indents $node.indentLevel)$($node.item)"
- description = $node.description
- }
- $acc.Add( (New-Object PsObject -property $hash) ) | out-null
- }
- $outgoingItems = new-object System.Collections.ArrayList
- foreach($node in $parsed.nodes) {
- visitFirst $node ${function:create-OutputItem} $outgoingItems
- }
- return $outgoingItems
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement