# ===========================================================================
# File: convert.tcl
# Target: text
#                        Created: 2010-08-29 09:51:41
#              Last modification: 2012-04-11 19:55:46
# Author: Bernard Desgraupes
# e-mail: <bdesgraupes@users.sourceforge.net>
# (c) Copyright: Bernard Desgraupes 2010-2012
# All rights reserved.
# Description: Aida callbacks for target text
# ===========================================================================


namespace eval text {
	variable split_file ""
	
	# Ensure fallback on base commands
	namespace path ::base
	
}


# Hooks
# -----

proc text::preConvertHook {} {}

proc text::postConvertHook {} {}

proc text::splitHook {file} {}


# Callbacks
# ---------

# # Use defaults for:
#     text::imageProc
#     text::linkProc
#     text::newLineProc
#     text::postambleProc
#     text::preambleProc
#     text::styleProc
#     text::tableProc
#     text::verbatimProc



## 
 # ------------------------------------------------------------------------
 # 
 # "text::anchorProc" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::anchorProc {label} {
	return "\[\[[aida::getRefMark $label]\]\]"
}


## 
 # ------------------------------------------------------------------------
 # 
 # "text::commentProc" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::commentProc {str} {
	set prfx [aida::getParam CommentPrefix text]
	return "$prfx$str"
}


##
 # ------------------------------------------------------------------------
 # 
 # "text::horizRuleProc" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::horizRuleProc {} {
	global aida_head
	set wd [aida::getParam PageWidth text]
	if {$wd <= 0} {
		set wd 80
	} 
	return "[string repeat "-" $wd]\n"
}


## 
 # ------------------------------------------------------------------------
 # 
 # "text::listProc" --
 # 
 # Build a default list.
 # 
 # The type argument can be: ol, ul, dl.
 # 
 # The supported list attributes are: 
 # 		start	-> ordered list
 # 		type	-> ordered list: 1 A a I i		<---  not handled yet
 # 				-> unordered list: disc square circle
 # 
 # ------------------------------------------------------------------------
 ##
proc text::listProc {kind depth attr itemList} {
	set block [list]
	set attrDict [aida::getAttr $kind $attr]
	if {[catch {dict get $attrDict start} cnt]} {
		set cnt 1
	} 
	if {[catch {dict get $attrDict type} tp]} {
		set tp "1"
	} 
	set indent [string repeat "    " $depth]
	set marker "<@t@x@t@>"

	if {$kind eq "ol"} {
		set head "$cnt. "
	} elseif {$kind eq "ul"} {
		if {[catch {dict get $attrDict type} tp]} {
			set tp "circle"
		} 
		switch -- $tp {
			"circle" {
				set head "o "
			}
			"disc" {
				set head "\u2022 "
			}
			"square" {
				set head "* "
			}
			"none" {
				set head ""
			}
			default {
				error "unknown type '$tp'"
			}
		}
	} else {
		set head ""
	} 
	foreach itm $itemList {
		if {$kind eq "dl"} {
			lappend block "\n$marker$indent[lindex $itm 0]\n[text::_wrapListItem [lindex $itm 1] $marker $indent]"
		} else {
			lappend block "\n[text::_wrapListItem $itm $marker $indent $head]"
			if {$kind eq "ol"} {
				incr cnt
				set head "$cnt. "
			}
		} 
	} 
	
	set result [join $block "\n"]
	if {$depth == 1} {
		regsub -all "$marker" $result "" result
	} 
	return $result
}


## 
 # ------------------------------------------------------------------------
 # 
 # "text::navBarProc" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::navBarProc {curr prev next top} {
	if {[aida::getParam NavBar]} {
		set result [list]
		if {$curr ne $top} {
			lappend result "[aida::getParam NavTop]: $top"		
		} 
		if {$prev ne ""} {
			lappend result "[aida::getParam NavPrev]: $prev"
		} 
		if {$next ne ""} {
			lappend result "[aida::getParam NavNext]: $next"
		} 

		return "[join $result " | "]\n\n"		
	} else {
		return ""
	} 
}


