summaryrefslogtreecommitdiff
path: root/support/dinbrief-gui
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dinbrief-gui
Initial commit
Diffstat (limited to 'support/dinbrief-gui')
-rw-r--r--support/dinbrief-gui/dinbrief.bat1
-rw-r--r--support/dinbrief-gui/dinbrief.kitbin0 -> 24782 bytes
-rwxr-xr-xsupport/dinbrief-gui/dinbrief.sh1
-rw-r--r--support/dinbrief-gui/dinbrief.vfs/.ofl0
-rwxr-xr-xsupport/dinbrief-gui/dinbrief.vfs/adjustTabs.tcl387
-rwxr-xr-xsupport/dinbrief-gui/dinbrief.vfs/constants.tcl324
-rwxr-xr-xsupport/dinbrief-gui/dinbrief.vfs/dinbrief.tcl240
-rwxr-xr-xsupport/dinbrief-gui/dinbrief.vfs/hyphen.tcl92
-rwxr-xr-xsupport/dinbrief-gui/dinbrief.vfs/main.tcl14
-rwxr-xr-xsupport/dinbrief-gui/dinbrief.vfs/menu.tcl621
-rwxr-xr-xsupport/dinbrief-gui/dinbrief.vfs/numbering.tcl201
-rwxr-xr-xsupport/dinbrief-gui/dinbrief.vfs/richtext.tcl579
-rw-r--r--support/dinbrief-gui/dinbrief.vfs/searchText.tcl300
-rw-r--r--support/dinbrief-gui/dinbrief.vfs/tabs2tex.tcl207
-rwxr-xr-xsupport/dinbrief-gui/dinbrief.vfs/util.tcl486
-rw-r--r--support/dinbrief-gui/global.vars1
16 files changed, 3454 insertions, 0 deletions
diff --git a/support/dinbrief-gui/dinbrief.bat b/support/dinbrief-gui/dinbrief.bat
new file mode 100644
index 0000000000..7101d603f0
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.bat
@@ -0,0 +1 @@
+wish dinbrief.vfs\main.tcl \ No newline at end of file
diff --git a/support/dinbrief-gui/dinbrief.kit b/support/dinbrief-gui/dinbrief.kit
new file mode 100644
index 0000000000..f047a78a17
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.kit
Binary files differ
diff --git a/support/dinbrief-gui/dinbrief.sh b/support/dinbrief-gui/dinbrief.sh
new file mode 100755
index 0000000000..17f3f48f32
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.sh
@@ -0,0 +1 @@
+wish dinbrief.vfs/main.tcl \ No newline at end of file
diff --git a/support/dinbrief-gui/dinbrief.vfs/.ofl b/support/dinbrief-gui/dinbrief.vfs/.ofl
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.vfs/.ofl
diff --git a/support/dinbrief-gui/dinbrief.vfs/adjustTabs.tcl b/support/dinbrief-gui/dinbrief.vfs/adjustTabs.tcl
new file mode 100755
index 0000000000..c8ce23fcec
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.vfs/adjustTabs.tcl
@@ -0,0 +1,387 @@
+namespace eval AdjustTabs {
+ variable counter 0
+}
+
+proc ::AdjustTabs::checkTabEvent {win} {
+ set index [$win index insert]
+ let {line col} [split $index .]
+ set tabTag [getTabTagAt $win insert]
+ set tabOccurs [winHasTabsAtLine $win $line]
+ if {!$tabOccurs && ($tabTag eq "")} {
+ # no tabs, nothing to do
+ return
+ } elseif {$tabTag eq ""} {
+ # new tab set
+ set tabTags [setTabTagAt $win $index]
+ } elseif {!$tabOccurs} {
+ # existing tab deleted
+ set tabTags [removeTabTagAt $win $index]
+ } else {
+ # existing tab area changed
+ set tabTags $tabTag
+ }
+ foreach tag $tabTags {
+ set code [namespace code "adjustWinTagTabs $win $tag"]
+ after cancel $code
+ after idle $code
+ }
+}
+
+#
+# ::AdjustTabs::removeTabTagAt
+# remove tags tab and tab[0-9]+ at $index
+# if inside, split area tabi to tabi + tabj
+# return name(s) of affected tags
+#
+proc ::AdjustTabs::removeTabTagAt {win index} {
+ set thisTabTag [getTabTagAt $win $index]
+ if {$thisTabTag eq ""} {
+ return
+ }
+ set fromIndex [$win index "$index linestart"]
+ set toIndex [$win index $fromIndex+1lines]
+ $win tag remove tab $fromIndex $toIndex
+ if {[$win compare $fromIndex > 1.0]} {
+ set aboveTabTag [getTabTagAt $win $fromIndex-1lines]
+ } else {
+ set aboveTabTag ""
+ }
+ set belowTabTag [getTabTagAt $win $toIndex]
+ if {$aboveTabTag eq "" && $belowTabTag eq ""} {
+ # no neighbour tab area
+ $win tag remove $thisTabTag $fromIndex $toIndex
+ return
+ } elseif {$belowTabTag eq ""} {
+ # reduce tag area above
+ $win tag remove $aboveTabTag $fromIndex $toIndex
+ return $aboveTabTag
+ } elseif {$aboveTabTag eq ""} {
+ # reduce tag area below
+ $win tag remove $belowTabTag $fromIndex $toIndex
+ return $belowTabTag
+ } else {
+ # split tag area
+ let {fromAround toAround} [$win tag prevrange $aboveTabTag $index]
+ $win tag remove $aboveTabTag $fromIndex $toAround
+ set newTabTag [genTagName $win]
+ lappend result $newTabTag
+ $win tag add $newTabTag $toIndex $toAround
+ # return this value
+ list $aboveTabTag $newTabTag
+ }
+}
+
+#
+# ::AdjustTabs::setTabTagAt
+# set tag tab[0-9]+ at $index
+# return tag name
+#
+proc ::AdjustTabs::setTabTagAt {win index} {
+ if {[getTabTagAt $win $index] ne ""} {
+ return
+ }
+ set fromIndex [$win index "$index linestart"]
+ set toIndex [$win index $fromIndex+1lines]
+ $win tag add tab $fromIndex $toIndex
+ if {[$win compare $fromIndex > 1.0]} {
+ set aboveTabTag [getTabTagAt $win $fromIndex-1lines]
+ } else {
+ set aboveTabTag ""
+ }
+ set belowTabTag [getTabTagAt $win $toIndex]
+ if {$aboveTabTag eq "" && $belowTabTag eq ""} {
+ # no neighbour tab area
+ set thisTabTag [genTagName $win]
+ $win tag add $thisTabTag $fromIndex $toIndex
+ return $thisTabTag
+ } elseif {$belowTabTag eq ""} {
+ # extend above tab area
+ $win tag add $aboveTabTag $fromIndex $toIndex
+ return $aboveTabTag
+ } elseif {$aboveTabTag eq ""} {
+ # extend below tab area
+ $win tag add $belowTabTag $fromIndex $toIndex
+ return $belowTabTag
+ } else {
+ # join tab area below and above
+ let {belowFrom belowTo} [$win tag ranges $belowTabTag]
+ $win tag remove $belowTabTag 1.0 end
+ $win tag add $aboveTabTag $fromIndex $belowTo
+ return $aboveTabTag
+ }
+}
+
+#
+# ::AdjustTabs::initTabTags
+# remove all tags tab[0-9]+
+# set tag tab on lines containing \t
+# set new tags tab[0-9]+
+# return list of set tags tab[0-9]+
+#
+proc ::AdjustTabs::initTabTags {win} {
+ $win tag remove tab 1.0 end
+ foreach tag [$win tag names] {
+ if {[regexp {^tab[0-9]+$} $tag]} {
+ $win tag remove $tag 1.0 end
+ }
+ }
+ set from 1.0
+ set to 2.0
+ while {[$win compare $from < end]} {
+ if {[$win search \t $from $to] ne ""} {
+ $win tag add tab $from $to
+ }
+ set from [$win index $from+1lines]
+ set to [$win index $to+1lines]
+ }
+ set result {}
+ foreach {from to} [$win tag ranges tab] {
+ set tabTag [genTagName $win]
+ $win tag add $tabTag $from $to
+ lappend result $tabTag
+ after idle\
+ [namespace code\
+ [list atjustWinTagTabsBackground $win $tabTag]]
+ }
+ raise [winfo toplevel .]
+ set result
+}
+
+#
+# ::AdjustTabs::genTagName
+# return tag name tab[0-9]+ which is new to $win
+#
+proc ::AdjustTabs::genTagName {win} {
+ variable counter
+ while {[lsearch [$win tag names] tab$counter] >= 0} {
+ incr counter
+ }
+ return tab$counter
+}
+
+#
+# ::AdjustTabs::getTabTagAt
+# return first tag tab[0-9]+ occuring at $index
+#
+proc ::AdjustTabs::getTabTagAt {win index} {
+ foreach tag [$win tag names $index] {
+ if {[regexp {^tab[0-9]+$} $tag]} {
+ return $tag
+ }
+ }
+}
+
+#
+# ::AdjustTabs::winHasTabsAtLine
+# return true if \t occurs in $line
+#
+proc ::AdjustTabs::winHasTabsAtLine {win line} {
+ expr {[$win search \t $line.0 $line.end] ne ""}
+}
+
+#
+# ::AdjustTabs::adjustWinTabAt
+# adjust tab tag which occurs in $window at $index
+#
+proc ::AdjustTabs::adjustWinTabAt {window index} {
+ set tabTag [getTabTagAt $window $index]
+ adjustWinTagTabs $window $tabTag
+}
+
+#
+# ::AdjustTabs::atjustWinTagTabsBackground
+#
+#
+proc ::AdjustTabs::atjustWinTagTabsBackground {win tag} {
+ if {![winfo exists $win] || [$win tag ranges $tag] eq ""} {
+ return
+ }
+ while {true} {
+ let {from to} [$win tag ranges $tag]
+ let {fromLine fromCol} [split $from .]
+ let {toLine toCol} [split $to .]
+ set someLinesVisible 0
+ set allLinesVisible 1
+ foreach line [range $fromLine $toLine] {
+ if {[$win dlineinfo $line.0] eq ""} {
+ set allLinesVisible 0
+ } else {
+ set someLinesVisible 1
+ }
+ }
+ if {$allLinesVisible} {
+ adjustWinTagTabs $win $tag
+ break
+ } elseif {$someLinesVisible} {
+ adjustWinTagTabs $win $tag
+ sleep 200
+ } else {
+ sleep 500
+ }
+ }
+ list tabstops of $tag in $win are adjusted
+}
+
+#
+# ::AdjustTabs::adjustWinTagTabs
+# adjust tabs in range of tag $tabTab
+# such that no cols overlap each other
+#
+proc ::AdjustTabs::adjustWinTagTabs {tabWindow tabTag {distance 12}} {
+ set ranges [$tabWindow tag ranges $tabTag]
+ if {$ranges eq {}} {
+ return
+ }
+ set lineNrs {}
+ foreach {from to} [$tabWindow tag ranges $tabTag] {
+ set startIndex [$tabWindow index "$from linestart"]
+ let {startLine startCol} [split $startIndex .]
+ while {[$tabWindow compare $startLine.0 < $to]} {
+ lappend lineNrs $startLine
+ incr startLine
+ }
+ }
+ if {[llength $lineNrs] <= 1} {
+ $tabWindow tag configure $tabTag -tabs {}
+ return
+ }
+ set cols ""
+ foreach nr $lineNrs {
+ set tabs [numOfTabsAtLine $tabWindow $nr]
+ if {$cols eq ""} {
+ set cols $tabs
+ } elseif {($tabs ne "" && $tabs > $cols)} {
+ set cols $tabs
+ }
+ }
+ if {$cols eq ""} {
+ return
+ }
+ set colWidths {}
+ for {set i 0} {$i < $cols} {incr i} {
+ set currentWidth [winTagColWidth $tabWindow $tabTag $i]
+ if {$currentWidth eq ""} {
+ break
+ }
+ incr currentWidth $distance
+ lappend colWidths $currentWidth
+ }
+ set tabstops {}
+ set tabstop 0
+ foreach colWidth $colWidths {
+ lappend tabstops [incr tabstop $colWidth]
+ }
+ $tabWindow tag configure $tabTag -tabs $tabstops
+}
+
+#
+# ::AdjustTabs::winTagColWidth
+# return really needed width inside tag $tabTag on col $colNr
+#
+proc ::AdjustTabs::winTagColWidth {tabWindow tabTag colNr} {
+ set result ""
+ foreach {from to} [$tabWindow tag ranges $tabTag] {
+ set startIndex [$tabWindow index "$from linestart"]
+ let {startLine startCol} [split $startIndex .]
+ while {[$tabWindow compare $startLine.0 < $to]} {
+ set colWidth [calcLineColWidth $tabWindow $startLine $colNr]
+ if {$colWidth ne ""} {
+ if {$result eq "" || $colWidth > $result} {
+ set result $colWidth
+ }
+ }
+ incr startLine
+ }
+ }
+ set result
+}
+
+#
+# ::AdjustTabs::calcLineColWidth
+# return really needed width in line $line at tabstop $colNr
+#
+proc ::AdjustTabs::calcLineColWidth {window line colNr} {
+ if {$colNr == 0} {
+ let {x y w h} [$window bbox $line.0]
+ if {![info exists x]} {
+ return
+ }
+ set leftEdge $x
+ } else {
+ set leftEdge [calcTabRightEdge $window $line [expr {$colNr-1}]]
+ }
+ if {$leftEdge eq ""} {
+ return
+ }
+ set rightEdge [calcTabLeftEdge $window $line $colNr]
+ if {$rightEdge ne ""} {
+ expr {$rightEdge - $leftEdge}
+ }
+}
+
+#
+# ::AdjustTabs::calcTabLeftEdge
+# return left edge of tab space in text window
+#
+proc ::AdjustTabs::calcTabLeftEdge {window line tabNr} {
+ set index [calcTabIndex $window $line $tabNr]
+ if {$index ne ""} {
+ let {x y w h} [$window bbox $index]
+ if {[info exists x]} {
+ set x
+ }
+ } elseif {[numOfTabsAtLine $window $line] == $tabNr} {
+ let {x y w h} [$window bbox $line.end]
+ if {[info exists x]} {
+ set x
+ }
+ }
+}
+
+#
+# ::AdjustTabs::calcTabRightEdge
+# return right edge of tab space in text window
+#
+proc ::AdjustTabs::calcTabRightEdge {window line tabNr} {
+ set index [calcTabIndex $window $line $tabNr]
+ if {$index ne ""} {
+ let {x y w h} [$window bbox $index]
+ if {[info exists x]} {
+ expr {$x + $w}
+ }
+ }
+}
+
+#
+# ::AdjustTabs::calcTabIndex
+# return widget index of tab $tabNr in line $line
+#
+proc ::AdjustTabs::calcTabIndex {window line tabNr {start 0}} {
+ set result\
+ [$window search \t "$line.0+$start chars" $line.0+1lines]
+ if {$tabNr == 0 || $result eq ""} {
+ set result
+ } else {
+ let {row col} [split $result .]
+ calcTabIndex $window $line [expr {$tabNr-1}] [incr col]
+ }
+}
+
+#
+# ::AdjustTabs::numOfTabsAtLine
+# return number of tabs contained in line
+#
+proc ::AdjustTabs::numOfTabsAtLine {window line} {
+ set str1 [$window get $line.0 $line.end]
+ set str2 [string map [list \t {}] $str1]
+ set l1 [string length $str1]
+ set l2 [string length $str2]
+ expr {$l1 - $l2}
+}
+
+namespace eval AdjustTabs {
+ namespace export\
+ checkTabEvent\
+ initTabTags
+}
+namespace import -force ::AdjustTabs::* \ No newline at end of file
diff --git a/support/dinbrief-gui/dinbrief.vfs/constants.tcl b/support/dinbrief-gui/dinbrief.vfs/constants.tcl
new file mode 100755
index 0000000000..29a120ac74
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.vfs/constants.tcl
@@ -0,0 +1,324 @@
+set documentPrefix {
+ \documentclass[12pt]{dinbrief}
+ \def\"#1{{\penalty10000\hskip 0pt plus 0pt\accent"7F\
+ #1\penalty10000\hskip 0pt plus 0pt}}
+ \def\logo#1{\noindent\hbox to 0pt{\vtop to 0pt{\raggedleft #1\vss}\hss}}
+ \def\euro{\penalty10000%
+ \hskip0.5pt\mbox{}%
+ \rlap{\hskip-0.5pt--}%
+ \rlap{\raise1.5pt\hbox{\hskip-0.5pt--}}%
+ C%
+ }
+ \def\pipe{\strut\penalty10000\hskip1pt\vrule\penalty10000\hskip1pt\relax}
+}
+
+set char2texTable [[lambda {l} {
+ # initialize ::html2tex::Char2texTable
+ set result {}
+ foreach {key val} $l {
+ lappend result [subst -nocommand -novariable $key] $val
+ }
+ # return this value
+ set result
+ }] {
+ | \\pipe{}
+ * {{*}}
+ - {{-}}
+ \u000c \\pagebreak{}
+ \u0022 \"{}
+ \u0023 {\#}
+ \u0025 {\%}
+ \u0026 {\&}
+ \u002f {\slash{}}
+ \u003c {$<$}
+ \u003d {\hskip 0pt plus 0pt\relax=\hskip 0pt plus 0pt\relax{}}
+ \u003e {$>$}
+ \u00a0 {~}
+ \u005b "{}\["
+ \u005c {\textbackslash{}}
+ \u005e {$\hat{~}$}
+ \u005d "{}\]"
+ \u005f {\strut\underline{~}}
+ \u007b {$\{$}
+ \u007d {$\}$}
+ \u00a1 {!`}
+ \u00a2 {$\not${c}}
+ \u00a3 {\pounds{}}
+ \u00a7 {\S{}}
+ \u00a8 {\"}
+ \u00a9 {\copyright{}}
+ \u00af {\={}}
+ \u00ac {$\neg$}
+ \u00ad {\-}
+ \u00b0 {$^\circ$}
+ \u00b1 {$\pm$}
+ \u00b2 {$^2$}
+ \u00b3 {$^3$}
+ \u00b4 {\'{}}
+ \u00b5 {$\mu$}
+ \u00b6 {\P{}}
+ \u00b7 {$\cdot$}
+ \u00b8 {\c{}}
+ \u00b9 {$^1$}
+ \u00bf {?`}
+ \u00c0 {\`A}
+ \u00c1 {\'A}
+ \u00c2 {\^A}
+ \u00c3 {\~A}
+ \u00c4 {\"A}
+ \u00c5 {\AA{}}
+ \u00c6 {\AE{}}
+ \u00c7 {\c{C}}
+ \u00c8 {\`E}
+ \u00c9 {\'E}
+ \u00ca {\^E}
+ \u00cb {\"E}
+ \u00cc {\`I}
+ \u00cd {\'I}
+ \u00ce {\^I}
+ \u00cf {\"I}
+ \u00d1 {\~N}
+ \u00d2 {\`O}
+ \u00d3 {\'O}
+ \u00d4 {\^O}
+ \u00d5 {\~O}
+ \u00d6 {\"O}
+ \u00d7 {$\times$}
+ \u00d8 {\O}
+ \u00d9 {\`U}
+ \u00da {\'U}
+ \u00db {\^U}
+ \u00dc {\"U}
+ \u00dd {\'Y}
+ \u00df {\ss{}}
+ \u00e0 {\`a}
+ \u00e1 {\'a}
+ \u00e2 {\^a}
+ \u00e3 {\~a}
+ \u00e4 {\"a}
+ \u00e5 {\aa{}}
+ \u00e6 {\ae{}}
+ \u00e7 {\c{c}}
+ \u00e8 {\`e}
+ \u00e9 {\'e}
+ \u00ea {\^e}
+ \u00eb {\"e}
+ \u00ec {\`\i{}}
+ \u00ed {\'\i{}}
+ \u00ee {\^\i{}}
+ \u00ef {\"\i{}}
+ \u00f1 {\~n}
+ \u00f2 {\`o}
+ \u00f3 {\'o}
+ \u00f4 {\^o}
+ \u00f5 {\~o}
+ \u00f6 {\"o}
+ \u00f7 {$\div$}
+ \u00f8 {\o{}}
+ \u00f9 {\`u}
+ \u00fa {\'u}
+ \u00fb {\^u}
+ \u00fc {\"u}
+ \u00fd {\'y}
+ \u00ff {\"y}
+ \u0100 {\=A}
+ \u0101 {\=a}
+ \u0102 {\u{A}}
+ \u0103 {\u{a}}
+ \u0104 {\c{A}}
+ \u0105 {\c{a}}
+ \u0106 {\'C}
+ \u0107 {\'c}
+ \u0108 {\^C}
+ \u0109 {\^c}
+ \u010a {\.C}
+ \u010b {\.c}
+ \u010c {\v{C}}
+ \u010d {\v{c}}
+ \u010e {\v{D}}
+ \u010f {\v{d}}
+ \u0112 {\=E}
+ \u0113 {\=e}
+ \u0114 {\u{E}}
+ \u0115 {\u{e}}
+ \u0116 {\.E}
+ \u0117 {\.e}
+ \u0118 {\c{E}}
+ \u0119 {\c{e}}
+ \u011a {\v{E}}
+ \u011b {\v{e}}
+ \u011c {\^G}
+ \u011d {\^g}
+ \u011e {\u{G}}
+ \u011f {\u{g}}
+ \u0120 {\.G}
+ \u0121 {\.g}
+ \u0122 {\c{G}}
+ \u0123 {\c{g}}
+ \u0124 {\^H}
+ \u0125 {\^h}
+ \u0128 {\~I}
+ \u0129 {\~\i{}}
+ \u012a {\=I}
+ \u012b {\=\i{}}
+ \u012c {\u{I}}
+ \u012d {\u\i{}}
+ \u012e {\c{I}}
+ \u012f {\c{i}}
+ \u0130 {\.I}
+ \u0131 {\i{}}
+ \u0132 IJ
+ \u0133 ij
+ \u0134 {\^J}
+ \u0135 {\^\j{}}
+ \u0136 {\c{K}}
+ \u0137 {\c{k}}
+ \u0139 {\'L}
+ \u013a {\'l}
+ \u013b {\c{L}}
+ \u013c {\c{l}}
+ \u013d {\v{L}}
+ \u013e {\v{l}}
+ \u0141 {\L{}}
+ \u0142 {\l{}}
+ \u0143 {\'N}
+ \u0144 {\'n}
+ \u0145 {\c{N}}
+ \u0146 {\c{n}}
+ \u0147 {\v{N}}
+ \u0148 {\v{n}}
+ \u014c {\=O}
+ \u014d {\=o}
+ \u014e {\u{O}}
+ \u014f {\u{o}}
+ \u0150 {\H{O}}
+ \u0151 {\H{o}}
+ \u0152 {\OE{}}
+ \u0153 {\oe{}}
+ \u0154 {\'R}
+ \u0155 {\'r}
+ \u0156 {\c{R}}
+ \u0157 {\c{r}}
+ \u0158 {\v{R}}
+ \u0159 {\v{r}}
+ \u015a {\'S}
+ \u015b {\'s}
+ \u015c {\^S}
+ \u015d {\^s}
+ \u015e {\c{S}}
+ \u015f {\c{s}}
+ \u0160 {\v{S}}
+ \u0161 {\v{s}}
+ \u0162 {\c{T}}
+ \u0163 {\c{t}}
+ \u0164 {\v{T}}
+ \u0165 {\v{t}}
+ \u0168 {\~U}
+ \u0169 {\~u}
+ \u016a {\=U}
+ \u016b {\=u}
+ \u016c {\u{U}}
+ \u016d {\u{u}}
+ \u016e {\r{U}}
+ \u016f {\r{u}}
+ \u0170 {\H{U}}
+ \u0171 {\H{u}}
+ \u0172 {\c{U}}
+ \u0173 {\c{u}}
+ \u0174 {\^W}
+ \u0175 {\^w}
+ \u0176 {\^Y}
+ \u0177 {\^y}
+ \u0178 {\"Y}
+ \u0179 {\'Z}
+ \u017a {\'Z}
+ \u017b {\.Z}
+ \u017c {\.Z}
+ \u017d {\v{Z}}
+ \u017e {\v{z}}
+ \u01c4 {D\v{Z}}
+ \u01c5 {D\v{z}}
+ \u01c6 {d\v{z}}
+ \u01c7 LJ
+ \u01c8 Lj
+ \u01c9 lj
+ \u01ca NJ
+ \u01cb Nj
+ \u01cc nj
+ \u01cd {\v{A}}
+ \u01ce {\v{a}}
+ \u01cf {\v{I}}
+ \u01d0 {\v\i{}}
+ \u01d1 {\v{O}}
+ \u01d2 {\v{o}}
+ \u01d3 {\v{U}}
+ \u01d4 {\v{u}}
+ \u01e6 {\v{G}}
+ \u01e7 {\v{g}}
+ \u01e8 {\v{K}}
+ \u01e9 {\v{k}}
+ \u01ea {\c{O}}
+ \u01eb {\c{o}}
+ \u01f0 {\v\j{}}
+ \u01f1 DZ
+ \u01f2 Dz
+ \u01f3 dz
+ \u01f4 {\'G}
+ \u01f5 {\'g}
+ \u01fc {\'\AE{}}
+ \u01fd {\'\ae{}}
+ \u01fe {\'\O{}}
+ \u01ff {\'\o{}}
+ \u02c6 {\^{}}
+ \u02dc {\~{}}
+ \u02d8 {\u{}}
+ \u02d9 {\.{}}
+ \u02da {\r{}}
+ \u02dd {\H{}}
+ \u02db {\c{}}
+ \u02c7 {\v{}}
+ \u03c0 {$\pi$}
+ \ufb01 fi
+ \ufb02 fl
+ \u2002 {\hskip 0pt plus 0pt\relax{}}
+ \u2013 {--}
+ \u2014 {---}
+ \u2018 {`}
+ \u2019 {\grq{}}
+ \u201a {\glq{}}
+ \u201c {``}
+ \u201d {\grqq}
+ \u201e {\glqq{}}
+ \u2020 {\dag{}}
+ \u2021 {\ddag{}}
+ \u2122 {$^\mbox{\tiny TM}$}
+ \u2022 {$\bullet$}
+ \u2026 {$\ldots$}
+
+ \u20ac {\euro{}}
+
+ \u2190 {$\leftarrow$}
+ \u2191 {$\uparrow$}
+ \u2192 {$\rightarrow$}
+ \u2193 {$\downarrow$}
+ \u2196 {$\leftrightarrow$}
+
+ \u21b5 {$\hookleftarrow$}
+
+ \u21d0 {$\Leftarrow$}
+ \u21d1 {$\Uparrow$}
+ \u21d2 {$\Rightarrow$}
+ \u21d3 {$\Downarrow$}
+ \u21d6 {$\Leftrightarrow$}
+
+ \u2202 {$\partial$}
+ \u220f {$\prod$}
+ \u2211 {$\sum$}
+ \u221a {$\surd$}
+ \u221e {$\infty$}
+ \u222b {$\int$}
+ \u2248 {$\approx$}
+ \u2260 {$\neq$}
+ \u2264 {$\leq$}
+ \u2265 {$\geq$}
+ }]
diff --git a/support/dinbrief-gui/dinbrief.vfs/dinbrief.tcl b/support/dinbrief-gui/dinbrief.vfs/dinbrief.tcl
new file mode 100755
index 0000000000..0c3d6bd948
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.vfs/dinbrief.tcl
@@ -0,0 +1,240 @@
+proc connectByTab {field1 field2 args} {
+ set code [lambda {entry} {
+ focus -force $entry
+ }]
+ bind $field1 <Tab> [list $code $field2]
+ bind $field1 <Tab> +break
+ bind $field2 <Shift-Tab> [list $code $field1]
+ bind $field2 <Shift-Tab> +break
+ if {[llength $args] > 0} {
+ eval connectByTab $field2 $args
+ }
+}
+
+proc dinbrief {} {
+ grid\
+ [label .addresslabel -text Absender]\
+ [scrolledrichtext .address -height 3 -width 25]\
+ [label .phonelabel -text Telefon]\
+ [entry .phone]\
+ -sticky ne
+ connectByTab .address .phone
+ grid ^ ^\
+ [label .placelabel -text Ort]\
+ [entry .place]\
+ -sticky se
+ grid ^ ^\
+ [label .datelabel -text Datum]\
+ [entry .date]\
+ -sticky se
+ grid \
+ [label .backaddresslabel -text Absenderzeile]\
+ [entry .backaddress] - -\
+ -sticky ne
+ grid\
+ [label .tolabel -text Empfänger]\
+ [scrolledrichtext .to -height 4 -width 25]\
+ [label .signlabel -text Zeichen]\
+ [entry .sign]\
+ -sticky ne
+ connectByTab .backaddress .to .sign
+ grid ^ ^\
+ [label .writerlabel -text Sachbearbeiter]\
+ [entry .writer]\
+ -sticky ne
+ grid ^ ^\
+ [label .yourmaillabel -text {Ihr Zeichen}]\
+ [entry .yourmail]\
+ -sticky se
+ grid\
+ [label .subjectlabel -text Betreff]\
+ [entry .subject] - -\
+ -sticky ne
+ grid\
+ [label .openinglabel -text Anrede]\
+ [entry .opening] - -\
+ -sticky ne
+ grid [scrolledrichtext .maintext -width 40 -height 10] - - - -sticky news
+ grid rowconfigure . 9 -weight 1
+ grid\
+ [label .closinglabel -text Grußformel]\
+ [entry .closing]\
+ [label .pslabel -text PS]\
+ [scrolledrichtext .ps -width 40 -height 4]\
+ -sticky ne
+ grid\
+ [label .signaturelabel -text Unterschrift]\
+ [entry .signature] ^ ^\
+ -sticky ne
+ grid\
+ [label .cclabel -text {Kopie an}]\
+ [entry .cc] ^ ^\
+ -sticky ne
+ grid\
+ [label .encllabel -text Anlage]\
+ [entry .encl] ^ ^\
+ -sticky ne
+ grid\
+ [label .bottomtextlabel -text Gesellschaft]\
+ [scrolledtext .bottomtext -height 2] - -\
+ -sticky ne
+ label .searchStringLabel -text Suche
+ label .searchString -textvariable ::searchText::searchString -relief sunken
+ grid configure .bottomtext -sticky news
+ grid columnconfigure . 3 -weight 1
+ grid configure\
+ .address .backaddress .to .yourmail .writer .sign\
+ .phone .place .date .subject .opening .maintext\
+ .closing .signature .cc .encl .ps .bottomtext\
+ -sticky news
+ .maintext tag configure tab -wrap none
+ focus .maintext.text
+ bind .maintext.text <Key> "after idle {checkTabEvent .maintext}"
+ bind .maintext.text <<Undo>> "after idle {initTabTags .maintext}"
+ bind .maintext.text <<Redo>> "after idle {initTabTags .maintext}"
+ bind .maintext.text <<Change>> "after idle {initTabTags .maintext}"
+ bind .maintext.text <F3> {searchMode .maintext}
+ bind .maintext.text <FocusIn> {
+ switchMenuEdit normal 0 1 2 4 5 7 8 9
+ break
+ }
+}
+
+proc entry2macro {name {default {}}} {
+ set field .[string tolower $name]
+ set macro \\$name
+ set contents ""
+ switch [winfo class $field] {
+ Text - Scrolledtext - Richtext - Scrolledrichtext {
+ set contents [hyphenated [unicode2tex [$field get 1.0 end-1chars]]]
+ }
+ Entry {
+ set contents [hyphenated [unicode2tex [$field get]]]
+ }
+ }
+ if {$contents ne ""} {
+ set result \n$macro
+ append result \{ $contents \} \n
+ } elseif {$default ne ""} {
+ set result \n$macro
+ append result \{ $default \} \n
+ }
+}
+
+proc formular2tex {} {
+ global documentPrefix
+ set result [string trim $documentPrefix]
+ if {[file exists preamble.inc.tex]} {
+ append result \n [cat preamble.inc.tex] \n
+ }
+ append result \\usepackage\[ [globalSetting language] \] \{ babel \}
+ append result \n\
+ [globalSetting verticalAddressAlign] \n\
+ [globalSetting addressRules] \n\
+ [globalSetting backAddressRules] \n\
+ [globalSetting paperFoldMarks] \n\
+ [globalSetting addressPos] \n
+ if { "[.yourmail get][.sign get][.writer get]" ne ""} {
+ set refLineGiven 1
+ set refLineDefault \\mbox{}
+ } else {
+ set refLineGiven 0
+ set refLineDefault ""
+ }
+ foreach field {
+ address backaddress place date subject signature bottomtext
+ } {
+ append result [entry2macro $field]
+ }
+ foreach field {
+ yourmail writer sign
+ } {
+ append result [entry2macro $field $refLineDefault]
+ }
+ set phoneFrags [split [.phone get] " /-"]
+ set phone0 [lindex $phoneFrags 0]
+ set phoneRest [join [lrange $phoneFrags 1 end] -]
+ append result \\phone\
+ \{ [unicode2tex $phone0] \}\
+ \{ [unicode2tex $phoneRest] \}
+ #
+ append result \n\
+ "\\begin{document}\n"\
+ "\\begin{letter}"\
+ \{ [unicode2tex [.to get 1.0 end-1chars]] \}
+ if {[file exists document.inc.tex]} {
+ append result \n [cat document.inc.tex] \n
+ }
+ if {$refLineGiven && [globalSetting refLineOverFold]} {
+ # append result \n \\setupperfoldmarkvpos{108mm}
+ switch [globalSetting addressPos] {
+ \\addresshigh {
+ append result \n \\setreflinetop{78.5mm}
+ }
+ default {
+ append result \n \\setreflinetop{96.5mm}
+ }
+ }
+ }
+ append result \n\
+ [entry2macro opening]\
+ [plaintext2tex [.maintext get 1.0 end]]\
+ [entry2macro closing]\
+ [entry2macro ps]\
+ [entry2macro cc]\
+ [entry2macro encl]\
+ "\n\n\\end{letter}\n\\end{document}"
+}
+
+proc getContents {} {
+ set result {}
+ foreach entry [winfo children .] {
+ switch [winfo class $entry] {
+ Text - Scrolledtext - Richtext - Scrolledrichtext {
+ lappend result $entry\
+ [unicode2asciiEncoded [$entry get 1.0 end-1chars]]
+ }
+ Entry {
+ lappend result $entry [unicode2asciiEncoded [$entry get]]
+ }
+ }
+ }
+ # return this value
+ set result
+}
+
+proc saveContents {file} {
+ saveString [getContents] $file
+}
+
+proc putContents {contents} {
+ foreach {entry rawValue} $contents {
+ set value [subst -nocommand -novariable $rawValue]
+ switch [winfo class $entry] {
+ Entry {
+ $entry delete 0 end
+ $entry insert end $value
+ }
+ Text - Scrolledtext - Richtext - Scrolledrichtext {
+ $entry delete 1.0 end
+ $entry insert end $value
+ }
+ }
+ }
+}
+
+proc loadContents {file} {
+ putContents [cat $file]
+}
+
+proc setFontSize n {
+ globalSetting fontSize $n
+ foreach child [winfo children .] {
+ switch [winfo class $child] {
+ Label - Entry - Text - Richtext - Scrolledtext - Scrolledrichtext {
+ $child configure -font "Helvetica $n"
+ }
+ }
+ }
+ option add *Text.font [list Helvetica $n]
+}
diff --git a/support/dinbrief-gui/dinbrief.vfs/hyphen.tcl b/support/dinbrief-gui/dinbrief.vfs/hyphen.tcl
new file mode 100755
index 0000000000..1e1deb1720
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.vfs/hyphen.tcl
@@ -0,0 +1,92 @@
+namespace eval global {
+ variable hyphenFile [file join $defaultDir hyphen.txt]
+ array set hyphen {}
+}
+
+proc global::loadHyphenation {} {
+ variable hyphenFile
+ variable hyphen
+ if {[file exists $hyphenFile]} {
+ array unset hyphen
+ array set hyphen [[lambda {file} {
+ set result {}
+ foreach name [cat $file] {
+ lappend result [string map {- {}} $name] $name
+ }
+ set result
+ }] $hyphenFile]
+ }
+}
+
+namespace eval global {
+ namespace export loadHyphenation
+}
+
+namespace import -force global::loadHyphenation
+
+after idle loadHyphenation
+
+proc global::hyphenWordPattern {word pattern} {
+ set fragList [split $pattern -]
+ set endIndex -1
+ set startIndex 0
+ set result {}
+ foreach frag $fragList {
+ set l [string length $frag]
+ incr endIndex $l
+ lappend result [string range $word $startIndex $endIndex]
+ incr startIndex $l
+ }
+ join $result \u00ad
+}
+
+proc global::hyphenated {l} {
+ set words [regexp -inline -all {[[:alnum:]]+} $l]
+ set puncts [regexp -inline -all {[^[:alnum:]]+} $l]
+ if {[regexp {[^[:alnum:]]} [string index $l 0]]} {
+ set words [concat [list ""] $words]
+ }
+ set result ""
+ variable hyphen
+ foreach word $words punct $puncts {
+ set word_ [string tolower $word]
+ if {[info exists hyphen($word_)]} {
+ append result [hyphenWordPattern $word $hyphen($word_)]
+ } else {
+ append result $word
+ }
+ append result $punct
+ }
+ set result
+}
+
+proc global::editHyphenations {} {
+ variable hyphenFile
+ if {[winfo exists .hyphenation]} {
+ raise .hyphenation
+ focus -force .hyphenation
+ return
+ }
+ toplevel .hyphenation
+ wm title .hyphenation Silbentrennung
+ wm transient .hyphenation .
+ pack [scrolledtext .hyphenation.editor -width 30] -expand yes -fill both
+ variable hyphenFile
+ if {[file exists $hyphenFile]} {
+ .hyphenation.editor insert end\
+ [join [lsort [string tolower [cat $hyphenFile]]] \n]
+ }
+ wm protocol .hyphenation WM_DELETE_WINDOW [subst -nocommand {
+ saveString [.hyphenation.editor get 1.0 end-1chars] $hyphenFile
+ destroy .hyphenation
+ loadHyphenation
+ }]
+}
+
+namespace eval global {
+ namespace export hyphenated editHyphenations
+}
+
+namespace import -force\
+ global::hyphenated\
+ global::editHyphenations \ No newline at end of file
diff --git a/support/dinbrief-gui/dinbrief.vfs/main.tcl b/support/dinbrief-gui/dinbrief.vfs/main.tcl
new file mode 100755
index 0000000000..228b9d50bf
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.vfs/main.tcl
@@ -0,0 +1,14 @@
+package require Tk
+
+source [file join [file dirname [info script]] util.tcl]
+source [file join [file dirname [info script]] constants.tcl]
+source [file join [file dirname [info script]] richtext.tcl]
+source [file join [file dirname [info script]] menu.tcl]
+source [file join [file dirname [info script]] hyphen.tcl]
+source [file join [file dirname [info script]] tabs2tex.tcl]
+source [file join [file dirname [info script]] numbering.tcl]
+source [file join [file dirname [info script]] adjustTabs.tcl]
+source [file join [file dirname [info script]] searchText.tcl]
+source [file join [file dirname [info script]] dinbrief.tcl]
+
+dinbrief
diff --git a/support/dinbrief-gui/dinbrief.vfs/menu.tcl b/support/dinbrief-gui/dinbrief.vfs/menu.tcl
new file mode 100755
index 0000000000..7b375af26f
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.vfs/menu.tcl
@@ -0,0 +1,621 @@
+if {[winfo exists .menu]} {
+ destroy .menu
+}
+
+# set currentFile ""
+
+namespace eval global {
+ array set value {
+ file ""
+ justOpened no
+ fontSize 9
+ verticalAddressAlign \\centeraddress
+ addressRules \\windowrules
+ backAddressRules \\backaddressrule
+ paperFoldMarks \\windowtics
+ pdflatex pdflatex
+ pdfViewer xpdf
+ smartQuotes C
+ list-O-matic deep
+ numberAlign right
+ ... \\ldots
+ windowGeometry 550x550+20+20
+ language ngerman
+ refLineOverFold 1
+ addressPos \\addressstd
+ 1000.dezimal, {. ,}
+ lastSearchString ""
+ }
+ variable defaultDir\
+ [file dirname [file dirname [file normalize [info script]]]]
+ after idle [list cd $defaultDir]
+ variable valueFile [file join $defaultDir global.vars]
+ set value(defaultFile) [file join $defaultDir default.dinbrief]
+ if {[file exists $valueFile]} {
+ array set value [cat $valueFile]
+ }
+ wm geometry . $value(windowGeometry)
+ option add *Entry.font "Helvetica $value(fontSize)"
+ option add *Label.font "Helvetica $value(fontSize)"
+ option add *Button.font "Helvetica $value(fontSize)"
+ option add *Menubutton.font "Helvetica $value(fontSize)"
+ option add *Checkbutton.font "Helvetica $value(fontSize)"
+ option add *Labelframe.font "Helvetica $value(fontSize)"
+ option add *Text.font "Helvetica $value(fontSize)"
+}
+
+
+
+proc global::globalSetting {args} {
+ variable value
+ if {[llength $args] > 1} {
+ array set value $args
+ } elseif {[llength $args] == 0} {
+ array get value
+ } else {
+ set value([lindex $args 0])
+ }
+}
+
+proc global::storeGlobalSettings {} {
+ variable value
+ variable valueFile
+ globalSetting windowGeometry [wm geometry .]
+ saveString [array get value] $valueFile
+}
+
+namespace eval global {
+ namespace export *
+}
+
+namespace import -force global::*
+
+after idle {::Richtext::setQuotes [globalSetting smartQuotes]}
+
+wm protocol . WM_DELETE_WINDOW {
+ .menu.file invoke Ende
+}
+
+[menu .menu] add cascade\
+ -label Datei\
+ -menu [menu .menu.file -tearoff 0]
+
+.menu.file add command\
+ -label Neu\
+ -command [lambda {} {
+ . configure -cursor watch
+ update
+ set defaultFile [globalSetting defaultFile]
+ set failure 0
+ if {[file exists $defaultFile]} {
+ if {[catch {
+ putContents [cat $defaultFile]
+ } err]} {
+ set failure 1
+ }
+ } else {
+ set failure 1
+ }
+ if {$failure} {
+ foreach entry [winfo children .] {
+ switch [winfo class $entry] {
+ Entry {
+ $entry delete 0 end
+ }
+ Text - Richtext - Scrolledtext - Scrolledrichtext {
+ $entry delete 1.0 end
+ }
+ }
+ }
+ }
+ wm title . "DIN-Brief"
+ globalSetting file ""
+ . configure -cursor ""
+ }]
+
+.menu.file add command\
+ -label {Öffnen ...}\
+ -command [lambda {} {
+ set f [tk_getOpenFile -filetypes {
+ {{DIN-Brief} {.dinbrief .DIN-Brief}}
+ {{Alle} *}
+ }]
+ if {$f ne ""} {
+ loadContents $f
+ # globalSetting file [file normalize $f]
+ globalSetting file [relPathFromTo [pwd] $f]
+ wm title . "DIN-Brief: [file rootname [file tail $f]]"
+ globalSetting justOpened yes
+ } else {
+ globalSetting justOpened no
+ }
+ after idle [list initTabTags .maintext]
+ }]
+
+.menu.file add command\
+ -label {Erneut öffnen}\
+ -command [lambda {} {
+ set currentFile [globalSetting file]
+ if {$currentFile eq ""} {
+ .menu.file invoke Neu
+ } else {
+ loadContents $currentFile
+ wm title . "DIN-Brief: [file rootname [file tail $currentFile]]"
+ after idle [list initTabTags .maintext]
+ }
+ }]
+
+after idle [list .menu.file invoke {Erneut öffnen}]
+
+.menu.file add command\
+ -label {Öffnen als Vorlage ...}\
+ -command [lambda {} {
+ .menu.file invoke {Öffnen ...}
+ if {[globalSetting justOpened]} {
+ globalSetting file ""
+ wm title . Din-Brief
+ }
+ }]
+
+.menu.file add separator
+
+.menu.file add command\
+ -label Speichern\
+ -command [lambda {} {
+ . configure -cursor watch
+ update
+ set currentFile [globalSetting file]
+ if {$currentFile ne ""} {
+ saveContents $currentFile
+ wm title . "DIN-Brief: [file rootname [file tail $currentFile]]"
+ } else {
+ .menu.file invoke {Speichern als ...}
+ }
+ . configure -cursor ""
+ }]
+
+.menu.file add command\
+ -label {Speichern als ...}\
+ -command [lambda {} {
+ . configure -cursor watch
+ update
+ set f [tk_getSaveFile\
+ -defaultextension .dinbrief\
+ -filetypes {
+ {{DIN-Brief}
+ {.dinbrief .DIN-Brief}}
+ {{Alle}
+ *}
+ }]
+ if {$f ne ""} {
+ saveContents $f
+ globalSetting file [file normalize $f]
+ wm title . "DIN-Brief: [file rootname [file tail $f]]"
+ }
+ . configure -cursor ""
+ }]
+
+.menu.file add command\
+ -label {Speichern als Default-Brief}\
+ -command [lambda {} {
+ . configure -cursor watch
+ update
+ set defaultFile [globalSetting defaultFile]
+ saveContents $defaultFile
+ globalSetting file ""
+ wm title . DIN-Brief
+ . configure -cursor ""
+ }]
+
+.menu.file add separator
+
+.menu.file add command\
+ -label {Export nach LaTeX}\
+ -command [lambda {} {
+ . configure -cursor watch
+ update
+ set currentFile [globalSetting file]
+ if {$currentFile eq ""} {
+ set f default
+ } else {
+ set workingDir [file dirname $currentFile]
+ set workingFile [string map {" " _} [file tail $currentFile]]
+ set f [file join $workingDir [file rootname $workingFile]]
+ }
+ saveString [formular2tex] $f.tex
+ . configure -cursor ""
+ }]
+
+.menu.file add command\
+ -label {Export nach PDF}\
+ -command [lambda {} {
+ set currentFile [globalSetting file]
+ .menu.file invoke {Export nach LaTeX}
+ if {$currentFile eq ""} {
+ set rootname default
+ } else {
+# set workingDir [file dirname $currentFile]
+# set workingFile [string map {" " _} [file tail $currentFile]]
+# set rootname\
+# [file join $workingDir [file rootname $workingFile]]
+ set rootname [string map {" " _} [file rootname $currentFile]]
+ }
+ if {![file executable [globalSetting pdflatex]]} {
+ .menu.external invoke {Pfad von pdflatex}
+ } else {
+ globalSetting justOpened yes
+ }
+ if {[globalSetting justOpened]} {
+ set cmd [list\
+ exec [globalSetting pdflatex]\
+ --interaction nonstopmode\
+ $rootname.tex]
+ if {[catch $cmd err]} {
+ puts $err
+ echo But don't worry,\
+ possibly just changed language,\
+ just another try ...
+ eval $cmd
+ }
+ }
+ }]
+
+.menu.file add separator
+
+.menu.file add command\
+ -label Ende\
+ -command {
+ if {[globalSetting file] ne ""} {
+ .menu.file invoke Speichern
+ }
+ storeGlobalSettings
+ exit
+ }
+
+.menu add cascade\
+ -label Bearbeiten\
+ -menu [menu .menu.edit -tearoff no]
+
+.menu.edit add command\
+ -label Ausschneiden\
+ -command {
+ event generate [focus] <<Cut>>
+ event generate [focus] <<Change>>
+ }\
+ -accelerator Ctrl-x
+
+.menu.edit add command\
+ -label Kopieren\
+ -command {
+ event generate [focus] <<Copy>>
+ }\
+ -accelerator Ctrl-c
+
+.menu.edit add command\
+ -label Einfügen\
+ -command {
+ event generate [focus] <<Paste>>
+ event generate [focus] <<Change>>
+ }\
+ -accelerator Ctrl-v
+
+.menu.edit add separator
+
+.menu.edit add command\
+ -label "Datum ([clock format [clock seconds] -format {%d.%m.%y}])"\
+ -command [lambda {} {
+ set window [focus]
+ switch [winfo class $window] {
+ Text - Richtext - Scrolledtext - Scrolledrichtext {
+ foreach {to from} [lreverse [$window tag ranges sel]] {
+ $window delete $from $to
+ }
+ $window insert insert\
+ [clock format [clock seconds] -format {%d.%m.%y}]
+ }
+ Entry {
+ catch {
+ $window delete sel.first sel.last
+ }
+ $window insert insert\
+ [clock format [clock seconds] -format {%d.%m.%y}]
+ }
+ }
+ }]
+
+.menu.edit add command\
+ -label Seitenwechsel\
+ -command {tk::TextInsert [focus] \n\u000c\n}\
+ -accelerator Ctrl-l
+
+.menu.edit add separator
+
+.menu.edit add command\
+ -label Suche\
+ -command {
+ focus .maintext.text
+ after idle {
+ toggleSearchMode .maintext
+ }
+ }\
+ -accelerator F3
+
+.menu.edit add command\
+ -label Rückgängig\
+ -command {
+ event generate [focus] <<Undo>>
+ }\
+ -accelerator Ctrl-z
+
+.menu.edit add command\
+ -label Wiederholen\
+ -command {
+ event generate [focus] <<Redo>>
+ }\
+ -accelerator Ctrl-y
+
+proc switchMenuEdit {state args} {
+ foreach i $args {
+ .menu.edit entryconfigure $i -state $state
+ }
+}
+
+bind Entry <FocusIn> {
+ switchMenuEdit normal 0 1 2 4 5 7 8 9
+ switchMenuEdit disabled 5 7 8 9
+}
+
+bind Richtext <FocusIn> {
+ switchMenuEdit normal 0 1 2 4 5 7 8 9
+ switchMenuEdit disabled 5 7
+}
+
+bind Richtext <Button-3> {
+ focus %W
+ tk_popup .menu.edit %X %Y
+}
+
+menu .menu.editEntry -tearoff 0
+
+[lambda {menu1 menu2 args} {
+ foreach i $args {
+ $menu2 add command\
+ -label [$menu1 entrycget $i -label]\
+ -command [$menu1 entrycget $i -command]
+ }
+}] .menu.edit .menu.editEntry 0 1 2 4
+
+bind Entry <Button-3> {
+ focus %W
+ tk_popup .menu.editEntry %X %Y
+}
+
+.menu add cascade\
+ -label Ansicht\
+ -menu [menu .menu.view -tearoff no]
+
+.menu.view add cascade\
+ -label Schriftgröße\
+ -menu [menu .menu.view.fontsize]
+
+foreach i {9 10 11 12 13 14 15} {
+ .menu.view.fontsize add radiobutton\
+ -label $i\
+ -variable ::global::value(fontSize)\
+ -command [list setFontSize $i]
+}
+
+.menu.view add separator
+
+.menu.view add command\
+ -label Vorschau\
+ -command [lambda {} {
+ set currentFile [globalSetting file]
+ .menu.file invoke {Export nach PDF}
+ if {[globalSetting justOpened]} {
+ if {$currentFile eq ""} {
+ set rootname default
+ } else {
+# set dirname [file dirname $currentFile]
+# set tailname [string map {" " _} [file tail $currentFile]]
+# set rootname [file rootname $dirname/$tailname]
+ set rootname [string map {" " _} [file rootname $currentFile]]
+ }
+ if {![file executable [globalSetting pdfViewer]]} {
+ .menu.external invoke {PDF-Betrachter}
+ }
+ if {[globalSetting justOpened]} {
+ exec [globalSetting pdfViewer] $rootname.pdf
+ }
+ }
+ }]
+
+.menu add cascade -label Einstellungen -menu [menu .menu.settings]
+
+.menu.settings add checkbutton\
+ -label {Typografischer Gedankenstrich}\
+ -variable ::Richtext::typoDashRequired\
+
+.menu.settings add cascade\
+ -label {Anführungszeichen}\
+ -menu [menu .menu.settings.smartquotes]
+
+.menu.settings.smartquotes add radiobutton\
+ -label Schreibmaschine\
+ -command [list ::Richtext::setQuotes C]\
+ -variable ::global::value(smartQuotes)\
+ -value C
+
+.menu.settings.smartquotes add radiobutton\
+ -label Deutsch\
+ -command [list ::Richtext::setQuotes de]\
+ -variable ::global::value(smartQuotes)\
+ -value de
+
+.menu.settings.smartquotes add radiobutton\
+ -label Englisch\
+ -command [list ::Richtext::setQuotes en]\
+ -variable ::global::value(smartQuotes)\
+ -value en
+
+.menu.settings.smartquotes add radiobutton\
+ -label Französisch\
+ -command [list ::Richtext::setQuotes fr]\
+ -variable ::global::value(smartQuotes)\
+ -value fr
+
+.menu.settings.smartquotes add radiobutton\
+ -label Schweiz\
+ -command [list ::Richtext::setQuotes ch]\
+ -variable ::global::value(smartQuotes)\
+ -value ch
+
+.menu.settings add cascade\
+ -label {Typografische Zeichenersetzung}\
+ -menu [menu .menu.settings.typographicalChars -tearoff 0]
+
+.menu.settings.typographicalChars add checkbutton\
+ -label {Punkte (...)}\
+ -variable ::global::value(...)\
+ -onvalue \\ldots\
+ -offvalue ...
+
+.menu.settings add separator
+
+.menu.settings add checkbutton\
+ -label {Absenderzeile mit Unterstrich}\
+ -variable ::global::value(backAddressRules)\
+ -onvalue \\backaddressrule\
+ -offvalue \\nobackaddressrule
+
+.menu.settings add checkbutton\
+ -label {Adressfeld mit Strichen umrandet}\
+ -variable ::global::value(addressRules)\
+ -onvalue \\windowrules\
+ -offvalue \\nowindowrules
+
+.menu.settings add checkbutton\
+ -label {Adressfeld vertikal zentriert}\
+ -variable ::global::value(verticalAddressAlign)\
+ -onvalue \\centeraddress\
+ -offvalue \\normaladdress
+
+.menu.settings add checkbutton\
+ -label {Nutztext verlängert}\
+ -variable ::global::value(addressPos)\
+ -onvalue \\addresshigh\
+ -offvalue \\addressstd
+
+.menu.settings add checkbutton\
+ -label {Falzmarkierungen}\
+ -variable ::global::value(paperFoldMarks)\
+ -onvalue \\windowtics\
+ -offvalue \\nowindowtics
+
+.menu.settings add checkbutton\
+ -label {Bezugszeile immer über dem Falz}\
+ -variable ::global::value(refLineOverFold)
+
+.menu.settings add separator
+
+.menu.settings add checkbutton\
+ -label {Zahlenspalten rechts- bzw. kommabündig}\
+ -variable ::global::value(numberAlign)\
+ -onvalue right\
+ -offvalue left
+
+.menu.settings add checkbutton\
+ -label {Deutsches Dezimalkomma}\
+ -variable ::global::value(1000.dezimal,)\
+ -onvalue {. ,}\
+ -offvalue {, .}
+
+.menu.settings add separator
+
+.menu.settings add cascade\
+ -label Listenformat\
+ -menu [menu .menu.settings.listOmatic -tearoff 0]
+
+.menu.settings.listOmatic add radiobutton\
+ -label Aus\
+ -variable ::global::value(list-O-matic)\
+ -value none
+
+.menu.settings.listOmatic add radiobutton\
+ -label Einfach\
+ -variable ::global::value(list-O-matic)\
+ -value flat
+
+.menu.settings.listOmatic add radiobutton\
+ -label Verschachtelt\
+ -variable ::global::value(list-O-matic)\
+ -value deep
+
+.menu.settings add cascade\
+ -label {Silbentrennung Sprache}\
+ -menu [menu .menu.settings.lang -tearoff 0]
+
+[lambda {list} {
+ foreach {lang label} $list {
+ .menu.settings.lang add radiobutton\
+ -label $label\
+ -value $lang\
+ -variable ::global::value(language)
+ }
+}] {
+ ngerman Deutsch
+ UKenglish {Englisch (Vereinigtes Königreich)}
+ USenglish {Englisch (Vereinigte Staaten)}
+ francais Französisch
+ italian Italienisch
+ spanish Spanisch
+ portuges Portugiesisch
+ swedish Schwedisch
+ polish Polnisch
+ esperanto Esperanto
+ german {Deutsch (Alte Rechtschreibung)}
+}
+
+.menu.settings add command\
+ -label {Silbentrennung Ausnahmen ...}\
+ -command editHyphenations
+
+.menu add cascade\
+ -label {Externe Hilfsprogramme}\
+ -menu [menu .menu.external]
+
+.menu.external add command\
+ -label {Pfad von pdflatex}\
+ -command [lambda {} {
+ globalSetting pdflatex\
+ [tk_getOpenFile -title "Genauer Pfad für PDFlatex"]
+ if {[file executable [globalSetting pdflatex]]} {
+ globalSetting justOpened yes
+ } else {
+ globalSetting justOpened no
+ }
+ }]
+
+.menu.external add command\
+ -label {PDF-Betrachter}\
+ -command [lambda {} {
+ globalSetting pdfViewer\
+ [tk_getOpenFile -title {PDF-Betrachter auswählen}]
+ if {[file executable [globalSetting pdfViewer]]} {
+ globalSetting justOpened yes
+ } else {
+ globalSetting justOpened no
+ }
+ }]
+
+.menu add cascade -label ? -menu [menu .menu.help -tearoff 0]
+
+.menu.help add command\
+ -label "Über dinbrief"\
+ -command {
+ tk_dialog .info Info\
+ "dinbrief V.1.0\n(c) 2005 Wolf-Dieter Busch"\
+ info 0 Ok
+ }
+
+. configure -menu .menu
diff --git a/support/dinbrief-gui/dinbrief.vfs/numbering.tcl b/support/dinbrief-gui/dinbrief.vfs/numbering.tcl
new file mode 100755
index 0000000000..d5262b2c5e
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.vfs/numbering.tcl
@@ -0,0 +1,201 @@
+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::*
diff --git a/support/dinbrief-gui/dinbrief.vfs/richtext.tcl b/support/dinbrief-gui/dinbrief.vfs/richtext.tcl
new file mode 100755
index 0000000000..5a73cd9ed2
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.vfs/richtext.tcl
@@ -0,0 +1,579 @@
+#####################################################
+# proc richtext pathname [-option value ...]
+#
+# builds a text widget with word processing capability
+# i. e. wrap word, cursor up/down by displayed line.
+#
+# Usage:
+# richtext .wp ? option value ? ...
+# produces a widget with certain WP abilities:
+#
+# Cursor navigates as expected by some DAU even if line is wrapped.
+# Smart quotes: none, de, en ... (switchable).
+# Typographical dashes by key sequences -- and --- (switchable).
+# Triple-click selects grammatical sentence.
+# Quadruple-click selects logical line (= paragraph)
+#
+# ::Richtext::requireTypoDash ? (1 | 0) ?
+# switches double & triple key minus to produce typographical dashes
+#
+# ::Richtext::setQuotes ? (de | en | fr | ch | C) ?
+# switches keys \" and \' to produce national "smart" quotes
+# or just \" if lang is C (which is default).
+#
+# 2003-03-13 Wolf Busch, Oberkleen
+######################################################
+
+namespace eval Richtext {
+ namespace export richtext
+ array set object {}
+ variable quoteMode C
+ variable doubleQuotes [list \" \"]
+ variable singleQuotes [list ' ']
+ variable typoDashRequired 1
+ variable actualWindow {}
+ variable actualObject {}
+}
+
+proc ::Richtext::richtext {widget {objectName {}}} {
+ variable object
+ eval text $widget -wrap word
+ if {$objectName ne {}} {
+ set object($widget) $objectName
+ }
+ set taglist {}
+ foreach tag [bindtags $widget] {
+ if {$tag eq "Text"} {
+ # lappend taglist Beforetext Richtext Aftertext
+ lappend taglist Richtext
+ } else {
+ lappend taglist $tag
+ }
+ }
+ bindtags $widget $taglist
+ $widget configure -cursor ""
+ return $widget
+}
+
+proc ::Richtext::unselectTablePartiallySelected {text} {
+ if {[$text tag ranges sel] ne {}} {
+ foreach {from to} [$text tag ranges blockobject] {
+ if {[$text compare $from < sel.first] &&\
+ [$text compare $to > sel.first]} {
+ $text tag remove sel sel.first $to
+ if {[$text compare insert < $to]} {
+ $text mark set insert $to
+ }
+ if {[$text tag ranges sel] eq {}} {
+ break
+ }
+ }
+ if {[$text compare $to > sel.last] &&\
+ [$text compare $from < sel.last]} {
+ $text tag remove sel $from-1chars sel.last
+ if {[$text compare insert > $from-1chars]} {
+ $text mark set insert $from-1chars
+ }
+ if {[$text tag ranges sel] eq {}} {
+ break
+ }
+ }
+ }
+ }
+}
+
+proc ::Richtext::TextInsert {w s} {
+ variable object
+ if {[string equal $s ""] ||\
+ [string equal [$w cget -state] "disabled"]} {
+ return
+ }
+ set compound 0
+ catch {
+ if {[$w compare sel.first <= insert] &&\
+ [$w compare sel.last >= insert]} {
+ set oldSeparator [$w cget -autoseparators]
+ if { $oldSeparator } {
+ $w configure -autoseparators 0
+ $w edit separator
+ set compound 1
+ }
+ unselectTablePartiallySelected $w
+ $w delete sel.first sel.last
+ }
+ }
+ # $w insert insert $s
+ $w insert insert $s [$w tag names insert]
+ $w see insert
+ if { $compound && $oldSeparator } {
+ $w edit separator
+ $w configure -autoseparators 1
+ }
+ if {[info exists object($w)]} {
+ $object($w) configure -changed 1
+ }
+}
+
+proc ::Richtext::requireTypoDash {{typo 1}} {
+ variable typoDashRequired
+ set typoDashRequired $typo
+}
+
+proc ::Richtext::insertDash {widget {index insert}} {
+ variable typoDashRequired
+ set tags [$widget tag names $index]
+ if {[atWordEnd $widget $index]} {
+ eval lappend tags [$widget tag names $index-1chars]
+ }
+ if {[string is true $typoDashRequired] &&\
+ ([lsearch $tags pre] < 0) &&\
+ ([lsearch $tags tt] < 0)} {
+ switch -- .[$widget get $index-1chars] {
+ .- {
+ $widget delete $index-1chars
+ $widget insert $index \u2013
+ }
+ .\u2013 {
+ $widget delete $index-1chars
+ $widget insert $index \u2014
+ }
+ default {
+ $widget insert $index -
+ }
+ }
+ } else {
+ $widget insert $index -
+ }
+}
+
+proc ::Richtext::atWordEnd {widget {index insert}} {
+ variable doubleQuotes
+ variable singleQuotes
+ set endpattern ""
+ append endpattern \
+ \[^\[:space:\]\] \
+ \[ \
+ \[:space:\] \
+ {?!:.,} \
+ ">\)\\\]\}" \
+ \]
+ #
+ set startpattern ""
+ append startpattern \
+ \[ \
+ "\{\[(<" \
+ [lindex $doubleQuotes 1]\
+ [lindex $singleQuotes 1]\
+ \].
+ #
+ if {[$widget compare $index == 1.0]} {
+ return 0
+ } elseif {[regexp\
+ $startpattern\
+ [$widget get $index-1chars $index+1chars]]} {
+ return 0
+ } elseif {[regexp\
+ $endpattern\
+ [$widget get $index-1chars $index+1chars]]} {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+proc ::Richtext::insertQuote {widget {index insert} {quotelist doubleQuotes}} {
+ set tags [$widget tag names $index]
+ if {[atWordEnd $widget $index]} {
+ eval lappend tags [$widget tag names $index-1chars]
+ }
+ if {([lsearch $tags pre] >= 0) || ([lsearch $tags tt] >= 0)} {
+ switch $quotelist {
+ doubleQuotes {
+ $widget insert $index \" $tags
+ }
+ default {
+ $widget insert $index ' $tags
+ }
+ }
+ return
+ }
+ variable doubleQuotes
+ variable singleQuotes
+ upvar 0 $quotelist quotes
+ if {[atWordEnd $widget $index]} {
+ $widget insert $index [lindex $quotes end] $tags
+ } else {
+ $widget insert $index [lindex $quotes 0] $tags
+ }
+}
+
+proc ::Richtext::setQuotes {{language C}} {
+ variable doubleQuotes
+ variable singleQuotes
+ variable quoteMode
+ switch [string tolower $language] {
+ german - deutsch - de {
+ set quoteMode de
+ set singleQuotes [list \u201a \u2018]
+ set doubleQuotes [list \u201e \u201c]
+ }
+ englisch - english - en {
+ set quoteMode en
+ set singleQuotes [list \u2018 \u2019]
+ set doubleQuotes [list \u201c \u201d]
+ }
+ schweiz - schweizerisch - swiss - suisse - ch {
+ set quoteMode ch
+ set singleQuotes [list \u203a \u2039]
+ set doubleQuotes [list \u00bb \u00ab]
+ }
+ französisch - francais - fr {
+ set quoteMode fr
+ set singleQuotes [list \u2039 \u203a]
+ set doubleQuotes [list \u00ab \u00bb]
+ }
+ default {
+ set quoteMode C
+ set singleQuotes [list ' ']
+ set doubleQuotes [list \" \"]
+ }
+ }
+ echo quoteMode $quoteMode
+}
+
+namespace import Richtext::richtext
+
+proc tmp {} {
+ foreach binding [bind Text] {
+ bind Richtext $binding\
+ [string map\
+ {tk::TextInsert Richtext::TextInsert}\
+ [bind Text $binding]]
+ }
+ # bind Richtext <Quadruple-Button-1> [bind Text <Triple-Button-1>]
+ # bind Richtext <Quadruple-Button-1> {
+ # ::tk::TextSetCursor %W [list @%x,%y linestart]
+ # ::tk::TextKeySelect %W insert+1lines
+ # }
+ bind Richtext <Control-Key-minus> {
+ tk::TextInsert %W \u00ad
+ }
+ bind Richtext <Control-Key-l> {
+ tk::TextInsert %W \n\u000c\n
+ }
+ bind Richtext <Alt-Key-2> {
+ tk::TextInsert %W \"
+ }
+ bind Richtext <Alt-Key-numbersign> {
+ tk::TextInsert %W '
+ }
+ bind Richtext <Alt-Control-e> {
+ tk::TextInsert %W \u20ac
+ }
+ bind Richtext <Quadruple-Button-1> [list [lambda {w x y} {
+ # bind Richtext <Quadruple-Button-1> (this)
+ set linestart [$w index "@$x,$y linestart"]
+ if {[lsearch [$w tag names $linestart] prefix] >= 0} {
+ set range [$w tag prevrange prefix $linestart+1chars]
+ set linestart [lindex $range end]
+ }
+ ::tk::TextSetCursor $w $linestart
+ ::tk::TextKeySelect $w "insert linestart + 1lines"
+ }] %W %x %y]
+ foreach {key script} {
+ <Triple-Button-1> {
+ set tk::Priv(selectMode) sentence
+ tk::TextSetCursor %W\
+ [Richtext::prevSentenceIndex %W [%W index @%x,%y]]
+ tk::TextKeySelect %W\
+ [Richtext::nextSentenceIndex %W insert]
+ }
+ <Shift-Button-1> {
+ tk::TextResetAnchor %W @%x,%y
+ tk::TextSelectTo %W %x %y 1
+ }
+ <Up> {
+ tk::TextSetCursor %W [Richtext::dLineUpIndex %W insert]
+ }
+ <Down> {
+ tk::TextSetCursor %W [Richtext::dLineDownIndex %W insert]
+ }
+ <Shift-Up> {
+ tk::TextKeySelect %W [Richtext::dLineUpIndex %W insert]
+ }
+ <Shift-Down> {
+ tk::TextKeySelect %W [Richtext::dLineDownIndex %W insert]
+ }
+ <Home> {
+ tk::TextSetCursor %W [Richtext::dLineStartIndex %W insert]
+ }
+ <Shift-Home> {
+ tk::TextKeySelect %W [Richtext::dLineStartIndex %W insert]
+ }
+ <End> {
+ tk::TextSetCursor %W [Richtext::dLineEndIndex %W insert]
+ }
+ <Shift-End> {
+ tk::TextKeySelect %W [Richtext::dLineEndIndex %W insert]
+ }
+ } {
+ bind Richtext $key $script
+ }
+ foreach {cursorKey letter} {
+ Right f
+ Left b
+ Home a
+ End e
+ } {
+ bind Richtext <Control-$letter> [subst {
+ if {!\$tk_strictMotif} {
+ event generate %W <$cursorKey>
+ }
+ }]
+ }
+ bind Richtext <Key-quotedbl> {
+ ::Richtext::insertQuote %W insert doubleQuotes
+ }
+ bind Richtext <Key-quoteright> {
+ ::Richtext::insertQuote %W insert singleQuotes
+ }
+ bind Richtext <Key-minus><Key-minus> {
+ ::Richtext::insertDash %W insert
+ }
+ bind Richtext <Key-minus><Key-minus><Key-minus> {
+ ::Richtext::insertDash %W insert
+ }
+ bind Richtext <Destroy> {
+ catch {::itcl::delete object $::Richtext::object(%W)}
+ array unset ::Richtext::object %W
+ }
+ bind Richtext <Shift-space> {
+ %W insert insert \u00a0 [%W tag names insert]
+ }
+}
+tmp
+rename tmp {}
+
+proc ::Richtext::prevSentenceIndex {widget {pos insert}} {
+ # return index of previous grammatical sentence begin.
+ set dotIndex\
+ [$widget search\
+ -count found\
+ -backwards\
+ -regexp {[\:.?!][\]\})]?( |\t|$)} $pos 1.0]
+if {$dotIndex eq ""} {
+ # no previous dot, so return start index of doc.
+ return 1.0
+}
+# now find next non-blank index.
+set charIndex\
+ [$widget search -regexp {[^[:space:]]} "$dotIndex + $found chars" end]
+if {$charIndex eq ""} {
+ # no non-blank, so return end index of doc.
+ return [$widget index end-1chars]
+} else {
+ set range [$widget tag prevrange blockobject $pos 1.0]
+ if {($range ne {}) &&\
+ [$widget compare [lindex $range end] > $charIndex]} {
+ return [lindex $range end]
+ } else {
+ return $charIndex
+ }
+}
+}
+# end of ::Richtext::prevSentenceIndex
+
+proc ::Richtext::nextSentenceIndex {widget {pos insert}} {
+ # return index of next grammatical sentce begin.
+ set dotIndex\
+ [$widget search -regexp {[\:.?!][\]\})]?( |\t|$)} $pos end]
+if {$dotIndex eq ""} {
+ # no dot found, so return end index of doc.
+ $widget index end-1chars
+} else {
+ $widget search -regexp {( |\t|$)} $dotIndex end
+}
+}
+# end of ::Richtext::nextSentenceIndex
+
+proc ::Richtext::dLineStartIndex {widget {pos insert}} {
+ # return start index of displayed line
+ $widget xview moveto 0
+ set dline [$widget dlineinfo $pos]
+ set beginX [lindex $dline 0]
+ set beginY [lindex $dline 1]
+ # return this value:
+ $widget index @$beginX,$beginY
+}
+
+proc ::Richtext::dLineEndIndex {widget {pos insert}} {
+ # return end index of displayed line
+ set dline [$widget dlineinfo $pos]
+ set endY [lindex $dline 1]
+ set endX [lindex $dline 0]
+ incr endX [lindex $dline 2]
+ set tooWide [expr {$endX > [winfo width $widget]}]
+ if {$tooWide} {
+ $widget xview moveto 1
+ } else {
+ $widget xview moveto 0
+ }
+ set index [$widget index @[winfo width $widget],$endY]
+ $widget see $index
+ return $index
+}
+
+proc ::Richtext::dLineUpIndex {widget {pos insert}} {
+ # return index of next char upwards inside text widget
+ $widget see $pos
+ if {[$widget dlineinfo $pos] == [$widget dlineinfo 1.0]} {
+ return [$widget index $pos]
+ }
+ set bbox [$widget bbox $pos]
+ if {[string equal $bbox ""]} {
+ set x 0
+ } elseif {[$widget get $pos] == "\n"} {
+ set x [expr {[lindex $bbox 0] + [lindex $bbox 3] / 4}]
+ } else {
+ set x [expr {[lindex $bbox 0] + [lindex $bbox 2] / 2}]
+ }
+ set lbox [$widget dlineinfo $pos]
+ set y [lindex $lbox 1]
+ if {$y < 5} {
+ $widget yview scroll -1 units
+ set lbox [$widget dlineinfo $pos]
+ set y [lindex $lbox 1]
+ }
+ incr y -1
+ # return this value:
+ $widget index @$x,$y
+}
+
+proc ::Richtext::dLineDownIndex {widget {pos insert}} {
+ # return index of next char downwards inside text widget
+ $widget see $pos
+ if {[$widget dlineinfo $pos] == [$widget dlineinfo end-1chars]} {
+ return [$widget index $pos]
+ }
+ set bbox [$widget bbox $pos]
+ if {[string equal $bbox ""]} {
+ set x 0
+ } elseif {[$widget get $pos] == "\n"} {
+ set x [expr {[lindex $bbox 0] + [lindex $bbox 3] / 4}]
+ } else {
+ set x [expr {[lindex $bbox 0] + [lindex $bbox 2] / 2}]
+ }
+ set lbox [$widget dlineinfo $pos]
+ set y [lindex $lbox 1]
+ incr y [lindex $lbox 3]
+ incr y 5
+ if {$y > [winfo height $widget]} {
+ # scrollDown
+ $widget yview scroll 1 units
+ set lbox [$widget dlineinfo $pos]
+ set y [lindex $lbox 1]
+ set dy [lindex $lbox 3]
+ incr y $dy
+ incr y 5
+ }
+ # return this value:
+ $widget index @$x,$y
+}
+
+# extending tk function:
+# extends switch $Priv(selectMode) by clause "sentence"
+# which should not matter functions of normal text widgets.
+
+proc ::tk::TextSelectTo {w x y {extend 0}} {
+ global tcl_platform
+ variable Priv
+
+ set cur [TextClosestGap $w $x $y]
+ if {[catch {$w index anchor}]} {
+ $w mark set anchor $cur
+ }
+ set anchor [$w index anchor]
+ if {[$w compare $cur != $anchor] || (abs($Priv(pressX) - $x) >= 3)} {
+ set Priv(mouseMoved) 1
+ }
+ switch $Priv(selectMode) {
+ char {
+ if {[$w compare $cur < anchor]} {
+ set first $cur
+ set last anchor
+ } else {
+ set first anchor
+ set last $cur
+ }
+ }
+ word {
+ if {[$w compare $cur < anchor]} {
+ set first [TextPrevPos $w "$cur + 1c" tcl_wordBreakBefore]
+ if { !$extend } {
+ set last [TextNextPos $w "anchor" tcl_wordBreakAfter]
+ } else {
+ set last anchor
+ }
+ } else {
+ set last [TextNextPos $w "$cur - 1c" tcl_wordBreakAfter]
+ if { !$extend } {
+ set first [TextPrevPos $w anchor tcl_wordBreakBefore]
+ } else {
+ set first anchor
+ }
+ }
+ }
+ sentence {
+ # here the extension!
+ if {[$w compare $cur < anchor]} {
+ set first [::Richtext::prevSentenceIndex $w $cur]
+ set last [::Richtext::nextSentenceIndex $w anchor]
+ } else {
+ set first [::Richtext::prevSentenceIndex $w anchor]
+ set last [::Richtext::nextSentenceIndex $w $cur]
+ }
+ }
+ line {
+ if {[$w compare $cur < anchor]} {
+ set first [$w index "$cur linestart"]
+ set last [$w index "anchor - 1c lineend + 1c"]
+ } else {
+ set first [$w index "anchor linestart"]
+ set last [$w index "$cur lineend + 1c"]
+ }
+ # modification
+ if {[lsearch [$w tag names $last] blockobject] >= 0} {
+ set last [$w index $last-1chars]
+ }
+ }
+ }
+ if {$Priv(mouseMoved) || [string compare $Priv(selectMode) "char"]} {
+ $w tag remove sel 0.0 end
+ $w mark set insert $cur
+ $w tag add sel $first $last
+ $w tag remove sel $last end
+ update idletasks
+ }
+}
+
+proc ::tk_textPaste w {
+ global tcl_platform
+ if {![catch {::tk::GetSelection $w CLIPBOARD} sel]} {
+ set oldSeparator [$w cget -autoseparators]
+ if { $oldSeparator } {
+ $w configure -autoseparators 0
+ $w edit separator
+ }
+# if {[string compare [tk windowingsystem] "x11"]} {
+# catch { $w delete sel.first sel.last }
+# }
+ #
+ catch { $w delete sel.first sel.last }
+ #
+ $w insert insert $sel
+ if { $oldSeparator } {
+ $w edit separator
+ $w configure -autoseparators 1
+ }
+ }
+} \ No newline at end of file
diff --git a/support/dinbrief-gui/dinbrief.vfs/searchText.tcl b/support/dinbrief-gui/dinbrief.vfs/searchText.tcl
new file mode 100644
index 0000000000..f5c0459414
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.vfs/searchText.tcl
@@ -0,0 +1,300 @@
+comment {
+ Inkrementelle Suche, nur Vorwärts, kein Ersetzen.
+ Das widget wird bei Betreten des Suchmodus
+ an das Ereignistag searchMode gebunden.
+ Bei Verlassen erhält es die vorigen Ereignistags zurück
+ (zwischengespeichert in bindTags($win)).
+}
+
+namespace eval searchText {
+ # bindtags: array intended to store original binding tags of widgets
+ variable bindTags
+ array set bindTags {}
+ variable searchModeOf
+ array set searchModeOf {}
+ # searchHistory contains history of incremental search
+ variable searchHistory {}
+ variable searchString ""
+ # escapeCharMap intended to translate spec chars to escaped ones
+ variable escapeCharMap [[lambda {} {
+ set result {}
+ lappend result\
+ \{ \\\{ \} \\\} ( \\( ) \\) \[ \\\[ \] \\\]\
+ * \\* + \\+ ? \\? \\ \\\\ . \\. \$ \\\$\
+ " " \\s \t \\s
+ set quotePat \[
+ append quotePat \u201e \u201c \u201d \u00bb \u00ab \]
+ lappend result \" $quotePat
+ set apostrophePat \[
+ append apostrophePat \u201a \u2018 \u2019 \u203a \u2039 \]
+ lappend result ' $apostrophePat
+ set dashPat \[
+ append dashPat \u2013 \u2014 - \]
+ lappend result - $dashPat
+ }]]
+ # asciifiedCharMap intended to translate typgraphical chars to ASCII
+ variable asciifiedCharMap\
+ [list \t " " \u2013 - \u2014 -\
+ \u201e \" \u201c \" \u201d \" \u00bb \" \u00ab \"\
+ \u201a ' \u2018 ' \u2019 ' \u203a ' \u2039 ']
+}
+
+#
+# ::searchText::getSearchModeOf win
+# return true if $win is in search mode
+#
+proc ::searchText::getSearchModeOf {win} {
+ variable searchModeOf
+ switch [winfo class $win] {
+ Scrolledtext - Scrolledrichtext {
+ getSearchModeOf $win.text
+ }
+ default {
+ expr {[info exists searchModeOf($win)] && $searchModeOf($win)}
+ }
+ }
+}
+
+proc ::searchText::setSearchModeOf {win val} {
+ variable searchModeOf
+ switch [winfo class $win] {
+ Scrolledtext - Scrolledrichtext {
+ setSearchModeOf $win.text $val
+ }
+ default {
+ set searchModeOf($win) $val
+ }
+ }
+}
+
+#
+# ::searchText::asciifiedSelection win
+# returns contents of current selection of $win
+#
+proc ::searchText::asciifiedSelection {win} {
+ if {[$win tag ranges sel] ne {}} {
+ variable asciifiedCharMap
+ string map $asciifiedCharMap [$win get sel.first sel.last]
+ }
+}
+
+#
+# ::searchText::searchWinEsc win str index dir
+# searches $str in $win such that " finds national quotes etc.
+#
+proc ::searchText::searchWinEsc {win str {index insert} {dir -forward}} {
+ variable escapeCharMap
+ set str1 [string map $escapeCharMap $str]
+ switch -- $dir {
+ -backward {
+ $win search -regexp -nocase -backward -- $str1 $index 1.0
+ }
+ default {
+ $win search -regexp -nocase -- $str1 $index end
+ }
+ }
+}
+
+proc ::searchText::toggleSearchMode {win} {
+ searchMode $win [expr {![expr {[getSearchModeOf $win]}]}]
+}
+
+#
+# ::searchText::searchMode .maintext no
+# switches searchimg mode for .maintext off
+#
+# ::searchText::searchMode .maintext ye
+# switches searchimg mode for .maintext on
+# if some text is selected, search it first
+#
+proc ::searchText::searchMode {win {mode yes}} {
+ switch [winfo class $win] {
+ Scrolledtext - Scrolledrichtext {
+ return [searchMode $win.text $mode]
+ }
+ }
+ variable bindTags
+ variable searchString
+ variable searchHistory
+ variable searchModeOf
+ if {$mode} {
+ if {[getSearchModeOf $win]} {
+ return
+ }
+ set searchModeOf($win) 1
+ $win tag configure found -background yellow
+ $win tag raise sel
+ set bindTags($win) [bindtags $win]
+ bindtags $win searchMode
+ grid .searchStringLabel .searchString - - -sticky ne
+ grid configure .searchString -sticky nw
+ .searchStringLabel configure -foreground black
+ if {[$win tag ranges sel] eq {}} {
+ set searchString ""
+ } else {
+ let {from to} [$win tag ranges sel]
+ set searchString [asciifiedSelection $win]
+ searchWinText $win $searchString [$win index sel.first]
+ }
+ set searchHistory {}
+ } else {
+ if {![getSearchModeOf $win]} {
+ return
+ }
+ set searchModeOf($win) 0
+ bindtags $win $bindTags($win)
+ $win tag remove found 1.0 end
+ grid forget .searchStringLabel .searchString
+ if {$searchString ne ""} {
+ globalSetting lastSearchString $searchString
+ }
+ }
+}
+
+#
+# ::searchText::markWinOccurrences win str
+# marks all occurrences of $str in $win with tag found
+# (currently yellow background)
+#
+proc ::searchText::markWinOccurrences {win string} {
+ $win tag remove found 1.0 end
+ if {$string eq ""} {
+ return
+ }
+ set i 1.0
+ # [set i [$win search -regexp -nocase -- $str1 $i end]]
+ while {[set i [searchWinEsc $win $string $i]] ne {}} {
+ set i1 [$win index $i+[string length $string]chars]
+ $win tag add found $i $i1
+ set i $i1
+ }
+}
+
+#
+# ::searchText::searchWinNextChar win char
+# appends $char to $searchString, calls searchWinText
+# (this proc realizes incremental search)
+#
+proc ::searchText::searchWinNextChar {win char} {
+ variable searchString
+ set sel [$win tag ranges sel]
+ if {$sel ne {}} {
+ let {from to} $sel
+ } else {
+ set from [$win index insert]
+ }
+ searchWinText $win $searchString$char $from
+}
+
+#
+# ::searchText::searchWinText win str index
+# searches $str in $win starting at $index
+# appends $str, sel.first, sel.last, ranges of tag found to searchHistory
+#
+proc ::searchText::searchWinText {win string {mark insert}} {
+ variable searchString
+ variable searchHistory
+ #
+ push $searchString searchHistory
+ if {[$win tag ranges sel] ne {}} {
+ push [$win index sel.first] searchHistory
+ push [$win index sel.last] searchHistory
+ } else {
+ push [$win index insert] searchHistory
+ push [$win index insert] searchHistory
+ }
+ push [$win tag ranges found] searchHistory
+ #
+ set searchString $string
+ $win tag remove sel 1.0 end
+ set index [searchWinEsc $win $searchString $mark]
+ set foundLength [string length $searchString]
+ if {$index ne {}} {
+ set index1 [$win index "$index + $foundLength chars"]
+ $win tag add sel $index $index1
+ $win mark set insert $index1
+ $win see insert
+ .searchStringLabel configure -foreground black
+ } else {
+ .searchStringLabel configure -foreground red
+ }
+ markWinOccurrences $win $string
+}
+
+#
+# ::searchText::searchHistoryBack win
+# if searchHistory is not empty,
+# then restore searchString, selection, ranges of tag found
+# else shorten searchString by last char and search
+# this proc realizes backward incremental search
+#
+proc ::searchText::searchHistoryBack {win} {
+ variable searchHistory
+ variable searchString
+ if {$searchHistory ne {}} {
+ $win tag remove sel 1.0 end
+ $win tag remove found 1.0 end
+ set foundRanges [pop searchHistory]
+ if {$foundRanges ne {}} {
+ eval $win tag add found $foundRanges
+ }
+ $win mark set insert [pop searchHistory]
+ $win tag add sel [pop searchHistory] insert
+ set searchString [pop searchHistory]
+ $win see insert
+ } elseif {$searchString eq {}} {
+ searchMode $win 0
+ } else {
+ if {[catch {set i0 [$win index sel.first]}]} {
+ set i0 [$win index insert]
+ }
+ set searchString [string range $searchString 0 end-1]
+ searchWinText $win $searchString $i0
+ $win mark set insert $i0
+ $win see insert
+ set searchHistory {}
+ }
+}
+
+# debug
+# upvar \#0 searchText::searchHistory searchHistory
+# upvar \#0 searchText::searchString searchString
+# end of debug
+
+namespace eval searchText {
+ namespace export *
+ bind searchMode <Key> [namespace code [list [lambda {win key sym} {
+ upvar searchString searchString
+ upvar searchHistory searchHistory
+ switch -glob -- $sym Control* - Alt* - *Shift* {
+ } F3 {
+ if {$searchString eq ""} {
+ searchWinText $win [globalSetting lastSearchString]
+ set searchHistory {}
+ } else {
+ searchWinText $win $searchString
+ }
+ } Escape - Left - Right - Up - Down - Home -\
+ End - Prior - Next - Insert - Delete - F* {
+ searchMode $win 0
+ } default {
+ switch -regexp -- $key {[[:graph:][:space:]]} {
+ searchWinNextChar $win $key
+ } \b {
+ # searchWinPrevChar $win
+ searchHistoryBack $win
+ } default {
+ echo exit: key $key
+ searchMode $win 0
+ }
+ }
+ }] %W %A %K]]
+ bind searchMode <Button-1> {searchMode %W 0}
+}
+
+bind searchMode <FocusOut> {
+ searchMode %W 0
+}
+
+namespace import -force {::searchText::*}
+
diff --git a/support/dinbrief-gui/dinbrief.vfs/tabs2tex.tcl b/support/dinbrief-gui/dinbrief.vfs/tabs2tex.tcl
new file mode 100644
index 0000000000..db63c4aba9
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.vfs/tabs2tex.tcl
@@ -0,0 +1,207 @@
+comment {
+ Bereiche mit Tabulatoren werden zum TeX-Makro \halign{...} umgesetzt.
+ Tabulator-Bereiche werden so behandelt:
+ (1) Die Zeilen werden eingesammelt und auf gleiche Tab-Zahl gebracht.
+ (2) Die Felder werden in Spalten einsortiert.
+ (3) Die Spalten werden auf Fließkomma- oder Ganzzahl untersucht.
+ (4) Reine Fließkommaspalten werden durch
+ Vorkomma- und Nachkommaspalten ersetzt.
+ (5) Fließkomma- und Ganzzahlspalten werden rechtsbündig ausgerichtet.
+}
+
+proc getTabulatorIndices {txt} {
+ set tabPat {(?:(?:[^\n]*\t)+[^\n]*\n)+}
+ regexp -inline -all -indices $tabPat $txt
+}
+
+proc getTextTabSequence {txt} {
+ set indexPairs [getTabulatorIndices $txt]
+ set tabParts {}
+ foreach {indexPair} $indexPairs {
+ let {from to} $indexPair
+ lappend tabParts [string range $txt $from $to]
+ }
+ set textIndices {}
+ lappend textIndices -1
+ foreach indexPair $indexPairs {
+ let {from to} $indexPair
+ lappend textIndices [expr {$from-1}] [expr {$to+1}]
+ }
+ lappend textIndices [string length $txt]
+ set textParts {}
+ foreach {from to} $textIndices {
+ lappend textParts [string range $txt $from $to]
+ }
+ set result {}
+ foreach textPart $textParts tabPart $tabParts {
+ lappend result $textPart $tabPart
+ }
+ lrange $result 0 end-1
+}
+
+proc txt2tabRows {tabPart} {
+ set lines [split [string trim $tabPart] \n]
+ set colNum 0
+ foreach line $lines {
+ set length [llength [split $line \t]]
+ if {$length > $colNum} {
+ set colNum $length
+ }
+ }
+ set rowNum [llength $lines]
+ set rows {}
+ foreach i [range $rowNum] {
+ set row [split [lindex $lines $i] \t]
+ while {[llength $row] < $colNum} {
+ lappend row {}
+ }
+ lappend rows $row
+ }
+ set rows
+}
+
+proc txt2tabCols {tabPart} {
+ set rows [txt2tabRows $tabPart]
+ set rowNum [llength $rows]
+ set colNum [llength [lindex $rows 0]]
+ set cols {}
+ foreach i [range $colNum] {
+ set col {}
+ foreach j [range $rowNum] {
+ lappend col [llindex $rows $j $i]
+ }
+ lappend cols $col
+ }
+ set cols
+}
+
+proc colType {col} {
+ if {[globalSetting numberAlign] eq "left"} {
+ return string
+ }
+ # try on integer
+ set isInteger 1
+ foreach f $col {
+ if {![regexp {^[0-9+-]*$} $f]} {
+ set isInteger 0
+ break
+ }
+ }
+ if {$isInteger} {
+ return integer
+ }
+ let {Punkt Komma} [globalSetting 1000.dezimal,]
+ set pat [subst -nocommand {^[+-]?[0-9$Punkt]+($Komma[0-9]+)?$}]
+ foreach f $col {
+ if {![regexp $pat $f]} {
+ return string
+ }
+ }
+ return float
+}
+
+proc splitFloatCol {col} {
+ let {Punkt Komma} [globalSetting 1000.dezimal,]
+ let vorkommas {} nachkommas {}
+ foreach float $col {
+ let {vorkomma nachkomma} [split $float $Komma]
+ lappend vorkommas $vorkomma
+ lappend nachkommas $nachkomma
+ }
+ list $vorkommas $nachkommas
+}
+
+proc txt2tabColStruct {tabPart} {
+ set cols [txt2tabCols $tabPart]
+ set cols1 {}
+ set types1 {}
+ foreach col $cols type [map colType $cols] {
+ switch $type {
+ float {
+ lappend types1 vorkomma nachkomma
+ let {vorkommas nachkommas} [splitFloatCol $col]
+ lappend cols1 [map [lambda {numString} {
+ # string map "- \u2013" $numString
+ string map {- $-$ + $+$} $numString
+ }] $vorkommas] [map [lambda {x} {
+ let {Punkt Komma} [globalSetting 1000.dezimal,]
+ if {$x ne ""} {
+ return "$Komma$x"
+ }
+ }] $nachkommas]
+ }
+ integer {
+ lappend types1 $type
+ lappend cols1 [map [lambda {numString} {
+ string map "- \u2013" $numString
+ }] $col]
+ }
+ default {
+ lappend types1 $type
+ lappend cols1 $col
+ }
+ }
+ }
+ list $types1 $cols1
+}
+
+proc txt2tabLineStruct {tabPart} {
+ let {types cols} [txt2tabColStruct $tabPart]
+ set colNum [llength $cols]
+ set rowNum [llength [lindex $cols 0]]
+ set result {}
+ lappend result $types
+ foreach i [range $rowNum] {
+ set row {}
+ foreach j [range $colNum] {
+ lappend row [llindex $cols $j $i]
+ }
+ lappend result $row
+ }
+ set result
+}
+
+proc tabRange2tex {tabPart} {
+ set struct [txt2tabLineStruct $tabPart]
+ set types [lindex $struct 0]
+ set lines [lrange $struct 1 end]
+ set patterns [map [lambda {type} {
+ switch $type {
+ vorkomma {
+ return " \\hfill \#"
+ }
+ nachkomma {
+ return "\# \\hfill "
+ }
+ integer {
+ return " \\hfill \# "
+ }
+ default {
+ return " \# \\hfill "
+ }
+ }
+ }] $types]
+ set texLines {}
+ lappend texLines [join $patterns &]
+ foreach line $lines {
+ lappend texLines [join [map unicode2tex $line ] {&}]
+ }
+ set result \\halign
+ append result \{ \n\
+ [join $texLines \\cr\n]\
+ \\cr \n \}
+}
+
+proc plaintext2tex {txt} {
+ set sequence [getTextTabSequence $txt]
+ set plaintext [lindex $sequence 0]
+ set result [unicode2texWithItems [hyphenated $plaintext]]
+ foreach {tabulatortext plaintext} [lrange $sequence 1 end] {
+ append result\
+ \n\n\
+ [tabRange2tex $tabulatortext]\
+ \n\n\
+ [unicode2texWithItems [hyphenated [string trim $plaintext]]]
+ }
+ string trim $result
+} \ No newline at end of file
diff --git a/support/dinbrief-gui/dinbrief.vfs/util.tcl b/support/dinbrief-gui/dinbrief.vfs/util.tcl
new file mode 100755
index 0000000000..195d25ac60
--- /dev/null
+++ b/support/dinbrief-gui/dinbrief.vfs/util.tcl
@@ -0,0 +1,486 @@
+proc comment args {}
+
+switch $tcl_platform(platform) {
+ unix {
+ event add <<Cut>> <Shift-Delete>
+ event add <<Copy>> <Control-Insert>
+ event add <<Paste>> <Shift-Insert>
+
+ event delete <<Paste>> <Control-Key-y>
+ event add <<Redo>> <Control-Key-y>
+
+ # correct some strange failures in key bindings
+
+ bind Text <Control-v> {event generate %W <<Paste>>}
+ bind Text <Control-y> {event generate %W <<Redo>>}
+ }
+}
+
+option add *Menu.tearOffCommand fixTornOffMenu
+option add *Canvas.highlightThickness 0
+option add *Label.borderWidth 1
+option add *Entry.borderWidth 1
+option add *Spinbox.borderWidth 1
+option add *Button.borderWidth 1
+option add *Menubutton.borderWidth 1
+option add *Scrollbar.borderWidth 1
+
+option add *Entry.font {Helvetica 9}
+option add *Label.font {Helvetica 9}
+option add *Button.font {Helvetica 9}
+option add *Menubutton.font {Helvetica 9}
+option add *Checkbutton.font {Helvetica 9}
+option add *Labelframe.font {Helvetica 9}
+option add *Text.font {Helvetica 9}
+
+option add *Menu.background \#c0c0c0
+option add *Menu.borderWidth 1
+option add *Menu.activeBorderWidth 1
+
+option add *Radiobutton.font {Helvetica 9}
+option add *Radiobutton.justify left
+option add *Radiobutton.wrapLength 300
+
+option add *Checkbutton.justify left
+option add *Checkbutton.wrapLength 300
+
+
+option add *Entry.background white
+option add *Entry.highlightThickness 0
+
+option add *Text.background white
+option add *Text.relief sunken
+option add *Text.borderWidth 1
+option add *Text.insertOffTime 0
+option add *Text.highlightThickness 0
+
+option add *Text.undo 1
+
+option add *Menu.background \#c0c0c0
+option add *Menu.borderwidth 0
+
+proc fixTornOffMenu {menu toplevel} {
+ # make tear-off transient to parent window.
+ set parent [winfo parent $toplevel]
+ wm transient $toplevel $parent
+ if {$::tcl_platform(platform) ne "unix"} {
+ set px [winfo pointerx $parent]
+ set py [winfo pointery $parent]
+ set x [expr {$px - 30}]
+ set y [expr {$py - 10}]
+ wm geometry $toplevel +$x+$y
+ }
+ wm resizable $toplevel no no
+}
+
+proc setVscrollbarIn {toplevel a b} {
+ # set vertical scrollbar in $toplevel (managed by grid)
+ if {$toplevel eq "."} {
+ set scrollbar .vscroll
+ } else {
+ set scrollbar $toplevel.vscroll
+ }
+ if {($a == 0.0) && ($b == 1.0)} {
+ set code "catch {grid forget $scrollbar}"
+ after cancel $code
+ after 100 $code
+ } else {
+ grid configure $scrollbar -row 0 -column 1 -sticky news
+ set code [list $scrollbar set $a $b]
+ after cancel $code
+ after idle $code
+ }
+}
+
+proc setHscrollbarIn {toplevel a b} {
+ # set horizontal scrollbar in $toplevel (managed by grid)
+ if {$toplevel eq "."} {
+ set scrollbar .hscroll
+ } else {
+ set scrollbar $toplevel.hscroll
+ }
+ if {($a == 0.0) && ($b == 1.0)} {
+ set code "catch {grid forget $scrollbar}"
+ after cancel $code
+ after 100 $code
+ } else {
+ grid configure $scrollbar -row 1 -column 0 -sticky news
+ set code [list $scrollbar set $a $b]
+ after cancel $code
+ after idle $code
+ }
+}
+
+
+namespace eval dummy {}
+
+proc scrolledtext {f args} {
+ frame $f -class Scrolledtext
+ text $f.text
+ grid $f.text\
+ [scrollbar $f.vscroll\
+ -command [list $f.text yview]]\
+ -sticky news
+ grid [scrollbar $f.hscroll\
+ -orient horizontal\
+ -command [list $f.text xview]]\
+ -sticky news
+ grid rowconfigure $f 0 -weight 1
+ grid columnconfigure $f 0 -weight 1
+ $f.text configure\
+ -xscrollcommand [list setHscrollbarIn $f]\
+ -yscrollcommand [list setVscrollbarIn $f]\
+ -wrap word
+ rename $f ::dummy::$f
+ proc $f {args} [subst {
+ eval $f.text \$args
+ }]
+ eval $f.text configure $args
+ set f
+}
+
+proc scrolledrichtext {f args} {
+ frame $f -class Scrolledrichtext
+ richtext $f.text
+ grid $f.text\
+ [scrollbar $f.vscroll\
+ -command [list $f.text yview]]\
+ -sticky news
+ grid [scrollbar $f.hscroll\
+ -orient horizontal\
+ -command [list $f.text xview]]\
+ -sticky news
+ grid rowconfigure $f 0 -weight 1
+ grid columnconfigure $f 0 -weight 1
+ $f.text configure\
+ -xscrollcommand [list setHscrollbarIn $f]\
+ -yscrollcommand [list setVscrollbarIn $f]\
+ -wrap word
+ rename $f ::dummy::$f
+ proc $f {args} [subst {
+ eval $f.text \$args
+ }]
+ eval $f.text configure $args
+ set f
+}
+
+namespace eval Lambda {
+ variable counter 0
+ array set function {}
+ namespace eval Function {}
+ namespace export lambda
+}
+
+proc ::Lambda::nextName {} {
+ variable counter
+ return [namespace current]::Function::[incr counter]
+}
+
+proc ::Lambda::lambda {arglist body} {
+ # return quasi-anonymous lambda term
+ # (i. e. build a procedure bound to some name, and return that name).
+ variable function
+ set formals [list $arglist $body]
+ if {![info exists function($formals)]} {
+ set name [nextName]
+ uplevel 1 [list proc $name $arglist $body]
+ set function($formals) $name
+ }
+ return $function($formals)
+}
+
+namespace import -force ::Lambda::lambda
+
+proc unicode2texNormal {unicode} {
+ variable char2texTable
+ set string [string trim $unicode]
+ set texChars [string map $char2texTable $string]
+ set lineFeedMap [list \n \\\\\n]
+ set texLines [string map $lineFeedMap $texChars]
+ set parPattern {(\s*\\\\\n){2,}}
+ set texLines [regsub -all $parPattern $texLines "\n\n"]
+ string map [list\
+ ... [globalSetting ...]\
+ {\pagebreak{}\\} {\pagebreak{}}
+ ] $texLines
+}
+
+#
+proc subSubjectIndices {src} {
+ set indices\
+ [regexp -all -inline -indices {(?:^|\n+)([*/_])[^\n]*?\1} $src]
+ set result {}
+ foreach {match sign} $indices {
+ let {from to} $match
+ lappend result $from
+ set foundRange [string range $src $from $to]
+ set char\
+ [string index [string trim $foundRange] 0]
+ set pat \\$char.*?\\$char
+ if {[regexp -indices $pat $foundRange match1]} {
+ let {from1 to1} $match1
+ set len [expr {$to1-$from1}]
+ lappend result\
+ [expr {$from + $len + [string first $char $foundRange]}]
+ } else {
+ lappend result $to
+ }
+ }
+ set result
+}
+
+proc textSubSubjectFragments {src} {
+ set indices -1
+ set subSubjects {}
+ foreach {from to} [subSubjectIndices $src] {
+ lappend subSubjects [string range $src $from $to]
+ lappend indices [expr {$from - 1}] [expr {$to + 1}]
+ }
+ lappend indices [string length $src]
+ set textList {}
+ foreach {from to} $indices {
+ lappend textList [string range $src $from $to]
+ }
+ # list subSubjectes $subSubjects textList $textList
+ set result [lrange $textList -1 0]
+ foreach subSubject $subSubjects text [lrange $textList 1 end] {
+ lappend result $subSubject $text
+ }
+ set result
+}
+
+proc unicode2tex {src} {
+ set frags [textSubSubjectFragments $src]
+ set result [unicode2texNormal [lindex $frags 0]]
+ array set meaning {
+ * \\bf
+ / \\it
+ _ \\underline
+ }
+ foreach {sub txt} [lrange $frags 1 end] {
+ regexp -indices {[*/_]} $sub indices
+ let {from to} $indices
+ set subChar [string range $sub $from $to]
+ set subText [string range $sub [expr {$to+1}] end-1]
+ set splitRange [regexp -inline ^\\s* $txt]
+ append result \n\n\{\
+ $meaning($subChar) \
+ \{ [unicode2texNormal $subText] \}\
+ \}\
+ $splitRange\
+ [unicode2texNormal $txt]
+ }
+ string trim $result
+}
+
+#
+
+proc charVal {char} {
+ scan $char %c
+}
+
+proc hex {number} {
+ format %x $number
+}
+
+proc echo {args} {
+ uplevel [list puts $args]
+}
+
+#
+# return string with non-ascii chars encoded as in ö = \u00f6 etc.
+#
+proc unicode2asciiEncoded {rawString} {
+ set string [string map {\\ \\\\} $rawString]
+ while {[regexp {[^[:ascii:]]} $string nonAsciiChar]} {
+ set nonAsciiVal [charVal $nonAsciiChar]
+ set hexVal [hex $nonAsciiVal]
+ while {[string length $hexVal] < 4} {
+ set hexVal 0$hexVal
+ }
+ set hexVal \\u$hexVal
+ set string [string map [list $nonAsciiChar $hexVal] $string]
+ }
+ set string
+}
+
+proc saveString {string file} {
+ set port [open $file w]
+ puts -nonewline $port $string
+ close $port
+}
+
+proc cat file {
+ set port [open $file]
+ set contents [read $port]
+ close $port
+ return $contents
+}
+
+proc let {args} {
+ uplevel 1 foreach $args {break}
+}
+
+proc range {num args} {
+ switch [llength $args] {
+ 0 {
+ set from 0
+ set to $num
+ set step 1
+ }
+ 1 {
+ set from $num
+ set to $args
+ set step 1
+ }
+ 2 {
+ set from $num
+ let {to step} $args
+ }
+ }
+ set result [list ]
+ for {set i $from} {$i < $to} {set i [expr {$i + $step}]} {
+ lappend result $i
+ }
+ return $result
+}
+
+proc map {func list} {
+ set result [list ]
+ foreach el $list {
+ lappend result [uplevel [list $func $el]]
+ }
+ return $result
+}
+
+proc llindex {l args} {
+ # return nested list index, e.g. llindex $nestedList 4 2
+ if {[llength $args] == 0} {
+ return $l
+ } else {
+ eval llindex [list [lindex $l [lindex $args 0]]] [lrange $args 1 end]
+ }
+}
+
+namespace eval Stack {
+ variable stack {}
+ namespace export push pop tos
+}
+
+proc Stack::pop {{s ::Stack::stack}} {
+ upvar $s stack
+ set result [lindex $stack end]
+ set stack [lrange $stack 0 end-1]
+ return $result
+}
+
+proc Stack::push {val {s ::Stack::stack}} {
+ upvar $s stack
+ lappend stack $val
+}
+
+proc Stack::tos {{s ::Stack::stack}} {
+ upvar $s stack
+ lindex $stack end
+}
+
+namespace import -force ::Stack::push
+namespace import -force ::Stack::pop
+namespace import -force ::Stack::tos
+
+proc map {func list} {
+ set result [list ]
+ foreach el $list {
+ lappend result [uplevel [list $func $el]]
+ }
+ return $result
+}
+
+proc shift {listVar} {
+ upvar $listVar list
+ set result [lindex $list 0]
+ set list [lrange $list 1 end]
+ set result
+}
+
+proc unshift {el listVar} {
+ upvar $listVar list
+ set list [concat $el $list]
+}
+
+namespace eval Sleep {
+ namespace export sleep
+ variable count 0
+}
+
+proc ::Sleep::newVar {} {
+ variable count
+ return var[incr count]
+}
+
+proc ::Sleep::sleep {num} {
+ set var [newVar]
+ uplevel 1 set ::Sleep::$var 1
+ after $num [list set ::Sleep::$var 0]
+ vwait ::Sleep::$var
+ unset ::Sleep::$var
+}
+
+namespace import -force ::Sleep::sleep
+
+proc lreverse {l} {
+ set i [llength $l]
+ set result {}
+ while {$i} {
+ lappend result [lindex $l [incr i -1]]
+ }
+ # return this value
+ set result
+}
+
+proc relPathFromTo {fromDir toDir} {
+ # return path string relative from $fromDir to $toDir.
+ # $fromDir is assumed to be a directory (not a file).
+ set from [file normalize $fromDir]
+ set to [file normalize $toDir]
+ if {$::tcl_platform(platform) eq "windows"} {
+ set driveMap {
+ a: A: b: B: c: C: d: D: e: E: f: F: g:
+ G: h: H: i: I: j: J: k: K: l: L: m: M:
+ n: N: o: O: p: P: q: Q: r: R: s: S: t:
+ T: u: U: v: V: w: W: x: X: y: Y: z: Z:
+ }
+ regexp {^[a-zA-Z]:} [pwd] drive
+ if {![regexp {^[a-zA-Z]:} $from]} {
+ set from $drive$from
+ }
+ set from [string map $driveMap $from]
+ if {![regexp {^[a-zA-Z]:} $to]} {
+ set to $drive$to
+ }
+ set to [string map $driveMap $to]
+ }
+ set fromList [file split $from]
+ set fromLength [llength $fromList]
+ set toList [file split $to]
+ set toLength [llength $toList]
+ set commonList {}
+ foreach path1 $fromList path2 $toList {
+ if {$path1 ne $path2} {
+ break
+ } else {
+ lappend commonList $path1
+ }
+ }
+ set commonLength [llength $commonList]
+ set fromList1 [lrange $fromList $commonLength end]
+ set toList1 [lrange $toList $commonLength end]
+ set resultList {}
+ foreach i $fromList1 {
+ lappend resultList ..
+ }
+ eval lappend resultList $toList1
+ if {$resultList ne {}} {
+ eval file join $resultList
+ }
+} \ No newline at end of file
diff --git a/support/dinbrief-gui/global.vars b/support/dinbrief-gui/global.vars
new file mode 100644
index 0000000000..e9f7eaa7e8
--- /dev/null
+++ b/support/dinbrief-gui/global.vars
@@ -0,0 +1 @@
+file {} justOpened no backAddressRules {\backaddressrule} paperFoldMarks {\windowtics} language ngerman numberAlign right defaultFile /home/ftpmaint/limbo/dinbrief-gui/default.dinbrief addressPos {\addressstd} pdflatex pdflatex smartQuotes C lastSearchString {} 1000.dezimal, {. ,} addressRules {\windowrules} ... {\ldots} fontSize 9 verticalAddressAlign {\centeraddress} list-O-matic deep windowGeometry 550x550+110+196 pdfViewer xpdf refLineOverFold 1 \ No newline at end of file