comment {

    Wenn 2 oder mehr Zeilen mit einer Nummerierung oder einem
    Aufzählungszeichen beginnen, dann werden die Zeilen eingesammelt
    und als Listenzeilen behandelt (TeX-Umgebung \begin{itemize}...).

    Wenn das Listenzeichen oder das Nummerierungsschema sich ändert,
    wird dies als Verschachtelung einer Liste behandelt so wie z. B. hier:

    1: eins
    2: zwo
       2a erster Einschub
       2b zweiter Einschub 
    3: drei
}

namespace eval ::numbering {
    variable numPat [[lambda {} {
	set punct {[<>().:-]}
	set arabic {[0-9]+[a-zA-Z]?}
	set alpha {[a-zA-Z][0-9]*}
	set roman {(?:[IVXLCDM]+|[ivxlcdm]+)[0-9]*}
	set number (?:$arabic|$alpha|$roman)
 	set numbered $punct?${number}(?:$punct$number)*$punct?
	#
	set unnumbered {[*>+-|]}
 	set result (?:$unnumbered|(?:$numbered))
	append result {[  \t]+}
    }]]

    variable itemPat "(?:(?:^|\\n+)$numPat\[\[:graph:\]\]\[^\\n\]+){2,}"
}

proc ::numbering::listType {line} {
    array set pat {
	* [*>+-|]
	1 [0-9]+
	a [a-z]+
	A [A-Z]+
	. [<>\(\).:-]+
    }
    set pat(?) (?:$pat(1)|$pat(a)|$pat(A)|$pat(.))
    variable numPat
    regexp $numPat $line match
    set head [string trim $match " \u00a0"]
    set patternMap [list * \\* + \\+ ? \\? ( \\(  ) \\)]
    set head [string map $patternMap $head]
    switch -regexp -- $pat(*)\\s $head {
	return [regexp -inline -- $head $pat(*)]
    } default {
	set result {}
	while {[regexp $pat(?) $head atom]} {
	    switch -regexp -- $atom $pat(1) {
		append result 1
	    } $pat(a) {
		append result a
	    } $pat(A) {
		append result A
	    } $pat(.) {
		append result [regexp -inline $pat(.) $head]
	    }
	    set l [string length $atom]
	    set head [string range $head $l end]
	}
    }
    regsub -all {[[:space:]]+} $result " "
}

proc ::numbering::listLevels {lines} {
    if {[globalSetting list-O-matic] ne "deep"} {
	return [string repeat " 1 " [llength $lines]]
    }
    set typeStack {}
    set result {}
    foreach line $lines {
	set type [listType $line]
	if {$type ne [tos typeStack]} {
	    if {[lsearch $typeStack $type] < 0} {
		push $type typeStack
	    } else {
		while {[tos typeStack] ne $type} {
		    pop typeStack
		}
	    }
	}
	lappend result [llength $typeStack]
    }
    set result
}

#
# getTextItemSequence
# take $txt, return sequence of (text, item, text, item ...)
#
proc ::numbering::getTextItemSequence {txt} {
    variable itemPat
    set itemParts {}
    set textIndices -1
    foreach indexPair [regexp -inline -indices -all $itemPat $txt] {
	let {from to} $indexPair
	lappend textIndices [expr {$from-1}] [expr {$to+1}]
	lappend itemParts [string range $txt $from $to]
    }
    lappend textIndices [string length $txt]
    set textParts {}
    foreach {from to} $textIndices {
	lappend textParts [string range $txt $from $to]
    }
    set result {}
    foreach textPart $textParts itemPart $itemParts {
	lappend result $textPart $itemPart
    }
    lrange $result 0 end-1
}

#
# item2lines
# return lines of an item area
#
proc ::numbering::item2lines {item} {
    regsub -all {\n+} $item \n item
    split [string trim $item] \n
}

#
# item2tex
# convert list src to TeX environment \begin{itemize}...\end{itemize}
#
proc ::numbering::item2tex {item} {
    if {[string trim $item] eq ""} {
	return
    }
    variable numPat
    regsub -all {\n+} $item \n item
    set result ""
    set lines [split [string trim $item] \n]
    set currentLevel 0
    foreach line $lines level [listLevels $lines] {
	while {$currentLevel < $level} {
	    append result\
		\n [string repeat "  " $currentLevel] \\begin{itemize}
	    incr currentLevel
	}
	while {$currentLevel > $level} {
	    incr currentLevel -1
	    append result\
		\n [string repeat "  " $currentLevel] \\end{itemize}
	}
	regexp $numPat $line __num
	set _num [string map [list \u00a0 ""] $__num]
	set l [string length $_num]
	set _text [string range $line $l end]
	set text [string trimleft $_text \u00a0]
	append result \n [string repeat "  " $currentLevel] \\item
	set num [string trim $_num]
	switch -- $num {
	    * {}
	    - {
		append result {[--]}
	    }
	    | {
		append result {[]}
	    }
	    default {
		append result\
		    \[\
		    [unicode2tex $num]\
		    \]
	    }
	}
	append result " " [unicode2tex [string trim $text]]
    }
    while {$currentLevel} {
	incr currentLevel -1
	append result \n \\end{itemize}
    }
    set result
}

#
# unicode2texWithItems
# return src converted to TeX including \begin{itemize}...
#
proc ::numbering::unicode2texWithItems {src} {
    if {[globalSetting list-O-matic] eq "none"} {
	return [unicode2tex $src]
    }
    set result ""
    foreach {text item} [getTextItemSequence $src] {
	append result\
	    [unicode2tex $text] \n\n\
	    [item2tex $item] \n\n
    }
    string trimright $result
}

namespace eval numbering {
    namespace export unicode2texWithItems *
}

namespace import -force ::numbering::*