##
 # ------------------------------------------------------------------------
 # 
 # "text::printIndexProc" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::printIndexProc {} {
	variable aida_head

	set numidx [aida::getParam NumberIndices]
	set result [list] 
	
	for {set idx 0} {$idx < [aida::countIndexMarks]} {incr idx} {
		lassign [aida::getIndexMark $idx] fl str
		if {[info exist indexArr($str)]} {
			if {$numidx} {
				lappend indexArr($str) "\[$idx\]"
			} 
		} else {
			set indexArr($str) "\[$idx\]"
		} 
	} 
	if {[info exists indexArr]} {
		if {$numidx} {
			foreach word [lsort -dict [array names indexArr]] {
				lappend result "$word\t[join $indexArr($word) ", "]"
			} 
		} else {
			set result [lsort -dict [array names indexArr]]
		} 
	} 
	return [join $result "\n"]
}


##
 # ------------------------------------------------------------------------
 # 
 # "text::refProc" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::refProc {str label {file ""}} {
	if {$file eq ""} {
		return "[string trim $str] \[\[[aida::getRefMark $label]\]\]"
	} else {
		return "[string trim $str] ($file \[\[[aida::getRefMark $label]\]\])"
	} 
}


## 
 # ------------------------------------------------------------------------
 # 
 # "text::sectionProc" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::sectionProc {str level {file ""}} {
	set ultitle [aida::getParam UnderlineTitles text]
	set title [aida::newSectionNumber $level]
	append title [aida::unwrapText [string trim $str]]
	aida::setSectionMark $level $file $title
	if {$ultitle ==  1} {
		if {$level == 1} {
			set usym "="
		} else {
			set usym "-"
		} 
		set uline [string repeat $usym [string length $title]]
		append title "\n" $uline
	} 
	return $title
}


## 
 # ------------------------------------------------------------------------
 # 
 # "text::setIndexProc" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::setIndexProc {str {file ""}} {
	set idx [aida::setIndexMark $file $str]
	if {[aida::getParam NumberIndices]} {
		set mark "\[$idx\]"
	} else {
		set mark ""
	} 		
	return $mark
}


##
 # ------------------------------------------------------------------------
 # 
 # "text::tocProc" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::tocProc {} {
	variable split_file

	set result [list]
	set depth [aida::getParam TocDepth]
	
	for {set sc 0} {$sc < [aida::countSectionMarks]} {incr sc} {
		lassign [aida::getSectionMark $sc] lv fl title
		if {$lv <= $depth} {
			if {[aida::splitting] && $fl ne $split_file} {
				lappend result "\n$fl"
				set split_file $fl
			} 			
			lappend result "[string repeat "  " $lv]$title"
		} 
	} 
	return [join $result "\n"]
}


##
 # ------------------------------------------------------------------------
 # 
 # "text::verbProc" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::verbProc {str} {
	return "'$str'"
}


# Target specific utility procs
# =============================


##
 # ------------------------------------------------------------------------
 # 
 # "text::defaultExtension" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::defaultExtension {} {
	if {[catch {aida::getParam Extension text} result]} {
		set result ".txt"
	} 
	return $result
}


## 
 # ------------------------------------------------------------------------
 # 
 # "text::_wrapListItem" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::_wrapListItem {item marker indent {head ""}} {
	set result [list]
	set lines [split $item "\n"]
	set len [llength $lines]
	set cumul [list]
	
	for {set i 0} {$i < $len} {incr i} {
		set li [lindex $lines $i]
		if {$li eq ""} {
			continue
		} 
		if {![regexp "^$marker" $li]} {
			lappend cumul $li
		} else {
			# Handle what has been accumulated
			if {[llength $cumul]} {
				lappend result [text::_wrapBlock $cumul $marker $indent $head]	
				set head ""
				set cumul [list]
			} 
			lappend result $li
		}
	}
	# Remaining accumulation
	if {[llength $cumul]} {
		lappend result [text::_wrapBlock $cumul $marker $indent $head]	
	} 
	
	return [join $result "\n"]
}


## 
 # ------------------------------------------------------------------------
 # 
 # "text::_wrapBlock" --
 # 
 # ------------------------------------------------------------------------
 ##
proc text::_wrapBlock {cumul marker indent {head ""}} {
	if {![catch {aida::getParam ListWrap text} res] && $res == 0} {
		set result [list]
		set cnt 0
		foreach line $cumul {
			if {$cnt > 0} {
				set head ""
			} 
			lappend result "$marker$indent$head$line"
			incr cnt
		} 
		return [join $result "\n"]
	} else {
		set lc [join $cumul " "]
		set lc [aida::wrapText "$head$lc" $indent]		
		regsub -all {([\n\r])} $lc "\\1$marker" lc
		return "$marker$lc"
	}	
}



