#!/bin/sh
# Call wish and restart \
exec wish "$0" "$@"

############################################################################
# dvedit: Version 1.0 (Experimental)
# Author: Abhijit Das (Barda) [abhij@csa.iisc.ernet.in]
# Last updated: Dec 15 1998
############################################################################

############################# ATTENTION ####################################
#
# Set the following variables, if the default values do not conform
# to your system settings.
#

# Edit the following two lines if you have dvedit library and bnr.gsf
# installed elsewhere. The former must be set appropriately. The latter
# is needed if you are using the PostScript exporter of dvedit.

set installdir "/usr/local/dvedit"
set psfontfile "$installdir/gsf/dvr.gsf"
set stylefile  "$installdir/sty/devnagari.sty"

# Set dpyfont to fixed, if your X windowing system does not support
# a font named `variable'. Tk version 8.0 onwards replaces any
# non-existing font by `fixed'. If you are using earlier versions
# of Tk, you must set dpyfont yourself.

# set dpyfont fixed
set dpyfont variable

# Similarly set hdrfont according as your X installation
# set hdrfont fixed
# set hdrfont variable
set hdrfont "-*-helvetica-bold-r-*-*-20-*"

#################### DO NOT EDIT AFTER THIS LINE ###########################

set fntprobe [ exec xlsfonts ]
if {[regexp "devnagari" $fntprobe] == 0} {
   puts "\nERROR: Font not found ...."
   puts "I cannot detect Devnagari fonts in your system."
   puts "First load the fonts and then run dvedit.\n"
   exit -1;
}
unset fntprobe
set fontlist [ exec xlsfonts | grep -v devnagari]
set fontlist [ split $fontlist "\n" ]
set scriptlist [ list suptag supsuptag subsuptag subtag subsubtag supsubtag ]

set appbg "#d3d3d3"
set appfg "#000000"
set btnbg "#a9a9a9"
set btnfg "#000000"

set textbg "#000000"
set textfg "#ffffff"
set textsbg "#ffffff"
set textsfg "#000000"
set textibg "#d0f080"
set textht 15
set textwd 75
set ptsize 120
set slant "r"
set charmap 1
set editrmn 0

set textbg2 "#000000"
set textfg2 "#ffffff"
set textsbg2 "#ffffff"
set textsfg2 "#000000"
set textibg2 "#d0f080"
set textht2 24
set textwd2 80
set olbg "#000000"
set olfg "#00ffff"

regsub "~" "~/dvmail" [glob -nocomplain "~"] dvmaildir
set mailcmd "elm -s %s %r < %f"
set mimen "mimencode %f"
set mimed "mimencode -u %f"
set uun "uuencode %f %f"
set uud "uudecode %f -o /dev/stdout"

proc readOptions {} {
   global textbg textfg textsbg textsfg textibg textht textwd ptsize slant charmap
   global textbg2 textfg2 textsbg2 textsfg2 textibg2 textht2 textwd2 editrmn
   global olbg olfg
   global dvmaildir mailcmd mimen mimed uun uud

   set rcfile "~/.dveditrc"
   if [file exists $rcfile] {
      set rcf [open $rcfile r]
      while { [gets $rcf rcline] >= 0 } {
         set rcline [string trim $rcline]
         set cidx [string first ":" $rcline]
         if {($cidx >= 0) && [string compare "#" [string index $rcline 0]]} {
            set rcName [ string range $rcline 0 [expr $cidx - 1] ]
            set rcVal [ string range $rcline [expr $cidx + 1] [expr [string length $rcline] - 1] ]
            set rcName [string tolower [string trim $rcName]]
            set rcVal [string tolower [string trim $rcVal]]
            switch -exact $rcName {
               "textbackground" { set textbg $rcVal }
               "textforeground" { set textfg $rcVal }
               "selectionbackground" { set textsbg $rcVal }
               "selectionforeground" { set textsfg $rcVal }
               "cursorcolor" { set textibg $rcVal }
               "textheight" { set textht $rcVal }
               "textwidth" { set textwd $rcVal }
               "defaultpointsize" { set ptsize $rcVal }
               "slant" { set slant $rcVal }
               "charmap" { set charmap $rcVal }
               "editroman" { set editrmn $rcVal }
               "textbackground2" { set textbg2 $rcVal }
               "textforeground2" { set textfg2 $rcVal }
               "selectionbackground2" { set textsbg2 $rcVal }
               "selectionforeground2" { set textsfg2 $rcVal }
               "cursorcolor2" { set textibg2 $rcVal }
               "textheight2" { set textht2 $rcVal }
               "textwidth2" { set textwd2 $rcVal }
               "onlineforeground" { set olfg $rcVal }
               "onlinebackground" { set olbg $rcVal }
               "dvmaildir" { regsub "~" $rcVal [glob -nocomplain "~"] dvmaildir }
               "mailcommand" { set mailcmd $rcVal }
               "mimencommand" { set mimen $rcVal }
               "mimedcommand" { set mimed $rcVal }
               "uuncommand" { set uun $rcVal }
               "uudcommand" { set uud $rcVal }
            }
         }
      }
      close $rcf
   }
}

readOptions

switch -exact $ptsize {
   100 {set textsp3 4; set off1 5; set off2 8; set off3 3;}
   120 {set textsp3 5; set off1 6; set off2 9; set off3 3;}
   150 {set textsp3 6; set off1 7; set off2 12; set off3 4;}
   180 {set textsp3 7; set off1 9; set off2 14; set off3 5;}
   210 {set textsp3 8; set off1 10; set off2 16; set off3 6;}
   250 {set textsp3 10; set off1 12; set off2 20; set off3 7;}
   300 {set textsp3 12; set off1 15; set off2 24; set off3 9;}
   360 {set textsp3 15; set off1 18; set off2 28; set off3 10;}
   default {set textsp3 5; set off1 6; set off2 9; set off3 3;}
}

frame .cmdfr -relief raised -borderwidth 2
frame .namefr
frame .mainfr
frame .mainfr.editfr
frame .mainfr.cafr -relief ridge -borderwidth 2
frame .mainfr.cafr.swarfr
frame .mainfr.cafr.kaarfr
frame .mainfr.cafr.banfr1
frame .mainfr.cafr.banfr2
frame .mainfr.cafr.splfr1
frame .mainfr.cafr.splfr2
frame .mainfr.cafr.engfr1
frame .mainfr.cafr.engfr2
frame .mainfr.cafr.engfr3
frame .mainfr.cafr.jukfr1
frame .mainfr.cafr.jukfr2
frame .mainfr.cafr.jukfr3
frame .mainfr.cafr.jukfr4
frame .mainfr.cafr.jukfr5

#Command bar
menubutton .cmdfr.file -text "File" -height 1 -relief flat \
      -menu .cmdfr.file.m -bg $appbg -fg $appfg -underline 0 \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
menubutton .cmdfr.edit -text "Edit" -height 1 -relief flat \
      -menu .cmdfr.edit.m -bg $appbg -fg $appfg -underline 0 \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
menubutton .cmdfr.tag -text "Tag" -height 1 -relief flat \
      -menu .cmdfr.tag.m -bg $appbg -fg $appfg -underline 2 \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
menubutton .cmdfr.import -text "Import" -height 1 -relief flat \
      -menu .cmdfr.import.m -bg $appbg -fg $appfg -underline 4 \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
menubutton .cmdfr.export -text "Export" -height 1 -relief flat \
      -menu .cmdfr.export.m -bg $appbg -fg $appfg -underline 1 \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
menubutton .cmdfr.mail -text "Mail" -height 1 -relief flat \
      -menu .cmdfr.mail.m -bg $appbg -fg $appfg -underline 0 \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
menubutton .cmdfr.option -text "Option" -height 1 -relief flat \
      -menu .cmdfr.option.m -bg $appbg -fg $appfg -underline 1 \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
menubutton .cmdfr.help -text "Help" -height 1 -relief flat \
      -menu .cmdfr.help.m -bg $appbg -fg $appfg -underline 0 \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
menu .cmdfr.file.m
.cmdfr.file.m add command -label "  New " -accelerator " (Alt+N)  " -command {newFile} -underline 2
.cmdfr.file.m add command -label "  Load " -accelerator " (Alt+L)  " -command {loadFile} -underline 2
.cmdfr.file.m add command -label "  Insert " -accelerator " (Alt+I)  " -command {insertFile} -underline 2
.cmdfr.file.m add command -label "  Append " -accelerator " (Alt+A)  " -command {appendFile} -underline 2
.cmdfr.file.m add command -label "  Save " -accelerator " (Alt+V)  " -command {saveThisFile} -underline 4
.cmdfr.file.m add command -label "  Save as " -accelerator " (Alt+S)  " -command {saveFile} -underline 2
.cmdfr.file.m add separator
.cmdfr.file.m add command -label "  Quit " -accelerator " (Alt+Q)  " -command {quitEditor} -underline 2
.cmdfr.file.m config -tearoff false -bg $appbg -fg $appfg
menu .cmdfr.edit.m
.cmdfr.edit.m add command -label "  Clear  " -command {clearTextArea; incr dirtybit 1} -underline 2
.cmdfr.edit.m add command -label "  Select all  " -command {selectAll} -underline 9
.cmdfr.edit.m add separator
.cmdfr.edit.m add command -label "  Cut  " -command {cutBuffer} -underline 4
.cmdfr.edit.m add command -label "  Copy  " -command {copyBuffer} -underline 5
.cmdfr.edit.m add command -label "  Paste  " -command {pasteBuffer} -underline 2
.cmdfr.edit.m config -tearoff false -bg $appbg -fg $appfg
menu .cmdfr.tag.m
.cmdfr.tag.m add command -label "  Normal  " -command {normalSel} -underline 2
.cmdfr.tag.m add command -label "  Underline  " -command {ulSel} -underline 2
.cmdfr.tag.m add command -label "  Superscript  " -command {supSel} -underline 4
.cmdfr.tag.m add command -label "  Supersuperscript  " -command {supsupSel} -underline 5
.cmdfr.tag.m add command -label "  Subsuperscript  " -command {subsupSel} -underline 9
.cmdfr.tag.m add command -label "  Subscript  " -command {subSel} -underline 4
.cmdfr.tag.m add command -label "  Subsubscript  " -command {subsubSel} -underline 9
.cmdfr.tag.m add command -label "  Supersubscript  " -command {supsubSel} -underline 15
.cmdfr.tag.m add command -label "  Select font  " -command {fontSel} -underline 9
.cmdfr.tag.m config -tearoff false -bg $appbg -fg $appfg
.cmdfr.tag.m add separator
.cmdfr.tag.m add command -label "  Load tags  " -command {loadTags} -underline 2
.cmdfr.tag.m add command -label "  Save tags  " -command {saveTags} -underline 4
menu .cmdfr.option.m
.cmdfr.option.m add command -label "  Show Keyboard map " -accelerator " (Alt+K)  " -command {viewKbdMap} -underline 7
if {$charmap} {
   .cmdfr.option.m add command -label "  Hide character array " -accelerator " (Alt+C) " -command {manageCharMap} -underline 7
} else {
   .cmdfr.option.m add command -label "  Show character array " -accelerator " (Alt+C) " -command {manageCharMap} -underline 7
}
.cmdfr.option.m add separator
.cmdfr.option.m add command -label "  Select document font " -accelerator " (Alt+D) " -command {chooseBaseFont} -underline 9
.cmdfr.option.m add separator
.cmdfr.option.m add command -label "  Edit options " -accelerator " (Alt+O)  " -command {editOptions 0} -underline 7
.cmdfr.option.m add command -label "  Save options  " -command {saveOptions 0} -underline 2
.cmdfr.option.m config -tearoff false -bg $appbg -fg $appfg
menu .cmdfr.import.m
.cmdfr.import.m add command -label "  Reread encoding  " -command {readEnc} -underline 2
.cmdfr.import.m add separator
.cmdfr.import.m add command -label "  Load transliterated roman file  " -command {importRoman 0} -underline 2
.cmdfr.import.m add command -label "  Insert transliterated roman file  " -command {importRoman 1} -underline 2
.cmdfr.import.m add separator
.cmdfr.import.m add command -label "  Edit transliterated roman text  " -command {editRoman} -underline 2
.cmdfr.import.m add separator
.cmdfr.import.m add command -label "  Roman-to-Devnagari conversion rules  " -command {helpwinRoman} -underline 11
.cmdfr.import.m config -tearoff false -bg $appbg -fg $appfg
menu .cmdfr.export.m
.cmdfr.export.m add command -label "  To HTML  " -command {exportHTML} -underline 5
.cmdfr.export.m add command -label "  To LaTeX  " -command {exportLaTeX} -underline 5
.cmdfr.export.m add command -label "  To PostScript  " -command {exportPS} -underline 5
.cmdfr.export.m config -tearoff false -bg $appbg -fg $appfg
menu .cmdfr.mail.m
.cmdfr.mail.m add command -label "  Send mail  " -command {sendMail 0} -underline 2
.cmdfr.mail.m add separator
.cmdfr.mail.m add command -label "  Read dvencoded text  " -command {readDV} -underline 7
.cmdfr.mail.m add command -label "  Read MIME-encoded text  " -command {readMIME} -underline 7
.cmdfr.mail.m add command -label "  Read uuencoded text  " -command {readUU} -underline 7
.cmdfr.mail.m add separator
.cmdfr.mail.m add command -label "  Edit mail options  " -command {set opttype 3; editOptions 0} -underline 2
.cmdfr.mail.m config -tearoff false -bg $appbg -fg $appfg
menu .cmdfr.help.m
.cmdfr.help.m add command -label "  About dvedit  " -command {helpwin} -underline 2
.cmdfr.help.m add command -label "  Copyright notice  " -command {copyInfo} -underline 2
.cmdfr.help.m config -tearoff false -bg $appbg -fg $appfg
label .cmdfr.blank -text "" -relief flat -bg $appbg -fg $appfg
image create photo dveditlogo -file "$installdir/images/dvedit-logo.gif"
label .cmdfr.logo -image "dveditlogo" -relief flat -bg $appbg -fg $appfg
pack .cmdfr.file .cmdfr.edit .cmdfr.tag .cmdfr.import \
   .cmdfr.export .cmdfr.mail .cmdfr.option .cmdfr.help \
   -side left -padx 5 -pady 0 -side left
pack .cmdfr.blank -side left -expand yes -fill both
pack .cmdfr.logo -side left -padx 5 -pady 0 -side left

#File name
label .namefr.lbl -text " File name: " -relief flat -foreground $appfg -background $appbg
entry .namefr.ent -textvariable fname -relief sunken \
      -background #ffb6c1 -foreground #000000
# Previous background: #ddaaaa
bind .namefr.ent <Return> {focus .mainfr.editfr.textarea; loadThisFile}
pack .namefr.lbl -side left -padx 0 -pady 0
pack .namefr.ent -side left -padx 0 -pady 0 -expand yes -fill x
.namefr.ent config -selectbackground #000000 -selectforeground #ffb6c1 -selectborderwidth 0

#Edit area
text .mainfr.editfr.textarea -relief sunken -height $textht -width $textwd \
            -font "-*-devnagari-medium-$slant-*-*-*-$ptsize-*-*-*-*-*-fontspecific" \
            -xscroll ".mainfr.hscroll set" -yscroll ".mainfr.editfr.scrbar set" \
            -wrap none -spacing3 $textsp3 -relief flat \
            -insertbackground $textibg -insertwidth 3 \
            -background $textbg -foreground $textfg -borderwidth 2 \
            -selectbackground $textsbg -selectforeground $textsfg -selectborderwidth 0
scrollbar .mainfr.editfr.scrbar -relief sunken -orient vertical \
           -command ".mainfr.editfr.textarea yview" -bg $appbg -width 12 \
           -activebackground $appbg
pack .mainfr.editfr.scrbar -fill y -side right -padx 0 -pady 0
pack .mainfr.editfr.textarea -expand yes -fill both -side right -padx 0 -pady 0

#Horizontal scrollbar
scrollbar .mainfr.hscroll -relief sunken -orient horizontal \
           -command ".mainfr.editfr.textarea xview" -bg $appbg -width 12 \
           -activebackground $appbg

proc addcb { fr asc } {
   global appbg appfg

   set char [list format "%c" $asc]
   button .mainfr.cafr.$fr.char$asc -text [eval $char] -relief flat -width 1 \
          -font "-*-devnagari-medium-r-*-*-*-100-*-*-*-*-*-fontspecific" \
          -bg #AADDCC -fg $appfg -borderwidth -2 -highlightthickness 0 \
          -activeforeground #ffffff -activebackground #446655 \
          -command "printChar $asc"
   pack .mainfr.cafr.$fr.char$asc -padx 0 -pady 0 -side left
}

proc addcbeng { fr name asc } {
   global appbg appfg

   set char [list format "%c" $asc]
   button .mainfr.cafr.$fr.$name -text [eval $char] -relief flat -width 1 \
      -font fixed -bg #AADDCC -fg $appfg -borderwidth -2 -highlightthickness 0 \
      -activeforeground #ffffff -activebackground #446655 \
      -command "printCharEng $asc"
   pack .mainfr.cafr.$fr.$name -padx 0 -pady 0 -side left
}

proc printChar { i } {
   global dirtybit

   set char [format "%c" $i]
   .mainfr.editfr.textarea insert insert $char
   incr dirtybit 1
}

proc printCharEng { i } {
   global dirtybit

   set char [format "%c" $i]
   .mainfr.editfr.textarea insert insert $char english
   incr dirtybit 1
}

#Swar frame
addcb swarfr 97
button .mainfr.cafr.swarfr.charA -text "aA" -relief flat -width 1 \
       -font "-*-devnagari-medium-r-*-*-*-100-*-*-*-*-*-fontspecific" \
       -bg #AADDCC -fg $appfg -borderwidth -2 -highlightthickness 0 \
       -activeforeground #ffffff -activebackground #446655 \
       -command {.mainfr.editfr.textarea insert insert "aA"; incr dirtybit 1}
pack .mainfr.cafr.swarfr.charA -padx 0 -pady 0 -side left
addcb swarfr 105
addcb swarfr 73
addcb swarfr 18
addcb swarfr 117
addcb swarfr 85
addcb swarfr 101
button .mainfr.cafr.swarfr.charoi -text "e\{" -relief flat -width 1 \
       -font "-*-devnagari-medium-r-*-*-*-100-*-*-*-*-*-fontspecific" \
       -bg #AADDCC -fg $appfg -borderwidth -2 -highlightthickness 0 \
       -activeforeground #ffffff -activebackground #446655 \
       -command {.mainfr.editfr.textarea insert insert "e\{"; incr dirtybit 1}
pack .mainfr.cafr.swarfr.charoi -padx 0 -pady 0 -side left
button .mainfr.cafr.swarfr.charao -text "ao" -relief flat -width 1 \
       -font "-*-devnagari-medium-r-*-*-*-100-*-*-*-*-*-fontspecific" \
       -bg #AADDCC -fg $appfg -borderwidth -2 -highlightthickness 0 \
       -activeforeground #ffffff -activebackground #446655 \
       -command {.mainfr.editfr.textarea insert insert "ao"; incr dirtybit 1}
pack .mainfr.cafr.swarfr.charao -padx 0 -pady 0 -side left
button .mainfr.cafr.swarfr.charaO -text "aO" -relief flat -width 1 \
       -font "-*-devnagari-medium-r-*-*-*-100-*-*-*-*-*-fontspecific" \
       -bg #AADDCC -fg $appfg -borderwidth -2 -highlightthickness 0 \
       -activeforeground #ffffff -activebackground #446655 \
       -command {.mainfr.editfr.textarea insert insert "aO"; incr dirtybit 1}
pack .mainfr.cafr.swarfr.charaO -padx 0 -pady 0 -side left
button .mainfr.cafr.swarfr.charom -text "a\\" -relief flat -width 1 \
       -font "-*-devnagari-medium-r-*-*-*-100-*-*-*-*-*-fontspecific" \
       -bg #AADDCC -fg $appfg -borderwidth -2 -highlightthickness 0 \
       -activeforeground #ffffff -activebackground #446655 \
       -command {.mainfr.editfr.textarea insert insert "a\\"; incr dirtybit 1}
pack .mainfr.cafr.swarfr.charom -padx 0 -pady 0 -side left
button .mainfr.cafr.swarfr.charoh -text "a," -relief flat -width 1 \
       -font "-*-devnagari-medium-r-*-*-*-100-*-*-*-*-*-fontspecific" \
       -bg #AADDCC -fg $appfg -borderwidth -2 -highlightthickness 0 \
       -activeforeground #ffffff -activebackground #446655 \
       -command {.mainfr.editfr.textarea insert insert "a,"; incr dirtybit 1}
pack .mainfr.cafr.swarfr.charoh -padx 0 -pady 0 -side left
addcb swarfr 27
addcb swarfr 17
addcb swarfr 24
addcb swarfr 25

addcb kaarfr 65
addcb kaarfr 69
addcb kaarfr 70
addcb kaarfr 8
addcb kaarfr 1
addcb kaarfr 3
addcb kaarfr 123
addcb kaarfr 111
addcb kaarfr 79
addcb kaarfr 92
addcb kaarfr 44
addcb kaarfr 2
addcb kaarfr 14
addcb kaarfr 31
addcb kaarfr 124
addcb kaarfr 19
addcb kaarfr 125
addcb kaarfr 126
addcb kaarfr 4
addcb kaarfr 255
addcb kaarfr 94
addcb kaarfr 253
addcb kaarfr 132
addcb kaarfr 20
addcb kaarfr 134

#Banjon frames
addcb banfr1 107
addcb banfr1 42
addcb banfr1 75
addcb banfr1 12
addcb banfr1 103
addcb banfr1 11
addcb banfr1 71
addcb banfr1 82
addcb banfr1 99
addcb banfr1 67
addcb banfr1 106
addcb banfr1 41
addcb banfr1 74
addcb banfr1 26
addcb banfr1 86
addcb banfr1 87
addcb banfr1 88
addcb banfr1 119
addcb banfr1 89
addcb banfr1 120
addcb banfr1 90
addcb banfr1 116
addcb banfr1 84

addcb banfr2 100
addcb banfr2 68
addcb banfr2 110
addcb banfr2 112
addcb banfr2 80
addcb banfr2 39
addcb banfr2 98
addcb banfr2 66
addcb banfr2 109
addcb banfr2 121
addcb banfr2 114
addcb banfr2 108
addcb banfr2 118
addcb banfr2 102
addcb banfr2 113
addcb banfr2 115
addcb banfr2 104
addcb banfr2 15
addcb banfr2 34
addcb banfr2 43
addcb banfr2 58
addcb banfr2 122
addcb banfr2 33

#Special frame
addcb splfr1 63
addcb splfr1 30
addcb splfr1 72
addcb splfr1 7
addcb splfr1 96
addcb splfr1 28
addcb splfr1 93
addcb splfr1 81
addcb splfr1 62
addcb splfr1 36
addcb splfr1 22
addcb splfr1 23
addcb splfr1 40
addcb splfr1 76
addcb splfr1 64
addcb splfr1 6
addcb splfr1 61
addcb splfr1 37
addcb splfr1 78
addcb splfr1 60
addcb splfr2 77
addcb splfr2 5
addcb splfr2 29
addcb splfr2 83
addcb splfr2 38
addcb splfr2 91
addcb splfr2 21
addcb splfr2 45
addcb splfr2 35
addcb splfr2 232
addcb splfr2 233
addcb splfr2 234
addcb splfr2 235
addcb splfr2 236
addcb splfr2 241
addcb splfr2 242
addcb splfr2 243
addcb splfr2 244
addcb splfr2 245
addcb splfr2 246

#upper case letters
for {set i 65} {$i <= 90} {incr i 1} {
   addcbeng engfr1 uc$i $i
}

#lower case letters
for {set i 97} {$i <= 122} {incr i 1} {
   addcbeng engfr2 lc$i $i
}

# Special symbols in the ASCII keyboard
addcbeng engfr3 dot 46
addcbeng engfr3 dollar 36
addcbeng engfr3 pound 163
addcbeng engfr3 lbrace 123
addcbeng engfr3 rbrace 125
addcbeng engfr3 lt 60
addcbeng engfr3 gt 62
addcbeng engfr3 bslash 92
addcbeng engfr3 at 64
addcbeng engfr3 amp 38
addcbeng engfr3 caret 94
addcbeng engfr3 underscore 95
addcbeng engfr3 multsign 215
addcbeng engfr3 divsign 247
addcbeng engfr3 copy 169
addcbeng engfr3 reg 174
addcbeng engfr3 zero 48
addcbeng engfr3 one 49
addcbeng engfr3 two 50
addcbeng engfr3 three 51
addcbeng engfr3 four 52
addcbeng engfr3 five 53
addcbeng engfr3 six 54
addcbeng engfr3 seven 55
addcbeng engfr3 eight 56
addcbeng engfr3 nine 57

#Juktakkhar frames
addcb jukfr1 47
addcb jukfr1 128
addcb jukfr1 129
addcb jukfr1 130
addcb jukfr1 131
addcb jukfr1 133
for {set i 135} {$i <= 151} {incr i 1} {
   addcb jukfr1 $i
}
for {set i 152} {$i <= 174} {incr i 1} {
   addcb jukfr2 $i
}
for {set i 175} {$i <= 197} {incr i 1} {
   addcb jukfr3 $i
}
for {set i 198} {$i <= 220} {incr i 1} {
   addcb jukfr4 $i
}
for {set i 221} {$i <= 231} {incr i 1} {
   addcb jukfr5 $i
}
for {set i 237} {$i <= 240} {incr i 1} {
   addcb jukfr5 $i
}
for {set i 247} {$i <= 252} {incr i 1} {
   addcb jukfr5 $i
}
addcb jukfr5 254

#pack top level components
pack .mainfr.cafr.swarfr -padx 0 -pady 0 -fill none
pack .mainfr.cafr.kaarfr -padx 0 -pady 0 -fill none
pack .mainfr.cafr.banfr1 -padx 0 -pady 0 -fill none
pack .mainfr.cafr.banfr2 -padx 0 -pady 0 -fill none
pack .mainfr.cafr.splfr1 -padx 0 -pady 0 -fill none
pack .mainfr.cafr.splfr2 -padx 0 -pady 0 -fill none
for {set i 1} {$i <= 5} {incr i 1} {
   pack .mainfr.cafr.jukfr$i -padx 0 -pady 0 -fill none
   .mainfr.cafr.jukfr$i config -bg $appbg
}
pack .mainfr.cafr.engfr1 -padx 0 -pady 0 -fill none
pack .mainfr.cafr.engfr2 -padx 0 -pady 0 -fill none
pack .mainfr.cafr.engfr3 -padx 0 -pady 0 -fill none
if {$charmap} { pack .mainfr.cafr -padx 0 -pady 0 -fill x -side bottom }
pack .mainfr.hscroll -padx 0 -pady 0 -fill x -side bottom
pack .mainfr.editfr -padx 0 -pady 0 -expand yes -fill both -side bottom
pack .cmdfr -padx 0 -pady 0 -fill x
pack .namefr -padx 5 -pady 5 -fill x
pack .mainfr -padx 0 -pady 0 -expand yes -fill both

.cmdfr config -bg $appbg
.namefr config -bg $appbg
.mainfr config -bg $appbg
.mainfr.editfr config -bg $appbg
.mainfr.cafr config -bg #AADDCC
.mainfr.cafr.swarfr config -bg #AADDCC
.mainfr.cafr.kaarfr config -bg #AADDCC
.mainfr.cafr.banfr1 config -bg #AADDCC
.mainfr.cafr.banfr2 config -bg #AADDCC
.mainfr.cafr.splfr1 config -bg #AADDCC
.mainfr.cafr.splfr2 config -bg #AADDCC
.mainfr.cafr.engfr1 config -bg #AADDCC
.mainfr.cafr.engfr2 config -bg #AADDCC
.mainfr.cafr.engfr3 config -bg #AADDCC
. config -bg $appbg

focus .mainfr.editfr.textarea

proc errmsg { msg } {
   global btnbg btnfg

   set ewin [toplevel .error]

   message $ewin.msg -text $msg -relief flat -bg #006688 -fg #ffffff -width 250 -justify center
   button $ewin.btn -text "Ok" -relief raised -fg $btnfg -bg $btnbg \
          -activeforeground $btnfg -activebackground $btnbg \
          -command {set edone 1} -height 0

   pack $ewin.msg -padx 0 -pady 0 -expand yes -fill both
   pack $ewin.btn -pady 10

   bind $ewin <Escape> {set edone 1}
   bind $ewin <Return> {set edone 1}

   $ewin config -bg #004466

   wm transient $ewin .
   set posx [winfo x .]
   set posy [winfo y .]
   incr posx [winfo x .mainfr]
   incr posy [winfo y .mainfr]
   set twd [winfo width .mainfr.editfr.textarea]
   set tht [winfo height .mainfr.editfr.textarea]
   set ewd 300
   set eht 150
   set posx [expr $posx + ($twd - $ewd) / 2]
   set posy [expr $posy + ($tht - $eht) / 2]
   if {$posx <= 0} { set posx 0 }
   if {$posy <= 0} { set posy 0 }
   wm geometry $ewin "${ewd}x${eht}+$posx+$posy"
   wm title $ewin "Diagnostic message"

   grab $ewin
   tkwait variable edone
   grab release $ewin
   destroy $ewin
}

set dirtybit 0
set scwinid -1
proc saveConfirm { } {
   global scwin dirtybit btnbg btnfg scwinid

   if {[winfo exists $scwinid]} {focus $scwinid; tkwait variable dirtybit; return;}
   while {$dirtybit} {
      set scwin [toplevel .sc]
      set scwinid $scwin
      $scwin config -bg #004466
      label $scwin.l -text "Editor text has unsaved changes" -fg #ffffff -bg #006688
      frame $scwin.bfr -bg #004466
      button $scwin.bfr.b1 -text "Save" -command {saveThisFile} -underline 0 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      button $scwin.bfr.b2 -text "Save as" -command {saveFile} -underline 5 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      button $scwin.bfr.b3 -text "Do not save" -command {set dirtybit 0} -underline 3 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      pack $scwin.l -expand yes -fill both -padx 0 -pady 0
      pack $scwin.bfr.b1 $scwin.bfr.b2 $scwin.bfr.b3 -side left -padx 10 -pady 0
      pack $scwin.bfr -expand no -padx 0 -pady 10

      bind $scwin <Key-s> {saveThisFile}
      bind $scwin <Key-a> {saveFile}
      bind $scwin <Key-n> {set dirtybit 0}

      wm transient $scwin .
      wm title $scwin "Options for unsaved changes"
      set posx [winfo x .]
      set posy [winfo y .]
      incr posx [winfo x .mainfr]
      incr posy [winfo y .mainfr]
      set twd [winfo width .mainfr.editfr.textarea]
      set tht [winfo height .mainfr.editfr.textarea]
      set ewd 350
      set eht 120
      set posx [expr $posx + ($twd - $ewd) / 2]
      set posy [expr $posy + ($tht - $eht) / 2]
      if {$posx <= 0} { set posx 0 }
      if {$posy <= 0} { set posy 0 }
      wm geometry $scwin "${ewd}x${eht}+$posx+$posy"
      focus $scwin

      tkwait variable dirtybit
      destroy $scwin
      set scwinid -1
   }
}

proc loadThisFile {} {
   global fname

   saveConfirm
   set fname [string trim $fname]
   if {![file readable $fname]} {
      errmsg "ERROR:\nI cannot load the file \"$fname\". The file does not exist or does not have read permission."
      return
   }
   if {![file isfile $fname]} {
      errmsg "ERROR:\nI cannot load the file. \"$fname\" is not a regular file."
      return
   }
   set f [open $fname r]
   set x [read $f]
   clearTextArea
   .mainfr.editfr.textarea insert 1.0 $x
   set t [close $f]
   wm title . "dvedit: $fname"
   focus .mainfr.editfr.textarea
   .mainfr.editfr.textarea see insert
}

proc newFile {} {
   global fname

   saveConfirm
   clearTextArea
   set fname ""
   wm title . "dvedit: (New file)"
}

proc loadFile {} {
   global fname

   saveConfirm
   set fn [getFileName "dvedit: Load"]
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         errmsg "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         return
      }
      set f [open $fn r]
      set x [read $f]
      clearTextArea
      .mainfr.editfr.textarea insert 1.0 $x
      set t [close $f]
      set fname $fn
      wm title . "dvedit: $fname"
      .mainfr.editfr.textarea see insert
   }
}

proc insertFile {} {
   set fn [getFileName "dvedit: Insert"]
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         errmsg "ERROR:\nI cannot insert the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg "ERROR:\nI cannot insert the file. \"$fn\" is not a regular file."
         return
      }
      set f [open $fn r]
      set x [read $f]
      .mainfr.editfr.textarea insert insert $x
      set t [close $f]
      .mainfr.editfr.textarea see insert
   }
}

proc appendFile {} {
   set fn [getFileName "dvedit: Append"]
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         errmsg "ERROR:\nI cannot append the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg "ERROR:\nI cannot append the file. \"$fn\" is not a regular file."
         return
      }
      set f [open $fn r]
      set x [read $f]
      .mainfr.editfr.textarea insert end $x
      set t [close $f]
      .mainfr.editfr.textarea see insert
   }
}

proc saveThisFile {} {
   global fname dirtybit

   set fname [string trim $fname]
   if {![string compare "" $fname]} {
      errmsg "ERROR:\nI cannot save file. No file name is given."
      return
   }
   set dnm [file dirname $fname]
   if {![file isdirectory $dnm]} {
      errmsg "ERROR:\nI cannot save the file. \"$dnm\" is not a directory."
      return
   }
   if {![file writable $dnm]} {
      errmsg "ERROR:\nI cannot save the file. You do not have permission to write in the directory \"$dnm\"."
      return
   }
   if {[file exists $fname] && ![file isfile $fname]} {
      errmsg "ERROR:\nI cannot save the file. \"$fname\" is not a regular file."
      return
   }
   if {[file exists $fname] && ![file writable $fname]} {
      errmsg "ERROR:\nI cannot save the file. You do not have permission to overwrite \"$fname\""
      return
   }
   set f [open $fname w]
   set x [.mainfr.editfr.textarea get 1.0 end]
   puts -nonewline $f $x
   set t [close $f]
   set dirtybit 0
   errmsg "$fname saved"
}

proc saveFile {} {
   global fname dirtybit

   set fn [getFileName "dvedit: Save"]
   if { [string compare $fn ""] != 0 } {
      set dnm [file dirname $fn]
      if {![file isdirectory $dnm]} {
         errmsg "ERROR:\nI cannot save the file. \"$dnm\" is not a directory."
         return
      }
      if {![file writable $dnm]} {
         errmsg "ERROR:\nI cannot save the file. You do not have permission to write in the directory \"$dnm\"."
         return
      }
      if {[file exists $fn] && ![file isfile $fn]} {
         errmsg "ERROR:\nI cannot save the file. \"$fn\" is not a regular file."
         return
      }
      if {[file exists $fn] && ![file writable $fn]} {
         errmsg "ERROR:\nI cannot save the file. You do not have permission to overwrite \"$fn\""
         return
      }
      set f [open $fn w]
      set x [.mainfr.editfr.textarea get 1.0 end]
      puts -nonewline $f $x
      set t [close $f]
      if { [string compare $fname ""] == 0 } {
         set fname $fn
         wm title . "dvedit: $fname"
      }
      set dirtybit 0
      errmsg "$fn saved"
   }
}

proc clearTextArea {} {
   .mainfr.editfr.textarea delete 1.0 end
}

proc quitEditor {} {
   global rwinid

   if {[winfo exists $rwinid]} {
      saveRomanConfirm $rwinid
      destroy $rwinid
   }
   saveConfirm
   destroy .
   exit 0
}

proc browse { win } {
   global browsedir

   $win delete 0 end
   if [regexp {/\.\.$} $browsedir] {
      set browsedir [string range $browsedir 0 [expr [string length $browsedir] - 4]]
      set browsedir [string range $browsedir 0 [expr [string last "/" $browsedir] - 1]]
   }
   if {[string compare $browsedir ""] == 0} {
      foreach f [exec ls -a "/"] {
         if {[regexp {^\.$} $f] == 0} {
            if [file isdirectory /$f] {
               $win insert end /$f/
            } else {
               $win insert end /$f
            }
         }
      }
   } else {
      foreach f [exec ls -a $browsedir] {
         if {[regexp {^\.$} $f] == 0} {
            if [file isdirectory $browsedir/$f] {
               $win insert end $browsedir/$f/
            } else {
               $win insert end $browsedir/$f
            }
         }
      }
   }
}

proc getFileName { wtitle } {
   global newfname browsedir dbox ok appbg appfg btnbg btnfg

   set dbox [toplevel .prompt]
   label $dbox.lbl -text "Enter filename: " -relief flat -fg $appfg -bg $appbg
   entry $dbox.ent -textvariable newfname -bg #88ddff -fg #000000 \
      -selectforeground #88ddff -selectbackground #000000 -selectborderwidth 0
   button $dbox.obtn -text "OK" -command {set ok 1} -fg $btnfg -bg $btnbg \
      -activeforeground $btnfg -activebackground $btnbg
   label $dbox.space -text "" -fg $appfg -bg $appbg
   button $dbox.cbtn -text "Cancel" -command {set ok 0} -fg $btnfg -bg $btnbg \
      -activeforeground $btnfg -activebackground $btnbg
   frame $dbox.brfr -bg $appbg
   listbox $dbox.brfr.lbx -width 50 -height 12 -bg #88ddff -fg $btnfg \
      -xscroll "$dbox.xscr set" -yscr "$dbox.brfr.yscr set" -relief sunken \
      -selectmode single -selectforeground #88ddff -selectbackground $btnfg \
      -selectborderwidth 0
   scrollbar $dbox.brfr.yscr -command "$dbox.brfr.lbx yview" \
      -troughcolor #88ddff -orient vertical -bg $appbg -width 12 \
      -activebackground $appbg
   scrollbar $dbox.xscr -command "$dbox.brfr.lbx xview" \
      -troughcolor #88ddff -orient horizontal -bg $appbg -width 12 \
      -activebackground $appbg
   bind $dbox.ent <Return> {set ok 1}
   bind $dbox <Escape> {set ok 0}
   bind $dbox.brfr.lbx <ButtonRelease-1> {
      foreach si [$dbox.brfr.lbx curselection] {
         set f [$dbox.brfr.lbx get $si]
         if {![file isdirectory $f]} { set newfname $f }
      }
   }
   bind $dbox.brfr.lbx <Double-Button-1> {
      foreach si [$dbox.brfr.lbx curselection] {
         set newfname [$dbox.brfr.lbx get $si]
         if [file isdirectory $newfname] {
            set browsedir [string range $f 0 [expr [string length $f] - 2]]
            browse $dbox.brfr.lbx
         } else {
            set ok 1
         }
      }
   }

   pack $dbox.lbl -padx 10 -pady 5
   pack $dbox.ent -padx 10 -pady 5 -fill x
   pack $dbox.brfr.yscr $dbox.brfr.lbx -side right -padx 0 -pady 0 -fill y
   pack $dbox.brfr -padx 10 -pady 0
   pack $dbox.xscr -padx 10 -pady 0 -fill x
   pack $dbox.obtn -padx 10 -pady 5 -side left
   pack $dbox.space -padx 10 -pady 5 -expand yes -fill x -side left
   pack $dbox.cbtn -padx 10 -pady 5
   $dbox config -bg $appbg

   wm title $dbox "$wtitle"
   wm resizable $dbox false false
   if {![file readable $browsedir]} { set browsedir [exec pwd] }
   browse $dbox.brfr.lbx

   focus $dbox.ent
   grab $dbox
   tkwait variable ok
   grab release $dbox
   destroy $dbox

   if {$ok} {
      return [string trim $newfname]
   } else {
      return ""
   }
}

set hwinid -1
proc helpwin { } {
   global installdir dveditlogo dpyfont appbg appfg hwinid
 
   if {[winfo exists $hwinid]} {focus $hwinid; return}
   set hwin [toplevel .help]
   set hwinid $hwin
   $hwin config -bg $appbg
   frame $hwin.cmdfr -bg $appbg
   frame $hwin.dpyfr -bg $appbg
   menubutton $hwin.cmdfr.file -relief flat -fg $appfg -bg $appbg \
      -activebackground $appbg -activeforeground $appfg \
      -menu $hwin.cmdfr.file.m -text "File"
   menubutton $hwin.cmdfr.content -relief flat -fg $appfg -bg $appbg \
      -activebackground $appbg -activeforeground $appfg \
      -menu $hwin.cmdfr.content.m -text "Contents"
   menu $hwin.cmdfr.file.m -tearoff false -bg $appbg -fg $appfg
   $hwin.cmdfr.file.m add command -label "  Close  " -command "destroy $hwin; set hwinid -1" -underline 2
   menu $hwin.cmdfr.content.m -tearoff false -bg $appbg -fg $appfg
   $hwin.cmdfr.content.m add command -label "  Introduction  " -command "adddoc $hwin.dpyfr.textarea intro 0"
   $hwin.cmdfr.content.m add separator
   $hwin.cmdfr.content.m add command -label "  Toolbar  " -command "adddoc $hwin.dpyfr.textarea toolbar 0"
   $hwin.cmdfr.content.m add command -label "      File menu  " -command "adddoc $hwin.dpyfr.textarea file 0"
   $hwin.cmdfr.content.m add command -label "      Edit menu  " -command "adddoc $hwin.dpyfr.textarea edit 0"
   $hwin.cmdfr.content.m add command -label "      Tag menu  " -command "adddoc $hwin.dpyfr.textarea tag 0"
   $hwin.cmdfr.content.m add command -label "      Import menu  " -command "adddoc $hwin.dpyfr.textarea import 0"
   $hwin.cmdfr.content.m add command -label "      Export menu  " -command "adddoc $hwin.dpyfr.textarea export 0"
   $hwin.cmdfr.content.m add command -label "      Mail menu  " -command "adddoc $hwin.dpyfr.textarea mail 0"
   $hwin.cmdfr.content.m add command -label "      Option menu  " -command "adddoc $hwin.dpyfr.textarea option 0"
   $hwin.cmdfr.content.m add command -label "      Help menu  " -command "adddoc $hwin.dpyfr.textarea help 0"
   $hwin.cmdfr.content.m add command -label "  Text area  " -command "adddoc $hwin.dpyfr.textarea textarea 0"
   $hwin.cmdfr.content.m add command -label "  Character array  " -command "adddoc $hwin.dpyfr.textarea chararray 0"
   $hwin.cmdfr.content.m add separator
   $hwin.cmdfr.content.m add command -label "  Edit transliterated text  " -command "adddoc $hwin.dpyfr.textarea editrmn 0"
   $hwin.cmdfr.content.m add command -label "      Toolbar  " -command "adddoc $hwin.dpyfr.textarea rmntool 0"
   $hwin.cmdfr.content.m add command -label "      Text area  " -command "adddoc $hwin.dpyfr.textarea rmntext 0"
   $hwin.cmdfr.content.m add command -label "      Online view  " -command "adddoc $hwin.dpyfr.textarea rmnolview 0"
   $hwin.cmdfr.content.m add separator
   $hwin.cmdfr.content.m add command -label "  Keyboard and mouse bindings  " -command "adddoc $hwin.dpyfr.textarea binding 0"
   $hwin.cmdfr.content.m add separator
   $hwin.cmdfr.content.m add command -label "  Copyright info  " -command "adddoc $hwin.dpyfr.textarea copyright 0"
   label $hwin.cmdfr.space -fg $appfg -bg $appbg -text ""
   label $hwin.cmdfr.logo -relief flat -fg $appfg -bg $appbg -image "dveditlogo"

   text $hwin.dpyfr.textarea -relief sunken -height 20 -width 60 \
      -yscroll "$hwin.dpyfr.vscroll set" \
      -wrap none -relief flat -font $dpyfont \
      -background #ddddaa -foreground #000000 -borderwidth 2 \
      -selectbackground #000000 -selectforeground #ddddaa -selectborderwidth 0
   scrollbar $hwin.dpyfr.vscroll -relief sunken -orient vertical \
      -command "$hwin.dpyfr.textarea yview" -bg $appbg -width 12 \
      -activebackground $appbg

   pack $hwin.cmdfr.file $hwin.cmdfr.content -padx 0 -pady 0 -side left
   pack $hwin.cmdfr.space -padx 0 -pady 0 -side left -expand yes -fill x
   pack $hwin.cmdfr.logo -padx 5 -pady 0 -side left
   pack $hwin.dpyfr.vscroll $hwin.dpyfr.textarea -padx 0 -pady 0 -side right \
      -expand yes -fill y
   pack $hwin.cmdfr $hwin.dpyfr -padx 0 -pady 3 -side top -fill x

   bind $hwin <Escape> "destroy $hwin; set hwinid -1"

   wm resizable $hwin false false
   wm title $hwin "dvedit: Help"
   wm iconname $hwin "dvedit: Help"
   wm iconbitmap $hwin @$installdir/images/dvedit-logo.xbm

   adddoc $hwin.dpyfr.textarea intro 0
}

set cwinid -1
proc copyInfo {} {
   global dveditlogo installdir appbg appfg btnbg btnfg cwinid

   if {[winfo exists $cwinid]} {destroy $cwinid; set cwinid -1; return}
   set cwin [toplevel .copyright]
   set cwinid $cwin
   label $cwin.hdr -relief flat -fg $appfg -bg $appbg -image "dveditlogo"
   label $cwin.ver -relief ridge -fg #000000 -bg #ddddaa \
      -text " Version 1.0, December 1998 "
   message $cwin.cpy -relief ridge -fg #000000 -bg #ddddaa -width 800 -text \
"dvedit -- An X11 application for editing and processing Devnagari text files.
   This is based on the Tcl/Tk shell wish. This requires a fixed X11 bitmap
   font for Devnagari provided with dvedit distribution. These font files
   are adapted from original METAFONT files written by Frans J. Velthuis.

dvedit is a freeware. You can use and distribute it free of charge as long as
   the original author gets credit and this copyright notice remains intact."

   label $cwin.aut -relief ridge -fg #000000 -bg #ddddaa -text " Author: "
   message $cwin.add -relief ridge -fg #000000 -bg #ddddaa -width 500 -text \
"Abhijit Das (Barda)
Department of Computer Science and Automation
Indian Institute of Science
Bangalore 560 012
INDIA

E-mail: abhij@csa.iisc.ernet.in"

   button $cwin.btn -fg $btnfg -bg "$btnbg" -text " Dismiss " \
      -command "destroy $cwin" -activeforeground $btnfg -activebackground $btnbg

   pack $cwin.hdr -padx 0 -pady 5
   pack $cwin.ver -padx 0 -pady 5
   pack $cwin.cpy -padx 5 -pady 5
   pack $cwin.aut -padx 0 -pady 5
   pack $cwin.add -padx 0 -pady 5
   pack $cwin.btn -padx 0 -pady 5
   $cwin config -bg $appbg
   bind $cwin <Escape> "destroy $cwin"

   wm title $cwin "dvedit: copyright notice"
   wm resizable $cwin false false
   wm iconname $cwin "dvedit: copyright notice"
   wm iconbitmap $cwin @$installdir/images/dvedit-logo.xbm
}

proc setKbdText { i j up down } {
   global mwinid

   $mwinid.row$i.f$j.l.up config -text $up
   $mwinid.row$i.f$j.l.down config -text $down
   $mwinid.row$i.f$j.r.up config -text $up
   $mwinid.row$i.f$j.r.down config -text $down
}

set mwinid -1
proc viewKbdMap {} {
   global appbg appfg btnbg btnfg mwinid dpyfont hdrfont

   if {[winfo exists $mwinid]} {focus $mwinid; return}
   set mapwin [toplevel .map]
   set mwinid $mapwin

   $mapwin config -bg $appbg
   label $mapwin.hdr -bg $appbg -fg $appfg -font $hdrfont -text "Keyboard map"
   frame $mapwin.row1 -bg $appbg
   frame $mapwin.row2 -bg $appbg
   frame $mapwin.row3 -bg $appbg
   frame $mapwin.row4 -bg $appbg

   for {set i 1} {$i <= 4} {incr i 1} {
      if {$i == 1} {set jmax 14} else {set jmax [expr 14 - $i]}
      for {set j 1} {$j <= $jmax} {incr j 1} {
         frame $mapwin.row$i.f$j -bg $appbg -relief raised -borderwidth 2
         frame $mapwin.row$i.f$j.l -bg $appbg -relief flat
         label $mapwin.row$i.f$j.l.up -fg $appfg -bg $appbg -relief flat -font $dpyfont -width 2
         label $mapwin.row$i.f$j.l.down -fg $appfg -bg $appbg -relief flat -font $dpyfont -width 2
         frame $mapwin.row$i.f$j.r -bg $appbg -relief flat
         label $mapwin.row$i.f$j.r.up -fg $appfg -bg $appbg -relief flat -width 2 \
            -font "-*-devnagari-medium-r-*-*-*-120-*-*-*-*-*-fontspecific"
         label $mapwin.row$i.f$j.r.down -fg $appfg -bg $appbg -relief flat -width 2 \
            -font "-*-devnagari-medium-r-*-*-*-120-*-*-*-*-*-fontspecific"
         pack $mapwin.row$i.f$j.l.up $mapwin.row$i.f$j.l.down -padx 0 -pady 0 -side top
         pack $mapwin.row$i.f$j.r.up $mapwin.row$i.f$j.r.down -padx 0 -pady 0 -side top
         pack $mapwin.row$i.f$j.l $mapwin.row$i.f$j.r -padx 0 -pady 0 -side left
         pack $mapwin.row$i.f$j -side left -padx 1 -pady 1
      }
   }

   setKbdText 1 1 "~" "'"
   setKbdText 1 2 "!" "1"
   setKbdText 1 3 "@" "2"
   setKbdText 1 4 "#" "3"
   setKbdText 1 5 "$" "4"
   setKbdText 1 6 "%" "5"
   setKbdText 1 7 "^" "6"
   setKbdText 1 8 "&" "7"
   setKbdText 1 9 "*" "8"
   setKbdText 1 10 "(" "9"
   setKbdText 1 11 ")" "0"
   setKbdText 1 12 "_" "-"
   setKbdText 1 13 "+" "="
   setKbdText 1 14 "|" "\\"

   setKbdText 2 1 "Q" "q"
   setKbdText 2 2 "W" "w"
   setKbdText 2 3 "E" "e"
   setKbdText 2 4 "R" "r"
   setKbdText 2 5 "T" "t"
   setKbdText 2 6 "Y" "y"
   setKbdText 2 7 "U" "u"
   setKbdText 2 8 "I" "i"
   setKbdText 2 9 "O" "o"
   setKbdText 2 10 "P" "p"
   setKbdText 2 11 "\{" "\["
   setKbdText 2 12 "\}" "\]"

   setKbdText 3 1 "A" "a"
   setKbdText 3 2 "S" "s"
   setKbdText 3 3 "D" "d"
   setKbdText 3 4 "F" "f"
   setKbdText 3 5 "G" "g"
   setKbdText 3 6 "H" "h"
   setKbdText 3 7 "J" "j"
   setKbdText 3 8 "K" "k"
   setKbdText 3 9 "L" "l"
   setKbdText 3 10 ":" ";"
   setKbdText 3 11 "\"" "\'"

   setKbdText 4 1 "Z" "z"
   setKbdText 4 2 "X" "x"
   setKbdText 4 3 "C" "c"
   setKbdText 4 4 "V" "v"
   setKbdText 4 5 "B" "b"
   setKbdText 4 6 "N" "n"
   setKbdText 4 7 "M" "m"
   setKbdText 4 8 "<" ","
   setKbdText 4 9 ">" "."
   setKbdText 4 10 "?" "/"

   button $mapwin.done -text "Done" -command "destroy $mapwin; set mwinid -1" -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg

   pack $mapwin.hdr $mapwin.row1 $mapwin.row2 $mapwin.row3 \
      $mapwin.row4 $mapwin.done -padx 5 -pady 5
   bind $mapwin <Escape> "destroy $mapwin; set mwinid -1"

   wm title $mapwin "dvedit: keyboard map"
   wm resizable $mapwin false false
}

proc manageCharMap {} {
   global charmap

   if {$charmap} {
      pack forget .mainfr.cafr
      set charmap 0
      .cmdfr.option.m entryconfigure 1 -label "  Show character array " -accelerator " (Alt+C)  " -underline 7
   } else {
      pack forget .mainfr.editfr
      pack forget .mainfr.hscroll
      pack .mainfr.cafr -padx 0 -pady 0 -fill x -side bottom
      pack .mainfr.hscroll -padx 0 -pady 0 -fill x -side bottom
      pack .mainfr.editfr -padx 0 -pady 0 -expand yes -fill both -side bottom
      set charmap 1
      .cmdfr.option.m entryconfigure 1 -label "  Hide character array " -accelerator " (Alt+C)  " -underline 7
   }
}

proc chooseBaseFont {} {
   global ptsize slant donef off1 off2 off3 appbg appfg btnbg btnfg
   
   set fwin [toplevel .font]

   label $fwin.lbl -text "Choose font size" -relief flat -fg $appfg -bg $appbg

   radiobutton $fwin.rb1 -width 6 -text "10" -variable ptsize -value "100" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb2 -width 6 -text "12" -variable ptsize -value "120" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb3 -width 6 -text "15" -variable ptsize -value "150" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb4 -width 6 -text "18" -variable ptsize -value "180" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb5 -width 6 -text "21" -variable ptsize -value "210" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb6 -width 6 -text "25" -variable ptsize -value "250" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb7 -width 6 -text "30" -variable ptsize -value "300" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg
   radiobutton $fwin.rb8 -width 6 -text "36" -variable ptsize -value "360" -relief ridge -selectcolor #bbff00 -fg $appfg -bg $appbg -activebackground $appbg -activeforeground $appfg

   checkbutton $fwin.cb -width 9 -text " slanted" -variable slant \
      -onvalue "o" -offvalue "r" -relief raised \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg

   button $fwin.done -text "Done" -command {set donef 1} -fg $btnfg -bg $btnbg \
      -activeforeground $btnfg -activebackground $btnbg
   button $fwin.cancel -text "Cancel" -command {set donef 0} -fg $btnfg -bg $btnbg \
      -activeforeground $btnfg -activebackground $btnbg

   pack $fwin.lbl -pady 5 -padx 5
   for {set i 1} {$i <= 8} {incr i 1} {
      pack $fwin.rb$i
   }
   pack $fwin.cb -padx 5 -pady 5
   pack $fwin.done $fwin.cancel -pady 5 -padx 5
   $fwin config -bg $appbg
   bind $fwin <Escape> {set donef 0}

   wm title $fwin "dvedit: select font"
   wm resizable $fwin false false

   grab $fwin
   tkwait variable donef
   grab release $fwin
   destroy $fwin

   if {$donef} {
      switch -exact $ptsize {
         100 {.mainfr.editfr.textarea config -spacing3 4; set off1 5; set off2 8; set off3 3;}
         120 {.mainfr.editfr.textarea config -spacing3 5; set off1 6; set off2 9; set off3 3;}
         150 {.mainfr.editfr.textarea config -spacing3 6; set off1 7; set off2 12; set off3 4;}
         180 {.mainfr.editfr.textarea config -spacing3 7; set off1 9; set off2 14; set off3 5;}
         210 {.mainfr.editfr.textarea config -spacing3 8; set off1 10; set off2 16; set off3 6;}
         250 {.mainfr.editfr.textarea config -spacing3 10; set off1 12; set off2 20; set off3 7;}
         300 {.mainfr.editfr.textarea config -spacing3 12; set off1 15; set off2 24; set off3 9;}
         360 {.mainfr.editfr.textarea config -spacing3 15; set off1 18; set off2 28; set off3 10;}
         default {.mainfr.editfr.textarea config -spacing3 5; set off1 6; set off2 9; set off3 3;}
      }
      .mainfr.editfr.textarea config -font "-*-devnagari-medium-$slant-*-*-*-$ptsize-*-*-*-*-*-fontspecific"
      configTags
   }
}

set buffer ""

proc cutBuffer {} {
   global buffer dirtybit

   set lsel [.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   incr dirtybit 1
   set buffer [.mainfr.editfr.textarea get sel.first sel.last]
   .mainfr.editfr.textarea delete sel.first sel.last
   .mainfr.editfr.textarea see insert
}

proc copyBuffer {} {
   global buffer

   set lsel [.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   set buffer [.mainfr.editfr.textarea get sel.first sel.last]
}

proc pasteBuffer {} {
   global buffer dirtybit

   .mainfr.editfr.textarea insert insert $buffer
   incr dirtybit 1
   .mainfr.editfr.textarea see insert
}

proc configTags {} {
   global off1 off2 off3 ptsize slant

   switch -exact $ptsize {
      100 { set scriptsize 100; set scriptscriptsize 100 }
      120 { set scriptsize 100; set scriptscriptsize 100 }
      150 { set scriptsize 120; set scriptscriptsize 100 }
      180 { set scriptsize 150; set scriptscriptsize 120 }
      210 { set scriptsize 180; set scriptscriptsize 150 }
      250 { set scriptsize 210; set scriptscriptsize 180 }
      300 { set scriptsize 250; set scriptscriptsize 210 }
      360 { set scriptsize 300; set scriptscriptsize 250 }
      default { set scriptsize 120; set scriptscriptsize 120 }
   }

   .mainfr.editfr.textarea tag config suptag -offset $off1 -font "-*-devnagari-medium-$slant-*-*-*-$scriptsize-*-*-*-*-*-fontspecific"
   .mainfr.editfr.textarea tag config supsuptag -offset $off2 -font "-*-devnagari-medium-$slant-*-*-*-$scriptscriptsize-*-*-*-*-*-fontspecific"
   .mainfr.editfr.textarea tag config subsuptag -offset $off3 -font "-*-devnagari-medium-$slant-*-*-*-$scriptscriptsize-*-*-*-*-*-fontspecific"
   .mainfr.editfr.textarea tag config subtag -offset -$off1 -font "-*-devnagari-medium-$slant-*-*-*-$scriptsize-*-*-*-*-*-fontspecific"
   .mainfr.editfr.textarea tag config subsubtag -offset -$off2 -font "-*-devnagari-medium-$slant-*-*-*-$scriptscriptsize-*-*-*-*-*-fontspecific"
   .mainfr.editfr.textarea tag config supsubtag -offset -$off3 -font "-*-devnagari-medium-$slant-*-*-*-$scriptscriptsize-*-*-*-*-*-fontspecific"
   .mainfr.editfr.textarea tag config ultag -underline true
}

configTags
foreach point {100 120 150 180 210 250 300 360} {
   .mainfr.editfr.textarea tag config devnagari${point}o -font "-*-devnagari-medium-o-*-*-*-$point-*-*-*-*-*-fontspecific"
   .mainfr.editfr.textarea tag config devnagari${point}r -font "-*-devnagari-medium-r-*-*-*-$point-*-*-*-*-*-fontspecific"
}
.mainfr.editfr.textarea tag config english -font fixed
set customfontno 0

proc supSel {} {
   set lsel [.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   .mainfr.editfr.textarea tag add suptag sel.first sel.last
   .mainfr.editfr.textarea tag remove supsuptag sel.first sel.last
   .mainfr.editfr.textarea tag remove subsuptag sel.first sel.last
   .mainfr.editfr.textarea tag remove subtag sel.first sel.last
   .mainfr.editfr.textarea tag remove subsubtag sel.first sel.last
   .mainfr.editfr.textarea tag remove supsubtag sel.first sel.last
}

proc supsupSel {} {
   set lsel [.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   .mainfr.editfr.textarea tag remove suptag sel.first sel.last
   .mainfr.editfr.textarea tag add supsuptag sel.first sel.last
   .mainfr.editfr.textarea tag remove subsuptag sel.first sel.last
   .mainfr.editfr.textarea tag remove subtag sel.first sel.last
   .mainfr.editfr.textarea tag remove subsubtag sel.first sel.last
   .mainfr.editfr.textarea tag remove supsubtag sel.first sel.last
}

proc subsupSel {} {
   set lsel [.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   .mainfr.editfr.textarea tag remove suptag sel.first sel.last
   .mainfr.editfr.textarea tag remove supsuptag sel.first sel.last
   .mainfr.editfr.textarea tag add subsuptag sel.first sel.last
   .mainfr.editfr.textarea tag remove subtag sel.first sel.last
   .mainfr.editfr.textarea tag remove subsubtag sel.first sel.last
   .mainfr.editfr.textarea tag remove supsubtag sel.first sel.last
}

proc subSel {} {
   set lsel [.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   .mainfr.editfr.textarea tag remove suptag sel.first sel.last
   .mainfr.editfr.textarea tag remove supsuptag sel.first sel.last
   .mainfr.editfr.textarea tag remove subsuptag sel.first sel.last
   .mainfr.editfr.textarea tag add subtag sel.first sel.last
   .mainfr.editfr.textarea tag remove subsubtag sel.first sel.last
   .mainfr.editfr.textarea tag remove supsubtag sel.first sel.last
}

proc subsubSel {} {
   set lsel [.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   .mainfr.editfr.textarea tag remove suptag sel.first sel.last
   .mainfr.editfr.textarea tag remove supsuptag sel.first sel.last
   .mainfr.editfr.textarea tag remove subsuptag sel.first sel.last
   .mainfr.editfr.textarea tag remove subtag sel.first sel.last
   .mainfr.editfr.textarea tag add subsubtag sel.first sel.last
   .mainfr.editfr.textarea tag remove supsubtag sel.first sel.last
}

proc supsubSel {} {
   set lsel [.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   .mainfr.editfr.textarea tag remove suptag sel.first sel.last
   .mainfr.editfr.textarea tag remove supsuptag sel.first sel.last
   .mainfr.editfr.textarea tag remove subsuptag sel.first sel.last
   .mainfr.editfr.textarea tag remove subtag sel.first sel.last
   .mainfr.editfr.textarea tag remove subsubtag sel.first sel.last
   .mainfr.editfr.textarea tag add supsubtag sel.first sel.last
}

proc ulSel {} {
   set lsel [.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   .mainfr.editfr.textarea tag add ultag sel.first sel.last
}

proc normalSel {} {
   global customfontno

   set lsel [.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   .mainfr.editfr.textarea tag remove suptag sel.first sel.last
   .mainfr.editfr.textarea tag remove supsuptag sel.first sel.last
   .mainfr.editfr.textarea tag remove subsuptag sel.first sel.last
   .mainfr.editfr.textarea tag remove subtag sel.first sel.last
   .mainfr.editfr.textarea tag remove subsubtag sel.first sel.last
   .mainfr.editfr.textarea tag remove supsubtag sel.first sel.last
   .mainfr.editfr.textarea tag remove ultag sel.first sel.last
   foreach point {100 120 150 180 210 250 300 360} {
      .mainfr.editfr.textarea tag remove devnagari${point}o sel.first sel.last
      .mainfr.editfr.textarea tag remove devnagari${point}r sel.first sel.last
   }
   .mainfr.editfr.textarea tag remove english sel.first sel.last
   for {set i 0} {$i < $customfontno} {incr i 1} {
      .mainfr.editfr.textarea tag remove customftag$i sel.first sel.last
   }
}

proc fontSel { } {
   global ptsize slant fseltype fselpt fselsl fswin fsgfname
   global fsok customfid customfontno lsel fontlist appbg appfg btnbg btnfg

   set lsel [.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg "Text does not contain a selected region. Select text by left mouse button and retry."
      return
   }

   set fswin [toplevel .fsel]
   set fseltype 0
   set fselpt $ptsize
   set fselsl $slant
   set fsgfname ""

   frame $fswin.bfr -bg $appbg -relief flat
   frame $fswin.efr -bg $appbg -relief flat
   frame $fswin.gfr -bg $appbg -relief flat
   frame $fswin.gfr.fr1 -bg $appbg -relief flat
   frame $fswin.gfr.fr2 -bg $appbg -relief flat
   frame $fswin.ofr -bg $appbg -relief flat
   radiobutton $fswin.bfr.rb  -text "Devnagari: " -variable fseltype -value 0 \
      -relief ridge -selectcolor #bbff00 -fg #000000 -bg #88ccdd \
      -activebackground #88ccdd -activeforeground #000000
   menubutton $fswin.bfr.mb -text "Point size" -height 1 -width 10 \
      -relief raised -menu $fswin.bfr.mb.m -bg $appbg -fg #000000 \
      -activebackground $appbg -activeforeground #000000 -disabledforeground #A2A2A2
   menu $fswin.bfr.mb.m -tearoff false -bg $appbg -fg $appfg
   $fswin.bfr.mb.m add command -label " 100 " -command {$fswin.bfr.mb config -text 100; set fselpt 100}
   $fswin.bfr.mb.m add command -label " 120 " -command {$fswin.bfr.mb config -text 120; set fselpt 120}
   $fswin.bfr.mb.m add command -label " 150 " -command {$fswin.bfr.mb config -text 150; set fselpt 150}
   $fswin.bfr.mb.m add command -label " 180 " -command {$fswin.bfr.mb config -text 180; set fselpt 180}
   $fswin.bfr.mb.m add command -label " 210 " -command {$fswin.bfr.mb config -text 210; set fselpt 210}
   $fswin.bfr.mb.m add command -label " 250 " -command {$fswin.bfr.mb config -text 250; set fselpt 250}
   $fswin.bfr.mb.m add command -label " 300 " -command {$fswin.bfr.mb config -text 300; set fselpt 300}
   $fswin.bfr.mb.m add command -label " 360 " -command {$fswin.bfr.mb config -text 360; set fselpt 360}
   checkbutton $fswin.bfr.cb -text "Slanted" \
      -variable fselsl -onvalue "o" -offvalue "r" -relief flat \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activeforeground #000000 -activebackground $appbg -disabledforeground #A2A2A2
   label $fswin.bfr.space -text "" -relief flat -fg #000000 -bg $appbg
   radiobutton $fswin.efr.rb  -text "English: " -variable fseltype -value 1 \
      -relief ridge -selectcolor #bbff00 -fg #000000 -bg #88ccdd \
      -activebackground #88ccdd -activeforeground #000000
   label $fswin.efr.space -text "" -relief flat -fg #000000 -bg $appbg
   radiobutton $fswin.gfr.fr1.rb  -text "General: " -variable fseltype -value 2 \
      -relief ridge -selectcolor #bbff00 -fg #000000 -bg #88ccdd \
      -activebackground #88ccdd -activeforeground #000000
   entry $fswin.gfr.fr1.e -textvariable fsgfname -width 40 -bg #ddddaa -fg #000000 \
      -state disabled -selectbackground #000000 -selectforeground #ddddaa
   listbox $fswin.gfr.fr2.lbx -bg #ddddaa -fg #A2A2A2 -height 10 \
      -yscroll "$fswin.gfr.fr2.scr set" -relief sunken \
      -selectmode single -selectforeground #ddddaa -selectbackground #A2A2A2 \
      -selectborderwidth 0
   scrollbar $fswin.gfr.fr2.scr -command "$fswin.gfr.fr2.lbx yview" \
      -orient vertical -bg $appbg -width 12 -activebackground $appbg
   set fllen [llength $fontlist]
   for {set idx 0} {$idx < $fllen} {incr idx 1} {
      $fswin.gfr.fr2.lbx insert end [lindex $fontlist $idx]
   }
   bind $fswin.gfr.fr2.lbx <ButtonPress-1> {
      if {$fseltype == 2} {
         set fsgfname [$fswin.gfr.fr2.lbx get [$fswin.gfr.fr2.lbx nearest %y]]
      }
   }
   bind $fswin.gfr.fr2.lbx <ButtonRelease-1> {
      .mainfr.editfr.textarea tag add sel [lindex $lsel 0] [lindex $lsel 1]
   }
   bind $fswin.bfr.rb <ButtonPress-1> {
      $fswin.gfr.fr2.lbx config -fg #A2A2A2 -selectbackground #A2A2A2
      $fswin.bfr.mb config -state active
      $fswin.bfr.cb config -state active
   }
   bind $fswin.efr.rb <ButtonPress-1> {
      $fswin.gfr.fr2.lbx config -fg #A2A2A2 -selectbackground #A2A2A2
      $fswin.bfr.mb config -state disabled
      $fswin.bfr.cb config -state disabled
   }
   bind $fswin.gfr.fr1.rb <ButtonPress-1> {
      $fswin.gfr.fr2.lbx config -fg #000000 -selectbackground #000000
      $fswin.bfr.mb config -state disabled
      $fswin.bfr.cb config -state disabled
   }

   button $fswin.ofr.ok -text " Ok " -relief raised -fg $btnfg -bg $btnbg \
      -activebackground $btnbg -activeforeground $btnfg -command "set fsok 1"
   label $fswin.ofr.space -text "" -relief flat -fg $appfg -bg $appbg
   button $fswin.ofr.cancel -text " Cancel " -relief raised -fg $btnfg -bg $btnbg \
      -activebackground $btnbg -activeforeground $btnfg -command "set fsok 0"

   pack $fswin.bfr.rb $fswin.bfr.mb $fswin.bfr.cb -expand no -side left -padx 5 -pady 0
   pack $fswin.bfr.space -expand yes -fill x -padx 5 -pady 0 -side left
   pack $fswin.efr.rb -expand no -side left -padx 5 -pady 0
   pack $fswin.efr.space -expand yes -fill x -padx 5 -pady 0 -side left
   pack $fswin.gfr.fr1.rb -expand no -side left -padx 5 -pady 0
   pack $fswin.gfr.fr1.e -expand yes -fill x -padx 5 -pady 0 -side left
   pack $fswin.gfr.fr2.scr -side right -expand no -fill y -padx 0 -pady 0
   pack $fswin.gfr.fr2.lbx -side right -expand yes -fill x -padx 0 -pady 0
   pack $fswin.gfr.fr1 -expand yes -fill x -padx 0 -pady 0
   pack $fswin.gfr.fr2 -expand yes -fill x -padx 5 -pady 0
   pack $fswin.ofr.ok -expand no -side left -padx 5 -pady 0
   pack $fswin.ofr.space -expand yes -fill x -padx 5 -pady 0 -side left
   pack $fswin.ofr.cancel -expand no -side left -padx 5 -pady 0
   pack $fswin.bfr $fswin.efr $fswin.gfr $fswin.ofr -padx 5 -pady 10 -expand yes -fill x
   $fswin config -bg $appbg

   wm title $fswin "Selection font"
   wm resizable $fswin false false

   bind $fswin <Escape> "set fsok 0"

   grab $fswin
   tkwait variable fsok
   destroy $fswin

   .mainfr.editfr.textarea tag add sel [lindex $lsel 0] [lindex $lsel 1]
   if {($fsok)} {
      foreach point {100 120 150 180 210 250 300 360} {
         .mainfr.editfr.textarea tag remove devnagari${point}o sel.first sel.last
         .mainfr.editfr.textarea tag remove devnagari${point}r sel.first sel.last
      }
      .mainfr.editfr.textarea tag remove english sel.first sel.last
      for {set i 0} {$i < $customfontno} {incr i 1} {
         .mainfr.editfr.textarea tag remove customftag$i sel.first sel.last
      }
      switch -exact $fseltype {
         0 { .mainfr.editfr.textarea tag add devnagari$fselpt$fselsl sel.first sel.last }
         1 { .mainfr.editfr.textarea tag add english sel.first sel.last }
         2 {
            set inserted 0
            for {set i 0} {($i < $customfontno) && (!$inserted)} {incr i 1} {
               if {![string comp $customfid($i) $fsgfname]} {
                  .mainfr.editfr.textarea tag add customftag$i sel.first sel.last
                  set inserted 1
               }
            }
            if {!($inserted)} {
               .mainfr.editfr.textarea tag config customftag$customfontno -font $fsgfname
               .mainfr.editfr.textarea tag add customftag$customfontno sel.first sel.last
               set customfid($customfontno) $fsgfname
               incr customfontno 1
            }
         }
      }
   }
}

proc saveTags {} {
   global customfontno customfid

   set fn [getFileName "dvedit: Save tags"]
   if { [string compare $fn ""] != 0 } {
      set dnm [file dirname $fn]
      if {![file isdirectory $dnm]} {
         errmsg "ERROR:\nI cannot save the file. \"$dnm\" is not a directory."
         return
      }
      if {![file writable $dnm]} {
         errmsg "ERROR:\nI cannot save the file. You do not have permission to write in the directory \"$dnm\"."
        return
      }
      if {[file exists $fn] && ![file isfile $fn]} {
         errmsg "ERROR:\nI cannot save the file. \"$fn\" is not a regular file."
         return
      }
      if {[file exists $fn] && ![file writable $fn]} {
         errmsg "ERROR:\nI cannot save the file. You do not have permission to overwrite \"$fn\""
         return
      }

      set f [open $fn w]
      foreach tagname { ultag suptag supsuptag subsuptag subtag subsubtag supsubtag english } {
         set tagranges [.mainfr.editfr.textarea tag ranges $tagname]
         if {[llength $tagranges] > 0} { puts $f "$tagname\t: $tagranges" }
      }
      foreach point {100 120 150 180 210 250 300 360} {
         set tagranges [.mainfr.editfr.textarea tag ranges devnagari${point}o ]
         if {[llength $tagranges] > 0} { puts $f "devnagari${point}o\t: $tagranges" }
         set tagranges [.mainfr.editfr.textarea tag ranges devnagari${point}r ]
         if {[llength $tagranges] > 0} { puts $f "devnagari${point}r\t: $tagranges" }
      }
      for {set i 0} {$i < $customfontno} {incr i 1} {
         set tagname customftag$i
         set tagranges [.mainfr.editfr.textarea tag ranges $tagname]
         if {[llength $tagranges] > 0} {
            set fid $customfid($i)
            puts $f "customfont\t: $fid\t$tagranges"
         }
      }
      close $f
   }
}

proc loadTags { {flag 0} {tfname "" } } {

   if {$flag} { set fn $tfname } else { set fn [getFileName "dvedit: Load tags"] }
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         errmsg "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         return
      }
      set f [open $fn r]
      foreach line [split [read $f] "\n"] {
         addTag $line
      }
      close $f
   }
}

proc selectAll {} {
   .mainfr.editfr.textarea tag add sel 1.0 end
}

set firstarg [lindex $argv 0]
if { [string compare $firstarg ""] } {
   set fname $firstarg
   if { [file exists $firstarg] } {
      loadThisFile
      set secondarg [lindex $argv 1]
      if { [string compare $secondarg ""] && [file exists $secondarg] } {
         loadTags 1 $secondarg
      }
   } else {
      wm title . "dvedit: $firstarg (New)"
   }
} else {
   set fname ""
   wm title . "dvedit: (No file)"
}
set browsedir [exec pwd]

proc getExportFileName {} {
   global efname verbatim omithdr ok appbg appfg btnbg btnfg

   set dbox [toplevel .export]
   frame $dbox.fr1
   frame $dbox.fr2
   frame $dbox.fr3
   frame $dbox.fr4
   label $dbox.fr1.lbl -text "Export to file:" -relief flat -anchor e -bg $appbg -fg $appfg
   entry $dbox.fr1.ent -textvariable efname -bg #ddaaaa -fg #000000
   label $dbox.fr2.lbl -text "Document title:" -relief flat -anchor e -bg $appbg -fg $appfg
   entry $dbox.fr2.ent -textvariable doctitle -bg #ddaaaa -fg #000000
   checkbutton $dbox.fr3.cb -text "  Verbatim copy " -variable verbatim -onvalue 1 -offvalue 0 -relief raised -selectcolor #bbff00 -bg $appbg -fg $appfg -activebackground $appbg -activeforeground $appfg
   checkbutton $dbox.fr3.oh -text "  Omit headers " -variable omithdr -onvalue 1 -offvalue 0 -relief raised -selectcolor #bbff00 -bg $appbg -fg $appfg -activebackground $appbg -activeforeground $appfg
   button $dbox.fr4.obtn -text "OK" -command {set ok 1} -width 6 -fg $btnfg -bg $btnbg -activebackground $btnbg -activeforeground $btnfg
   button $dbox.fr4.cbtn -text "Cancel" -command {set ok 0} -width 6 -fg $btnfg -bg $btnbg -activebackground $btnbg -activeforeground $btnfg
   label $dbox.fr4.space -text "" -relief flat -bg $appbg -fg $appfg
   bind $dbox.fr1.ent <Return> "focus $dbox.fr2.ent"
   bind $dbox.fr2.ent <Return> {set ok 1}
   bind $dbox <Escape> {set ok 0}

   pack $dbox.fr1 $dbox.fr2 $dbox.fr3 -expand yes -fill x
   pack $dbox.fr4 -expand yes -fill both
   pack $dbox.fr1.lbl -padx 5 -pady 5 -expand yes -fill x -side left
   pack $dbox.fr1.ent -padx 5 -pady 5
   pack $dbox.fr2.lbl -padx 5 -pady 5 -expand yes -fill x -side left
   pack $dbox.fr2.ent -padx 5 -pady 5
   pack $dbox.fr3.cb  -padx 5 -pady 5
   pack $dbox.fr3.oh  -padx 5 -pady 5
   pack $dbox.fr4.obtn -padx 5 -pady 5 -fill y -side left
   pack $dbox.fr4.space -padx 5 -pady 5 -expand yes -fill x -side left
   pack $dbox.fr4.cbtn -padx 5 -pady 5 -fill y
   $dbox config -bg $appbg
   $dbox.fr1 config -bg $appbg
   $dbox.fr2 config -bg $appbg
   $dbox.fr3 config -bg $appbg
   $dbox.fr4 config -bg $appbg

   wm title $dbox "dvedit: export"
   wm resizable $dbox false false

   focus $dbox.fr1.ent
   grab $dbox
   tkwait variable ok
   grab release $dbox
   destroy $dbox

   if {$ok} {
      return [string trim $efname]
   } else {
      return ""
   }
}

proc exportLaTeX {} {
   global fname efname verbatim omithdr doctitle customfontno ptsize slant
   global stylefile

   if { [string compare $fname ""] != 0 } {
      set dotindex [string last "." $fname]
      incr dotindex -1
   } else {
      set dotindex -1
   }
   if {$dotindex >= 0} {
      set efname [string range $fname 0 $dotindex]
      set efname "$efname.tex"
   } else {
      set efname "$fname.tex"
   }
   set verbatim 0
   set omithdr 0
   set doctitle ""
   set efn [getExportFileName]
   if { [string compare $efn ""] != 0 } {
      switch -exact $ptsize {
         100 { set bndft "\\dv\\small" ; set ss "\\dv\\tiny" ; set sss "\\dv\\tiny" }
         150 { set bndft "\\dv\\large" ; set ss "\\dv" ; set sss "\\dv\\small" }
         180 { set bndft "\\dv\\Large" ; set ss "\\dv\\large" ; set sss "\\dv" }
         210 { set bndft "\\dv\\LARGE" ; set ss "\\dv\\Large" ; set sss "\\dv\\large" }
         250 { set bndft "\\dv\\huge" ; set ss "\\dv\\LARGE" ; set sss "\\dv\\Large" }
         300 { set bndft "\\dv\\Huge" ; set ss "\\dv\\huge" ; set sss "\\dv\\LARGE" }
         360 { set bndft "\\dv\\Huge" ; set ss "\\dv\\huge" ; set sss "\\dv\\LARGE" }
         default {set bndft "\\dv" ; set ss "\\dv\\small" ; set sss "\\dv\\tiny" }
      }
      if {![string compare "o" $slant]} { set bndft "$bndft\\sl" }
      foreach tagname {suptag supsuptag subsuptag subtag subsubtag supsubtag english} {
         set ${tagname}rng [.mainfr.editfr.textarea tag ranges $tagname]
      }
      for {set i 0} {$i < $customfontno} {incr i 1} {
         set englishrng [concat $englishrng [.mainfr.editfr.textarea tag ranges customftag$i]]
      }
      set smallrng [.mainfr.editfr.textarea tag ranges devnagari100r]
      set normalsizerng [.mainfr.editfr.textarea tag ranges devnagari120r]
      set largerng [.mainfr.editfr.textarea tag ranges devnagari150r]
      set Largerng [.mainfr.editfr.textarea tag ranges devnagari180r]
      set LARGErng [.mainfr.editfr.textarea tag ranges devnagari210r]
      set hugerng [.mainfr.editfr.textarea tag ranges devnagari250r]
      set Hugerng [lsort -real -increasing [concat \
         [.mainfr.editfr.textarea tag ranges devnagari300r] \
         [.mainfr.editfr.textarea tag ranges devnagari360r]]]
      set smallslrng [.mainfr.editfr.textarea tag ranges devnagari100o]
      set normalsizeslrng [.mainfr.editfr.textarea tag ranges devnagari120o]
      set largeslrng [.mainfr.editfr.textarea tag ranges devnagari150o]
      set Largeslrng [.mainfr.editfr.textarea tag ranges devnagari180o]
      set LARGEslrng [.mainfr.editfr.textarea tag ranges devnagari210o]
      set hugeslrng [.mainfr.editfr.textarea tag ranges devnagari250o]
      set Hugeslrng [lsort -real -increasing [concat \
         [.mainfr.editfr.textarea tag ranges devnagari300o] \
         [.mainfr.editfr.textarea tag ranges devnagari360o]]]

      foreach scriptrng { \$suptagrng \$subtagrng \$supsuptagrng \$subsuptagrng \$subsubtagrng \$supsubtagrng } {
         set srlen [ eval llength $scriptrng ]
         if {$srlen > 0} {
            foreach tagrng { \$normalsizerng \$smallrng \$largerng \$Largerng \$LARGErng \$hugerng \$Hugerng \$englishrng \$normalsizeslrng \$smallslrng \$largeslrng \$Largeslrng \$LARGEslrng \$hugeslrng \$Hugeslrng } {
               set trlen [ eval llength $tagrng ]
               if {$trlen > 0} {
                  for {set i 0} {$i < $srlen} {incr i 2} {
                     for {set j 0} {$j < $trlen} {incr j 1} {
                        set si [eval lindex $scriptrng $i]
                        set ti1 [eval lindex $tagrng $j]
                        incr j 1
                        set ti2 [eval lindex $tagrng $j]
                        if { ($ti1 < $si) && ($ti2 > $si) } {
                           set [string range $tagrng 1 [expr [string length $tagrng] - 1]] [eval linsert $tagrng $j $si $si]
                           incr trlen 2
                        }
                     }
                  }
                  for {set i 1} {$i < $srlen} {incr i 2} {
                     for {set j 0} {$j < $trlen} {incr j 1} {
                        set si [eval lindex $scriptrng $i]
                        set ti1 [eval lindex $tagrng $j]
                        incr j 1
                        set ti2 [eval lindex $tagrng $j]
                        if { ($ti1 < $si) && ($ti2 > $si) } {
                           set [string range $tagrng 1 [expr [string length $tagrng] - 1]] [eval linsert $tagrng $j $si $si]
                           incr trlen 2
                        }
                     }
                  }
               }
            }
         }
      }

      set f [open $efn w]
      puts $f "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
      puts $f "%% Filename: $efname"
      puts $f "%% Original file: $fname"
      puts $f "%% Exported by: dvedit version 1.0"
      puts $f "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
      if {$omithdr == 0} {
         puts $f "\\documentstyle\[11pt\]\{article\}"
         puts $f "\\input $stylefile"
         puts $f "\\parindent 0pt"
         puts $f "\\parskip 10pt"
         puts $f "\\hbadness 10000"
         if { [string compare $doctitle ""] != 0 } {
            puts $f "\\pagestyle\{myheadings\}"
            puts $f "\\markboth\{$doctitle\}\{$doctitle\}"
         }
         puts $f "\\begin\{document\}"
      }
      puts $f "\\begingroup$bndft\\leavevmode"
      set ins [.mainfr.editfr.textarea get 1.0 end]
      set inl [string length $ins]
      set lineno 1
      set charno 0
      set englishmode 0
      set tagshere {}
      for {set i 0} {$i < $inl} {incr i 1} {
         if {[lsearch -regexp $tagshere "devnagari"] >= 0} {
            foreach tagname { \$normalsizerng \$smallrng \$largerng \$Largerng \$LARGErng \$hugerng \$Hugerng \$normalsizeslrng \$smallslrng \$largeslrng \$Largeslrng \$LARGEslrng \$hugeslrng \$Hugeslrng } {
               set ridx [eval lsearch -exact $tagname $lineno.$charno]
               if { ($ridx >= 0) && ($ridx & 1) } { puts -nonewline $f "\}" }
            }
         }
         set ridx [lsearch -exact $englishrng $lineno.$charno]
         if { ($ridx >= 0) && ($ridx & 1) } {
            puts -nonewline $f "\}"
            incr englishmode -1
         }
         set suidx [lsearch -regexp $tagshere "su"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            set ridx [eval lsearch -exact \$${tagname}rng $lineno.$charno]
            if { ($ridx >= 0) && ($ridx & 1) } {
               if {[string length $tagname] == 6} {
                  puts -nonewline $f "\}\}\$"
               } else {
                  puts -nonewline $f "\}\}\}\$"
               }
            }
         }
         set tagshere [.mainfr.editfr.textarea tag names "$lineno.$charno"]
         set suidx [lsearch -regexp $tagshere "su"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            switch -exact $tagname {
               suptag {
                  set ridx [lsearch -exact $suptagrng $lineno.$charno]
                  if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f "\$^\{\\hbox\{$ss " }
               }
               subtag {
                  set ridx [lsearch -exact $subtagrng $lineno.$charno]
                  if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f "\$_\{\\hbox\{$ss " }
               }
               supsuptag {
                  set ridx [lsearch -exact $supsuptagrng $lineno.$charno]
                  if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f "\$^\{^\{\\hbox\{$sss " }
               }
               subsuptag {
                  set ridx [lsearch -exact $subsuptagrng $lineno.$charno]
                  if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f "\$^\{_\{\\hbox\{$sss " }
               }
               subsubtag {
                  set ridx [lsearch -exact $subsubtagrng $lineno.$charno]
                  if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f "\$_\{_\{\\hbox\{$sss " }
               }
               subsubtag {
                  set ridx [lsearch -exact $supsubtagrng $lineno.$charno]
                  if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f "\$_\{^\{\\hbox\{$sss " }
               }
            }
         }
         set ridx [lsearch -exact $englishrng $lineno.$charno]
         if { ($ridx >= 0) } {
            if { !($ridx & 1) } {
               incr englishmode 1 ; puts -nonewline $f "\{\\rm "
            } else {
               incr ridx 1
               if { ($ridx < [llength $englishrng]) && ("$lineno.$charno" == [lindex $englishrng $ridx]) } {
                  incr englishmode 1 ; puts -nonewline $f "\{\\rm "
               }
            }
         }
         if {[lsearch -regexp $tagshere "devnagari"] >= 0} {
            foreach tagname { normalsize small large Large LARGE huge Huge } {
               set ridx [eval lsearch -exact \$${tagname}rng $lineno.$charno]
               if { ($ridx >= 0) } {
                  if { !($ridx & 1) } {
                     puts -nonewline $f "\{\\$tagname\\nsl "
                  } else {
                     incr ridx 1
                     if { ($ridx < [eval llength  \$${tagname}rng]) && ("$lineno.$charno" == [eval lindex \$${tagname}rng $ridx]) } {
                        puts -nonewline $f "\{\\$tagname\\nsl "
                     }
                  }
               }
               set ridx [eval lsearch -exact \$${tagname}slrng $lineno.$charno]
               if { ($ridx >= 0) } {
                  if { !($ridx & 1) } {
                     puts -nonewline $f "\{\\$tagname\\sl "
                  } else {
                     incr ridx 1
                     if { ($ridx < [eval llength  \$${tagname}rng]) && ("$lineno.$charno" == [eval lindex \$${tagname}slrng $ridx]) } {
                        puts -nonewline $f "\{\\$tagname\\sl "
                     }
                  }
               }
            }
         }
         set nextchar [string range $ins $i $i]
         scan $nextchar "%c" asciival
         if {$asciival == 10} { set charno 0 ; incr lineno 1 } else { incr charno 1 }
         if {($englishmode & 1)} {
            switch -exact $asciival {
               10 { if {$verbatim} {
                       puts $f "\\null\\\\\\null"
                    } else {
                       puts $f ""
                    }
               }
               32 { if {$verbatim} {
                       puts -nonewline $f "\\ "
                    } else {
                       puts -nonewline $f " "
                    }
               }
               35 { puts -nonewline $f "\\#" }
               36 { puts -nonewline $f "\\\$" }
               37 { puts -nonewline $f "\\%" }
               38 { puts -nonewline $f "\\&" }
               60 { puts -nonewline $f "\$<\$" }
               62 { puts -nonewline $f "\$>\$" }
               91 { puts -nonewline $f "\$\[\$" }
               92 { puts -nonewline $f "\$\\backslash\$" }
               93 { puts -nonewline $f "\$\]\$" }
               94 { puts -nonewline $f "\{\\char94\}" }
               95 { puts -nonewline $f "\\_" }
               123 { puts -nonewline $f "\\\{" }
               124 { puts -nonewline $f "\$|\$" }
               125 { puts -nonewline $f "\\\}" }
               126 { puts -nonewline $f "\$\\tilde\{\\phantom\{1\}\}\$" }
               169 { puts -nonewline $f "\\copyright\{\}" }
               215 { puts -nonewline $f "\$\\times\$" }
               247 { puts -nonewline $f "\$\\div\$" }
               default { puts -nonewline $f $nextchar }
            }
         } else {
            switch -exact $asciival {
                3 { puts -nonewline $f "\\kern-.52em\{\\char3\}\\kern-.25em" }
                4 { puts -nonewline $f "\\kern-.34em\{\\char4\}\\kern-.2em" }
                8 { puts -nonewline $f "\{\\char0\}" }
                9 { puts -nonewline $f "\t" }
               10 { if {$verbatim} {
                       puts $f "\\null\\\\\\null"
                    } else {
                       puts $f ""
                    }
                  }
               19 { puts -nonewline $f "\\kern-.1em\{\\char19\}\\kern-.2em" }
               21 { puts -nonewline $f "\{\\char9\}" }
               30 { puts -nonewline $f "\{\\char10\}" }
               32 { if {$verbatim} {
                       puts -nonewline $f "\\ "
                    } else {
                       puts -nonewline $f " "
                    }
                  }
               35 { puts -nonewline $f "\\#" }
               36 { puts -nonewline $f "\{\\char36\}" }
               37 { puts -nonewline $f "\\%" }
               38 { puts -nonewline $f "\{\\char38\}" }
               60 { puts -nonewline $f ".." }
               62 { puts -nonewline $f "\{\\char62\}" }
               64 { puts -nonewline $f "\{\\char64\}" }
               91 { puts -nonewline $f "\{\\char91\}" }
               92 { puts -nonewline $f "\\kern-.1em\{\\char92\}\\kern-.2em" }
               93 { puts -nonewline $f "\{\\char93\}" }
               94 { puts -nonewline $f "\{\\char94\}" }
               95 { puts -nonewline $f "\{\\char95\}" }
              123 { puts -nonewline $f "\\kern-.52em\{\\char123\}\\kern-.25em" }
              125 { puts -nonewline $f "\\kern-.65em\{\\char125\}" }
              132 { puts -nonewline $f "\\kern-.1em\{\\char13\}\\kern-.22em" }
              134 { puts -nonewline $f "\{\\char127\}" }
              253 { puts -nonewline $f "\\kern-.65em\{\\char253\}\\kern.65em" }
              255 { puts -nonewline $f "\\kern-.34em\{\\char32\}\\kern-.2em" }
               default {
                  if { $asciival < 32 } {
                     puts -nonewline $f "\{\\char$asciival\}"
                  } elseif { $asciival >= 124 } {
                     puts -nonewline $f "\{\\char$asciival\}"
                  } else {
                     puts -nonewline $f $nextchar
                  }
               }
            }
         }
      }
      puts $f "\\endgroup"
      if {$omithdr == 0} { puts $f "\\end\{document\}" }
      puts $f "%% End of file"
      close $f
   }
}

proc exportHTML {} {
   global fname efname verbatim omithdr doctitle ptsize slant customfontno

   if { [string compare $fname ""] != 0 } {
      set dotindex [string last "." $fname]
      incr dotindex -1
   } else {
      set dotindex -1
   }
   if {$dotindex >= 0} {
      set efname [string range $fname 0 $dotindex]
      set efname "$efname.html"
   } else {
      set efname "$fname.html"
   }
   set verbatim 0
   set omithdr 0
   set doctitle "untitled"
   set efn [getExportFileName]
   if { [string compare $efn ""] != 0 } {
      foreach tagname {suptag supsuptag subsuptag subtag subsubtag supsubtag english} {
         set ${tagname}rng [.mainfr.editfr.textarea tag ranges $tagname]
      }
      for {set i 0} {$i < $customfontno} {incr i 1} {
         set englishrng [concat $englishrng [.mainfr.editfr.textarea tag ranges customftag$i]]
      }
      set englishrng [lsort -real -increasing $englishrng]
      set size1rng [.mainfr.editfr.textarea tag ranges devnagari100r]
      set size2rng [.mainfr.editfr.textarea tag ranges devnagari120r]
      set size3rng [.mainfr.editfr.textarea tag ranges devnagari150r]
      set size4rng [.mainfr.editfr.textarea tag ranges devnagari180r]
      set size5rng [.mainfr.editfr.textarea tag ranges devnagari210r]
      set size6rng [.mainfr.editfr.textarea tag ranges devnagari250r]
      set size7rng [lsort -real -increasing [concat \
         [.mainfr.editfr.textarea tag ranges devnagari300r] \
         [.mainfr.editfr.textarea tag ranges devnagari360r]]]
      set size1slrng [.mainfr.editfr.textarea tag ranges devnagari100o]
      set size2slrng [.mainfr.editfr.textarea tag ranges devnagari120o]
      set size3slrng [.mainfr.editfr.textarea tag ranges devnagari150o]
      set size4slrng [.mainfr.editfr.textarea tag ranges devnagari180o]
      set size5slrng [.mainfr.editfr.textarea tag ranges devnagari210o]
      set size6slrng [.mainfr.editfr.textarea tag ranges devnagari250o]
      set size7slrng [lsort -real -increasing [concat \
         [.mainfr.editfr.textarea tag ranges devnagari300o] \
         [.mainfr.editfr.textarea tag ranges devnagari360o]]]
      foreach scriptrng { \$suptagrng \$subtagrng \$supsuptagrng \$subsuptagrng \$subsubtagrng \$supsubtagrng } {
         set srlen [ eval llength $scriptrng ]
         if {$srlen > 0} {
            foreach tagrng { \$englishrng \$size1rng \$size2rng \$size3rng \$size4rng \$size5rng \$size6rng \$size7rng \$size1slrng \$size2slrng \$size3slrng \$size4slrng \$size5slrng \$size6slrng \$size7slrng } {
               set trlen [ eval llength $tagrng ]
               if {$trlen > 0} {
                  for {set i 0} {$i < $srlen} {incr i 2} {
                     for {set j 0} {$j < $trlen} {incr j 1} {
                        set si [eval lindex $scriptrng $i]
                        set ti1 [eval lindex $tagrng $j]
                        incr j 1
                        set ti2 [eval lindex $tagrng $j]
                        if { ($ti1 < $si) && ($ti2 > $si) } {
                           set [string range $tagrng 1 [expr [string length $tagrng] - 1]] [eval linsert $tagrng $j $si $si]
                           incr trlen 2
                        }
                     }
                  }
                  for {set i 1} {$i < $srlen} {incr i 2} {
                     for {set j 0} {$j < $trlen} {incr j 1} {
                        set si [eval lindex $scriptrng $i]
                        set ti1 [eval lindex $tagrng $j]
                        incr j 1
                        set ti2 [eval lindex $tagrng $j]
                        if { ($ti1 < $si) && ($ti2 > $si) } {
                           set [string range $tagrng 1 [expr [string length $tagrng] - 1]] [eval linsert $tagrng $j $si $si]
                           incr trlen 2
                        }
                     }
                  }
               }
            }
         }
      }
      
      set f [open $efn w]
      puts $f "<!--------------------------------------------------------->"
      puts $f "<!-- Filename: $efname -->"
      puts $f "<!-- Original file: $fname -->"
      puts $f "<!-- Exported by: dvedit version 1.0 -->"
      puts $f "<!--------------------------------------------------------->"
      if {$omithdr == 0} {
         puts $f "<HTML>"
         puts $f "<HEAD><TITLE>$doctitle</TITLE></HEAD>"
      }
      switch -exact $ptsize {
         100 { puts $f "<BASEFONT SIZE=2>" }
         150 { puts $f "<BASEFONT SIZE=4>" }
         180 { puts $f "<BASEFONT SIZE=5>" }
         210 { puts $f "<BASEFONT SIZE=6>" }
         250 { puts $f "<BASEFONT SIZE=7>" }
         300 { puts $f "<BASEFONT SIZE=7>" }
         360 { puts $f "<BASEFONT SIZE=7>" }
      }
      if {$omithdr == 0} { puts $f "<BODY>" }
      set ins [.mainfr.editfr.textarea get 1.0 end]
      set inl [string length $ins]
      set lineno 1
      set charno 0
      set tagshere {}
      set opsctg(sup) "<SUP>"
      set opsctg(sub) "<SUB>"
      set opsctg(supsup) "<SUP><SUP>"
      set opsctg(subsup) "<SUP><SUB>"
      set opsctg(subsub) "<SUB><SUB>"
      set opsctg(supsub) "<SUB><SUP>"
      set clsctg(sup) "</SUP>"
      set clsctg(sub) "</SUB>"
      set clsctg(supsup) "</SUP></SUP>"
      set clsctg(subsup) "</SUB></SUP>"
      set clsctg(subsub) "</SUB></SUB>"
      set clsctg(supsub) "</SUP></SUB>"
      for {set i 0} {$i < $inl} {incr i 1} {
         if {[lsearch -regexp $tagshere "devnagari"] >= 0} {
            foreach tagname { \$size1rng \$size2rng \$size3rng \$size4rng \$size5rng \$size6rng \$size7rng } {
               set ridx [eval lsearch -exact $tagname $lineno.$charno]
               if { ($ridx >= 0) && ($ridx & 1) } {
                  puts -nonewline $f "</FONT>"
               }
            }
            foreach tagname { \$size1slrng \$size2slrng \$size3slrng \$size4slrng \$size5slrng \$size6slrng \$size7slrng } {
               set ridx [eval lsearch -exact $tagname $lineno.$charno]
               if { ($ridx >= 0) && ($ridx & 1) } {
                  puts -nonewline $f "</I></FONT>"
               }
            }
         }
         set ridx [lsearch -exact $englishrng $lineno.$charno]
         if { ($ridx >= 0) && ($ridx & 1) } { puts -nonewline $f "</TT>" }
         set suidx [lsearch -regexp $tagshere "su"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            set tagname [string range $tagname 0 [expr [string length $tagname] - 4]]
            set ridx [eval lsearch -exact \$${tagname}tagrng $lineno.$charno]
            if { ($ridx >= 0) && ($ridx & 1) } { puts -nonewline $f $clsctg($tagname) }
         }
         set tagshere [.mainfr.editfr.textarea tag names "$lineno.$charno"]
         set suidx [lsearch -regexp $tagshere "su"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            set tagname [string range $tagname 0 [expr [string length $tagname] - 4]]
            set ridx [eval lsearch -exact \$${tagname}tagrng $lineno.$charno]
            if { ($ridx >= 0) && !($ridx & 1) } { puts -nonewline $f $opsctg($tagname) }
         }
         set ridx [lsearch -exact $englishrng $lineno.$charno]
         if {($ridx >= 0)} {
            if { !($ridx & 1) } { puts -nonewline $f "<TT>" } else {
               incr ridx 1
               if { ($ridx < [llength $englishrng]) && ("$lineno.$charno" == [lindex $englishrng $ridx]) } {
                   puts -nonewline $f "<TT>"
               }
            }
         }
         if {[lsearch -regexp $tagshere "devnagari"] >= 0} {
            for {set ftsz 1} {$ftsz <= 7} {incr ftsz 1} {
               set ridx [eval lsearch -exact \$size${ftsz}rng $lineno.$charno]
               if {($ridx >= 0)} {
                  if { !($ridx & 1) } {
                     puts -nonewline $f "<FONT SIZE=$ftsz>"
                  } else {
                     incr ridx 1
                     if { ($ridx < [eval llength \$size${ftsz}rng]) && ("$lineno.$charno" == [eval lindex \$size${ftsz}rng $ridx]) } {
                        puts -nonewline $f "<FONT SIZE=$ftsz>"
                     }
                  }
               }
               set ridx [eval lsearch -exact \$size${ftsz}slrng $lineno.$charno]
               if {($ridx >= 0)} {
                  if { !($ridx & 1) } {
                     puts -nonewline $f "<FONT SIZE=$ftsz><I>"
                  } else {
                     incr ridx 1
                     if { ($ridx < [eval llength \$size${ftsz}slrng]) && ("$lineno.$charno" == [eval lindex \$size${ftsz}slrng $ridx]) } {
                        puts -nonewline $f "<FONT SIZE=$ftsz><I>"
                     }
                  }
               }
            }
         }
         set nextchar [string range $ins $i $i]
         scan $nextchar "%c" asciival
         if {$asciival == 10} { set charno 0 ; incr lineno 1 } else { incr charno 1 }
         switch -exact $asciival {
            34 { puts -nonewline $f "&quot;" }
            38 { puts -nonewline $f "&amp;" }
            60 { puts -nonewline $f "&lt;" }
            62 { puts -nonewline $f "&gt;" }
             9 { if {$verbatim} {
                    puts -nonewline $f "&nbsp;"
                 } else {
                    puts  -nonewline $f "\t"
                 }
               }
            10 { if {$verbatim} {
                    puts $f "<BR>"
                 } else {
                    incr i 1
                    set nextnextchar [string range $ins $i $i]
                    if { [string compare $nextnextchar "\n"] == 0 } {
                       puts $f "\n<P>"
                    } else {
                       incr i -1
                       puts $f ""
                    }
                 }
               }
            32 { if {$verbatim} {
                    puts -nonewline $f "&nbsp;"
                 } else {
                    puts -nonewline $f " "
                 }
               }
            default {
               if { $asciival < 32 } {
                  puts -nonewline $f "&#$asciival;"
               } elseif { $asciival >= 128 } {
                  puts -nonewline $f "&#$asciival;"
               } else {
                  puts -nonewline $f $nextchar
               }
            }
         }
      }
      if {$omithdr == 0} {
         puts $f "</BODY>"
         puts $f "</HTML>"
      }
      puts $f "<!-- End of file -->"
      close $f
   }
}

proc getPSFileName {} {
   global efname pt pageheight textheight xoffset yoffset ok
   global btnbg btnfg appbg appfg

   set dbox [toplevel .export]
   frame $dbox.fr1
   frame $dbox.fr2
   frame $dbox.fr3
   frame $dbox.fr4
   frame $dbox.fr5
   frame $dbox.fr6
   frame $dbox.fr6a
   frame $dbox.fr7
   label $dbox.fr1.lbl -text "Export to file:" -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.fr1.ent -textvariable efname -bg #ddaaaa -fg #000000
   label $dbox.fr2.lbl -text "Point size:" -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.fr2.ent -textvariable pt -bg #ddaaaa -fg #000000
   label $dbox.fr3.lbl -text "Text height (cm)" -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.fr3.ent -textvariable textheight -bg #ddaaaa -fg #000000
   label $dbox.fr4.lbl -text "X offset (cm)" -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.fr4.ent -textvariable xoffset -bg #ddaaaa -fg #000000
   label $dbox.fr5.lbl -text "Y offset (cm)" -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.fr5.ent -textvariable yoffset -bg #ddaaaa -fg #000000
   label $dbox.fr6.lbl -text "Page height (cm)" -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.fr6.ent -textvariable pageheight -bg #ddaaaa -fg #000000
   label $dbox.fr6a.lbl -text "Paper" -relief flat -anchor e -fg $appfg -bg $appbg
   menubutton $dbox.fr6a.btn -text "A4" -height 1 -width 10 -relief raised \
      -menu $dbox.fr6a.btn.m -bg $appbg -fg $appfg \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
   menu $dbox.fr6a.btn.m -tearoff false -bg $appbg -fg $appfg
   $dbox.fr6a.btn.m add command -label "  A3" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 42.0; set textheight 37.0; $dbox.fr6a.btn config -text A3"
   $dbox.fr6a.btn.m add command -label "  A4" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 29.7; set textheight 24.7; $dbox.fr6a.btn config -text A4"
   $dbox.fr6a.btn.m add command -label "  A5" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 21.0; set textheight 16.0; $dbox.fr6a.btn config -text A5"
   $dbox.fr6a.btn.m add command -label "  B4" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 36.4; set textheight 31.4; $dbox.fr6a.btn config -text B4"
   $dbox.fr6a.btn.m add command -label "  B5" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 25.7; set textheight 20.7; $dbox.fr6a.btn config -text B5"
   $dbox.fr6a.btn.m add command -label "  Executive" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 25.4; set textheight 20.4; $dbox.fr6a.btn config -text Executive"
   $dbox.fr6a.btn.m add command -label "  Folio" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 33.0; set textheight 28.0; $dbox.fr6a.btn config -text Folio"
   $dbox.fr6a.btn.m add command -label "  Ledger" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 27.9; set textheight 22.9; $dbox.fr6a.btn config -text Ledger"
   $dbox.fr6a.btn.m add command -label "  Legal" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 35.6; set textheight 30.6; $dbox.fr6a.btn config -text Legal"
   $dbox.fr6a.btn.m add command -label "  Letter" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 27.9; set textheight 22.9; $dbox.fr6a.btn config -text Letter"
   $dbox.fr6a.btn.m add command -label "  Quarto" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 27.5; set textheight 22.5; $dbox.fr6a.btn config -text Quarto"
   $dbox.fr6a.btn.m add command -label "  Statement" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 21.6; set textheight 16.6; $dbox.fr6a.btn config -text Statement"
   $dbox.fr6a.btn.m add command -label "  Tabloid" -command "set xoffset 2.5; set yoffset 2.5; set pageheight 43.2; set textheight 38.2; $dbox.fr6a.btn config -text Tabloid"
   button $dbox.fr7.obtn -text "OK" -command {set ok 1} -width 6 -fg $btnfg -bg $btnbg -activebackground $btnbg -activeforeground $btnfg
   button $dbox.fr7.cbtn -text "Cancel" -command {set ok 0} -width 6 -fg $btnfg -bg $btnbg -activebackground $btnbg -activeforeground $btnfg
   label $dbox.fr7.space -text "" -relief flat -fg $appfg -bg $appbg
   pack $dbox.fr1 $dbox.fr2 $dbox.fr3 $dbox.fr4 $dbox.fr5 $dbox.fr6 -expand yes -fill x
   pack $dbox.fr6a -expand no
   pack $dbox.fr7 -expand yes -fill x
   pack $dbox.fr1.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr1.ent -padx 5 -pady 5
   pack $dbox.fr2.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr2.ent -padx 5 -pady 5
   pack $dbox.fr3.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr3.ent -padx 5 -pady 5
   pack $dbox.fr4.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr4.ent -padx 5 -pady 5
   pack $dbox.fr5.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr5.ent -padx 5 -pady 5
   pack $dbox.fr6.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr6.ent -padx 5 -pady 5
   pack $dbox.fr6a.lbl -padx 5 -pady 5 -side left -expand no
   pack $dbox.fr6a.btn -padx 5 -pady 5
   pack $dbox.fr7.obtn -padx 5 -pady 5 -side left
   pack $dbox.fr7.space -padx 5 -pady 5  -side left -expand yes -fill x
   pack $dbox.fr7.cbtn -padx 5 -pady 5 -fill y
   $dbox config -bg $appbg
   $dbox.fr1 config -bg $appbg
   $dbox.fr2 config -bg $appbg
   $dbox.fr3 config -bg $appbg
   $dbox.fr4 config -bg $appbg
   $dbox.fr5 config -bg $appbg
   $dbox.fr6 config -bg $appbg
   $dbox.fr6a config -bg $appbg
   $dbox.fr7 config -bg $appbg
   bind $dbox <Escape> {set ok 0}
   bind $dbox.fr1.ent <Return>  "focus $dbox.fr2.ent"
   bind $dbox.fr2.ent <Return>  "focus $dbox.fr3.ent"
   bind $dbox.fr3.ent <Return>  "focus $dbox.fr4.ent"
   bind $dbox.fr4.ent <Return>  "focus $dbox.fr5.ent"
   bind $dbox.fr5.ent <Return>  "focus $dbox.fr6.ent"
   bind $dbox.fr6.ent <Return>  {set ok 1}

   wm title $dbox "dvedit: export"
   wm resizable $dbox false false

   focus $dbox.fr1.ent
   grab $dbox
   tkwait variable ok
   grab release $dbox
   destroy $dbox

   if {$ok} {
      return [string trim $efname]
   } else {
      return ""
   }
}

proc exportPS {} {
   global fname efname pt pageheight textheight xoffset yoffset psfontfile
   global customfontno ptsize slant appbg appfg

   if { [string compare $fname ""] != 0 } {
      set dotindex [string last "." $fname]
      incr dotindex -1
   } else {
      set dotindex -1
   }
   if {$dotindex >= 0} {
      set efname [string range $fname 0 $dotindex]
      set efname "$efname.ps"
   } else {
      set efname "$fname.ps"
   }
   set pt 12
   set sl "normal"
   set pageheight 29.7
   set textheight 24.7
   set xoffset 2.5
   set yoffset 2.5

   set efn [getPSFileName]
   if { [string compare $efn ""] != 0 } {
      if {[string compare "o" $slant]} { set slflag 0 } else { set slflag 1 }
      foreach tagname {suptag supsuptag subsuptag subtag subsubtag supsubtag english} {
         set ${tagname}rng [.mainfr.editfr.textarea tag ranges $tagname]
      }
      for {set i 0} {$i < $customfontno} {incr i 1} {
         set englishrng [concat $englishrng [.mainfr.editfr.textarea tag ranges customftag$i]]
      }
      set englishrng [lsort -real -increasing $englishrng]
      set smallrng [.mainfr.editfr.textarea tag ranges devnagari100r]
      set normalrng [.mainfr.editfr.textarea tag ranges devnagari120r]
      set largerng [.mainfr.editfr.textarea tag ranges devnagari150r]
      set Largerng [.mainfr.editfr.textarea tag ranges devnagari180r]
      set LARGErng [.mainfr.editfr.textarea tag ranges devnagari210r]
      set hugerng [.mainfr.editfr.textarea tag ranges devnagari250r]
      set Hugerng [.mainfr.editfr.textarea tag ranges devnagari300r]
      set HUGErng [.mainfr.editfr.textarea tag ranges devnagari360r]
      set smallslrng [.mainfr.editfr.textarea tag ranges devnagari100o]
      set normalslrng [.mainfr.editfr.textarea tag ranges devnagari120o]
      set largeslrng [.mainfr.editfr.textarea tag ranges devnagari150o]
      set Largeslrng [.mainfr.editfr.textarea tag ranges devnagari180o]
      set LARGEslrng [.mainfr.editfr.textarea tag ranges devnagari210o]
      set hugeslrng [.mainfr.editfr.textarea tag ranges devnagari250o]
      set Hugeslrng [.mainfr.editfr.textarea tag ranges devnagari300o]
      set HUGEslrng [.mainfr.editfr.textarea tag ranges devnagari360o]
      foreach scriptrng { \$suptagrng \$subtagrng \$supsuptagrng \$subsuptagrng \$subsubtagrng \$supsubtagrng } {
         set srlen [ eval llength $scriptrng ]
         if {$srlen > 0} {
            foreach tagrng { \$normalrng \$smallrng \$largerng \$Largerng \$LARGErng \$hugerng \$Hugerng \$HUGErng \$englishrng \$normalslrng \$smallslrng \$largeslrng \$Largeslrng \$LARGEslrng \$hugeslrng \$Hugeslrng \$HUGEslrng } {
               set trlen [ eval llength $tagrng ]
               if {$trlen > 0} {
                  for {set i 0} {$i < $srlen} {incr i 2} {
                     for {set j 0} {$j < $trlen} {incr j 1} {
                        set si [eval lindex $scriptrng $i]
                        set ti1 [eval lindex $tagrng $j]
                        incr j 1
                        set ti2 [eval lindex $tagrng $j]
                        if { ($ti1 < $si) && ($ti2 > $si) } {
                           set [string range $tagrng 1 [expr [string length $tagrng] - 1]] [eval linsert $tagrng $j $si $si]
                           incr trlen 2
                        }
                     }
                  }
                  for {set i 1} {$i < $srlen} {incr i 2} {
                     for {set j 0} {$j < $trlen} {incr j 1} {
                        set si [eval lindex $scriptrng $i]
                        set ti1 [eval lindex $tagrng $j]
                        incr j 1
                        set ti2 [eval lindex $tagrng $j]
                        if { ($ti1 < $si) && ($ti2 > $si) } {
                           set [string range $tagrng 1 [expr [string length $tagrng] - 1]] [eval linsert $tagrng $j $si $si]
                           incr trlen 2
                        }
                     }
                  }
               }
            }
         }
      }
      set pageno 1
      set f [open $efn w]
      puts $f "%!PS-Adobe-2.0"
      puts $f "%%Title: Exported from $fname"
      puts $f "%%Creator: dvedit version 1.0"
      puts $f "%%CreationDate: [exec date]"
      puts $f "%%Pages: (atend)"
      puts $f "%%PageOrder: Ascend"
      puts $f "%%BoundingBox: 0 0 596 842"
      puts $f "%%DocumentFonts: "
      puts $f "%%DocumentPaperSizes: a4"
      puts $f "%%EndComments"

      set ff [open $psfontfile r]
      set x [read $ff]
      puts $f $x
      close $ff

      set corr1 [expr 0.1 * $pt]
      set corr2 [expr 0.2 * $pt]
      set corr3 [expr 0.3 * $pt]
      set corr4 [expr 0.4 * $pt]
      set corr5 [expr 0.5 * $pt]
      set lineskip [expr 1.4 * $pt]
      set uly [expr ($pageheight - $yoffset) * 28.35 - (0.8 * $pt)]
      set lly [expr $uly - ($textheight * 28.35)]
      set xoffset [expr $xoffset * 28.35]
      set currenty $uly
      set off1 [expr 0.5 * $pt]
      set off2 [expr 0.8 * $pt]
      set off3 [expr 0.3 * $pt]
      puts $f "/bnnormal \{ /Devnagari findfont $pt scalefont setfont \} def"
      set bnsize [expr 0.7 * $pt]
      puts $f "/bnsmall \{ /Devnagari findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 0.5 * $pt]
      puts $f "/bntiny \{ /Devnagari findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 1.2 * $pt]
      puts $f "/bnlarge \{ /Devnagari findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 1.44 * $pt]
      puts $f "/bnLarge \{ /Devnagari findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 1.728 * $pt]
      puts $f "/bnLARGE \{ /Devnagari findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 2.074 * $pt]
      puts $f "/bnhuge \{ /Devnagari findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 2.488 * $pt]
      puts $f "/bnHuge \{ /Devnagari findfont $bnsize scalefont setfont \} def"
      set bnsize [expr 2.986 * $pt]
      puts $f "/bnHUGE \{ /Devnagari findfont $bnsize scalefont setfont \} def"
      puts $f "/english \{ /Times-Roman findfont $pt scalefont setfont \} def"

      puts $f "/bsup \{ 0 $off1 rmoveto \} def"
      puts $f "/bsub \{ 0 -$off1 rmoveto \} def"
      puts $f "/bsupsup \{ 0 $off2 rmoveto \} def"
      puts $f "/bsubsub \{ 0 -$off2 rmoveto \} def"
      puts $f "/bsubsup \{ 0 $off3 rmoveto \} def"
      puts $f "/bsupsub \{ 0 -$off3 rmoveto \} def"
      puts $f "/esup \{ 0 -$off1 rmoveto \} def"
      puts $f "/esub \{ 0 $off1 rmoveto \} def"
      puts $f "/esupsup \{ 0 -$off2 rmoveto \} def"
      puts $f "/esubsub \{ 0 $off2 rmoveto \} def"
      puts $f "/esubsup \{ 0 -$off3 rmoveto \} def"
      puts $f "/esupsub \{ 0 $off3 rmoveto \} def"

      puts $f "/M \{ dup 4 div neg /y0 exch def moveto \} def"
      puts $f "/S \{ show \} def"
      puts $f "/SS \{ dup stringwidth pop /xx exch def gsave \[1 0 0.25 1 y0 0\] concat show grestore xx 0 rmoveto \} def"
      puts $f "/N \{ $xoffset $uly M \} def"
      puts $f "/B \{ neg /corr exch def corr 0 rmoveto \} def /F \{ /corr exch def corr 0 rmoveto \} def"
      puts $f "/CH 1 string def"
      puts $f "/P \{ CH 0 3 -1 roll put CH S \} def"
      puts $f "/PP \{ CH 0 3 -1 roll put CH SS \} def"
      puts $f "bnnormal"
      set tos 0
      set fontstack(0) "bnnormal"

      puts $f "\n%%Page: $pageno $pageno\nN"
      set ins [.mainfr.editfr.textarea get 1.0 end]
      set inl [string length $ins]
      set lineno 1
      set charno 0
      set englishmode 0
      foreach tagname { sub sup subsup supsub supsup subsub large Large LARGE huge Huge HUGE } {
         set ${tagname}found 0
         set prevcorr 0
      }
      set acc ""
      set tagshere {}
      for {set i 0} {$i < $inl} {incr i 1} {
         if {[lsearch -regexp $tagshere "devnagari"] >= 0} {
            foreach tagname { \$normalrng \$smallrng \$largerng \$Largerng \$LARGErng \$hugerng \$Hugerng \$HUGErng \$normalslrng \$smallslrng \$largeslrng \$Largeslrng \$LARGEslrng \$hugeslrng \$Hugeslrng \$HUGEslrng } {
               set ridx [eval lsearch -exact $tagname $lineno.$charno]
               if { ($ridx >= 0) && ($ridx & 1) } {
                  incr tos -1 ; set prevfont $fontstack($tos) ; set acc "$acc $prevfont"
                  if {[string compare $slant "o"]} {set slflag 0} else {set slflag 1}
               }
            }
         }
         set ridx [lsearch -exact $englishrng $lineno.$charno]
         if { ($ridx >= 0) && ($ridx & 1) } {
            incr englishmode -1
            incr tos -1 ; set prevfont $fontstack($tos) ; set acc "$acc $prevfont"
         }
         set suidx [lsearch -regexp $tagshere "su"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            set tagname [string range $tagname 0 [expr [string length $tagname] - 4]]
            set ridx [eval lsearch -exact \$${tagname}tagrng $lineno.$charno]
            if { ($ridx >= 0) && ($ridx & 1) } {
               set acc "$acc e$tagname"
               incr tos -1 ; set prevfont $fontstack($tos) ; set acc "$acc $prevfont"
            }
         }
         set tagshere [.mainfr.editfr.textarea tag names "$lineno.$charno"]
         set suidx [lsearch -regexp $tagshere "su.tag"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            set tagname [string range $tagname 0 [expr [string length $tagname] - 4]]
            set ridx [eval lsearch -exact \$${tagname}tagrng $lineno.$charno]
            if { ($ridx >= 0) && !($ridx & 1) && ([string length $tagname] == 3) } {
               set acc "$acc b$tagname"
               incr tos 1 ; set fontstack($tos) bnsmall ; set acc "$acc bnsmall"
               set ${tagname}found 1
            }
         }
         set suidx [lsearch -regexp $tagshere "su.su.tag"]
         if {$suidx >= 0} {
            set tagname [lindex $tagshere $suidx]
            set tagname [string range $tagname 0 [expr [string length $tagname] - 4]]
            set ridx [eval lsearch -exact \$${tagname}tagrng $lineno.$charno]
            if { ($ridx >= 0) && !($ridx & 1) } {
               set acc "$acc b$tagname"
               incr tos 1 ; set fontstack($tos) bntiny ; set acc "$acc bntiny"
               set ${tagname}found 1
            }
         }
         set ridx [lsearch -exact $englishrng $lineno.$charno]
         if {($ridx >= 0)} {
            if { !($ridx & 1) } {
               incr englishmode 1
               incr tos 1 ; set fontstack($tos) english ; set acc "$acc english"
            } else {
               incr ridx 1
               if { ($ridx < [llength $englishrng]) && ("$lineno.$charno" == [lindex $englishrng $ridx]) } {
                  incr englishmode 1
                  incr tos 1 ; set fontstack($tos) english ; set acc "$acc english"
               }
            }
         }
         if {[lsearch -regexp $tagshere "devnagari"] >= 0} {
            foreach tagname { normal small large Large LARGE huge Huge HUGE } {
               set ridx [eval lsearch -exact \$${tagname}rng $lineno.$charno]
               if {($ridx >= 0)} {
                  if { !($ridx & 1) } {
                     set acc "$acc bn$tagname" ; set slflag 0
                     incr tos 1 ; set fontstack($tos) bn$tagname
                     set ${tagname}found 1
                  } else {
                     incr ridx 1
                     if { ($ridx < [eval llength \$${tagname}rng]) && ("$lineno.$charno" == [eval lindex \$${tagname}rng $ridx]) } {
                        set acc "$acc bn$tagname" ; set slflag 0
                        incr tos 1 ; set fontstack($tos) bn$tagname
                        set ${tagname}found 1
                     }
                  }
               }
               set ridx [eval lsearch -exact \$${tagname}slrng $lineno.$charno]
               if {($ridx >= 0)} {
                  if { !($ridx & 1) } {
                     set acc "$acc bn$tagname" ; set slflag 1
                     incr tos 1 ; set fontstack($tos) bn$tagname
                     set ${tagname}found 1
                  } else {
                     incr ridx 1
                     if { ($ridx < [eval llength \$${tagname}slrng]) && ("$lineno.$charno" == [eval lindex \$${tagname}slrng $ridx]) } {
                        set acc "$acc bn$tagname" ; set slflag 1
                        incr tos 1 ; set fontstack($tos) bn$tagname
                        set ${tagname}found 1
                     }
                  }
               }
            }
         }
         set nextchar [string range $ins $i $i]
         scan $nextchar "%c" asciival
         if {$asciival == 10} { set charno 0 ; incr lineno 1 } else { incr charno 1 }
         if {($slflag) && !($englishmode)} {set P PP ; set S SS} else {set P P ; set S S}
         if {$asciival == 10} {
            set currenty [expr $currenty - $lineskip]
            if {$prevcorr != 0} { set currenty [expr $currenty - ( $prevcorr * $pt )] }
            set sosc 0
            if {$subsupfound} { set sosc 0.3 }
            if {$supfound} { set sosc 0.5 }
            if {$supsupfound} { set sosc 0.8 }
            set fosc 0
            if {$largefound} { set fosc 0.25 }
            if {$Largefound} { set fosc 0.5 }
            if {$LARGEfound} { set fosc 0.75 }
            if {$hugefound} { set fosc 1.08 }
            if {$Hugefound} { set fosc 1.5 }
            if {$HUGEfound} { set fosc 2 }
            set tosc [expr ( $sosc + $fosc ) * $pt]
            set currenty [expr $currenty - $tosc]
            set prevcorr 0
            if { $currenty <= $lly } {
               incr pageno 1
               puts $f "showpage\n\n%%Page: $pageno $pageno\nN"
               set currenty $uly
            } else {
               if {$supsubfound} {set prevcorr 0.3}
               if {$subfound} {set prevcorr 0.5}
               if {$subsubfound} {set prevcorr 0.8}
            }
            puts $f "$xoffset $currenty M"
            puts $f $acc
            set acc ""
            set taglist [.mainfr.editfr.textarea tag names "$lineno.0"]
            if {[lsearch -regexp $taglist "devnagari150"] >= 0} { set largefound 1 } else { set largefound 0 }
            if {[lsearch -regexp $taglist "devnagari180"] >= 0} { set Largefound 1 } else { set Largefound 0 }
            if {[lsearch -regexp $taglist "devnagari210"] >= 0} { set LARGEfound 1 } else { set LARGEfound 0 }
            if {[lsearch -regexp $taglist "devnagari250"] >= 0} { set hugefound 1 } else { set hugefound 0 }
            if {[lsearch -regexp $taglist "devnagari300"] >= 0} { set Hugefound 1 } else { set Hugefound 0 }
            if {[lsearch -regexp $taglist "devnagari360"] >= 0} { set HUGEfound 1 } else { set HUGEfound 0 }
            foreach tagname { sub sup subsup supsub supsup subsub } {
               if {[lsearch -exact $taglist "${tagname}tag"] >= 0} {
                  set ${tagname}found 1
               } else { set ${tagname}found 0 }
            }
         } elseif {$englishmode} {
            switch -exact $asciival {
               37 { set acc "$acc (\\$nextchar) S" }
               40 { set acc "$acc (\\$nextchar) S" }
               41 { set acc "$acc (\\$nextchar) S" }
               92 { set acc "$acc (\\$nextchar) S" }
               default {
                  if { ($asciival < 32) || ($asciival > 127) } {
                     set acc "$acc $asciival P"
                  } else {
                     set acc "$acc ($nextchar) S"
                  }
               }
            }
         } else {
            switch -exact $asciival {
                1 { set acc "$acc $corr1 B 1 $P $corr2 F" }
                2 { set acc "$acc $corr1 B 2 $P $corr2 F" }
                3 { set acc "$acc $corr4 B 3 $P $corr1 B" }
                4 { set acc "$acc $corr3 B 4 $P" }
                8 { set acc "$acc $corr1 B 8 $P $corr2 F" }
               14 { set acc "$acc $corr1 B 14 $P $corr2 F" }
               19 { set acc "$acc $corr2 B 19 $P $corr1 F" }
               31 { set acc "$acc $corr1 B 31 $P $corr2 F" }
               37 { set acc "$acc (\\$nextchar) $S" }
               40 { set acc "$acc (\\$nextchar) $S" }
               41 { set acc "$acc (\\$nextchar) $S" }
               44 { set acc "$acc $corr1 F 44 $P $corr2 B" }
               70 { set acc "$acc $corr3 B 70 $P $corr3 F" }
               79 { set acc "$acc $corr3 B 79 $P $corr3 F" }
               92 { set acc "$acc $corr1 B (\\$nextchar) $S $corr1 B" }
               94 { set acc "$acc $corr1 B 94 $P $corr2 F" }
              111 { set acc "$acc $corr3 B 111 $P $corr3 F" }
              123 { set acc "$acc $corr4 B 123 $P $corr1 B" }
              124 { set acc "$acc $corr1 B 124 $P $corr2 F" }
              125 { set acc "$acc $corr5 B 125 $P" }
              126 { set acc "$acc $corr1 B 126 $P $corr2 F" }
              132 { set acc "$acc $corr2 B 132 $P" }
              253 { set acc "$acc $corr5 B 253 $P $corr5 F" }
              255 { set acc "$acc $corr3 B 255 $P" }
               default {
                  if { ($asciival < 32) || ($asciival > 127) } {
                     set acc "$acc $asciival $P"
                  } else {
                     set acc "$acc ($nextchar) $S"
                  }
               }
            }
         }
      }
      puts $f "showpage\n"
      puts $f "%%Trailer"
      puts $f "%%Pages: $pageno"
      puts $f "%%EOF"
      close $f
   }
}

proc applyMainOptions {} {
   global textbg textfg textsbg textsfg textibg textht textwd ptsize slant charmap charmap2 textsp3

   switch -exact $ptsize {
      100 {set textsp3 4}
      120 {set textsp3 5}
      150 {set textsp3 6}
      180 {set textsp3 7}
      210 {set textsp3 8}
      250 {set textsp3 10}
      300 {set textsp3 12}
      360 {set textsp3 15}
      default {set textsp3 5}
   }

   .mainfr.editfr.textarea config -height $textht -width $textwd \
          -font "-*-devnagari-medium-$slant-*-*-*-$ptsize-*-*-*-*-*-fontspecific" \
          -spacing3 $textsp3 -insertbackground $textibg \
          -background $textbg -foreground $textfg \
          -selectbackground $textsbg -selectforeground $textsfg

   if {$charmap != $charmap2} { manageCharMap }
}

proc saveOptions { flag { rwin .mainfr.editfr.textarea } } {
   global textbg textfg textsbg textsfg textibg textht textwd ptsize slant charmap
   global textbg2 textfg2 textsbg2 textsfg2 textibg2 textht2 textwd2 editrmn
   global olfg olbg
   global dvmaildir mailcmd mimen mimed uun uud

   set rcfile "~/.dveditrc"
   set rcf [open $rcfile w]
   puts $rcf "# Resource file for dvedit version 1.0"
   puts $rcf "# Do not edit. Use the \"Edit options\" menu of dvedit\n"
   puts $rcf "# Main window"
   puts $rcf "TextBackGround\t\t: $textbg"
   puts $rcf "TextForeGround\t\t: $textfg"
   puts $rcf "SelectionBackGround\t: $textsbg"
   puts $rcf "SelectionForeGround\t: $textsfg"
   puts $rcf "CursorColor\t\t: $textibg"
   puts $rcf "TextHeight\t\t: $textht"
   puts $rcf "TextWidth\t\t: $textwd"
   puts $rcf "DefaultPointSize\t: $ptsize"
   puts $rcf "Slant\t\t\t: $slant"
   puts $rcf "CharMap\t\t\t: $charmap"
   puts $rcf "\n# Roman window"
   puts $rcf "TextBackGround2\t\t: $textbg2"
   puts $rcf "TextForeGround2\t\t: $textfg2"
   puts $rcf "SelectionBackGround2\t: $textsbg2"
   puts $rcf "SelectionForeGround2\t: $textsfg2"
   puts $rcf "CursorColor2\t\t: $textibg2"
   puts $rcf "TextHeight2\t\t: $textht2"
   puts $rcf "TextWidth2\t\t: $textwd2"
   puts $rcf "EditRoman\t\t: $editrmn"
   puts $rcf "OnlineForeGround\t: $olfg"
   puts $rcf "OnlineBackGround\t: $olbg"
   puts $rcf "\n# Mail options"
   puts $rcf "DVMailDir\t\t: $dvmaildir"
   puts $rcf "MailCommand\t\t: $mailcmd"
   puts $rcf "MIMENCommand\t\t: $mimen"
   puts $rcf "MIMEDCommand\t\t: $mimed"
   puts $rcf "UUNCommand\t\t: $uun"
   puts $rcf "UUDCommand\t\t: $uud"
   puts $rcf "\n# End of .dveditrc"
   close $rcf

   if {($flag == 0)} {
      errmsg "Options saved"
   } else {
      errmsg2 "Options saved" $rwin
   }
}

proc activateFileMenu {} {
   set posx [winfo x .]
   incr posx [winfo x .cmdfr.file]
   set posy [winfo y .]
   incr posy [winfo y .cmdfr.file]
   incr posy [winfo height .cmdfr.file]
   .cmdfr.file.m post $posx $posy
   .cmdfr.file.m activate 0
   grab set -global .cmdfr.file.m
}

proc activateEditMenu {} {
   set posx [winfo x .]
   incr posx [winfo x .cmdfr.edit]
   set posy [winfo y .]
   incr posy [winfo y .cmdfr.edit]
   incr posy [winfo height .cmdfr.edit]
   .cmdfr.edit.m post $posx $posy
   .cmdfr.edit.m activate 0
   grab set -global .cmdfr.edit.m
}

proc activateTagMenu {} {
   set posx [winfo x .]
   incr posx [winfo x .cmdfr.tag]
   set posy [winfo y .]
   incr posy [winfo y .cmdfr.tag]
   incr posy [winfo height .cmdfr.tag]
   .cmdfr.tag.m post $posx $posy
   .cmdfr.tag.m activate 0
   grab set -global .cmdfr.tag.m
}

proc activateOptionMenu {} {
   set posx [winfo x .]
   incr posx [winfo x .cmdfr.option]
   set posy [winfo y .]
   incr posy [winfo y .cmdfr.option]
   incr posy [winfo height .cmdfr.option]
   .cmdfr.option.m post $posx $posy
   .cmdfr.option.m activate 0
   grab set -global .cmdfr.option.m
}

proc activateImportMenu {} {
   set posx [winfo x .]
   incr posx [winfo x .cmdfr.import]
   set posy [winfo y .]
   incr posy [winfo y .cmdfr.import]
   incr posy [winfo height .cmdfr.import]
   .cmdfr.import.m post $posx $posy
   .cmdfr.import.m activate 0
   grab set -global .cmdfr.import.m
}

proc activateExportMenu {} {
   set posx [winfo x .]
   incr posx [winfo x .cmdfr.export]
   set posy [winfo y .]
   incr posy [winfo y .cmdfr.export]
   incr posy [winfo height .cmdfr.export]
   .cmdfr.export.m post $posx $posy
   .cmdfr.export.m activate 0
   grab set -global .cmdfr.export.m
}

proc activateMailMenu {} {
   set posx [winfo x .]
   incr posx [winfo x .cmdfr.mail]
   set posy [winfo y .]
   incr posy [winfo y .cmdfr.mail]
   incr posy [winfo height .cmdfr.mail]
   .cmdfr.mail.m post $posx $posy
   .cmdfr.mail.m activate 0
   grab set -global .cmdfr.mail.m
}

proc activateHelpMenu {} {
   set posx [winfo x .]
   incr posx [winfo x .cmdfr.help]
   set posy [winfo y .]
   incr posy [winfo y .cmdfr.help]
   incr posy [winfo height .cmdfr.help]
   .cmdfr.help.m post $posx $posy
   .cmdfr.help.m activate 0
   grab set -global .cmdfr.help.m
}

bind .cmdfr.file.m <Right> { grab release .cmdfr.file.m; .cmdfr.file.m unpost; activateEditMenu }
bind .cmdfr.edit.m <Right> { grab release .cmdfr.edit.m; .cmdfr.edit.m unpost; activateTagMenu }
bind .cmdfr.tag.m <Right> { grab release .cmdfr.tag.m; .cmdfr.tag.m unpost; activateImportMenu }
bind .cmdfr.import.m <Right> { grab release .cmdfr.import.m; .cmdfr.import.m unpost; activateExportMenu }
bind .cmdfr.export.m <Right> { grab release .cmdfr.export.m; .cmdfr.export.m unpost; activateMailMenu }
bind .cmdfr.mail.m <Right> { grab release .cmdfr.mail.m; .cmdfr.mail.m unpost; activateOptionMenu }
bind .cmdfr.option.m <Right> { grab release .cmdfr.option.m; .cmdfr.option.m unpost; activateHelpMenu }
bind .cmdfr.help.m <Right> { grab release .cmdfr.help.m; .cmdfr.help.m unpost; activateFileMenu }
bind .cmdfr.file.m <Left> { grab release .cmdfr.file.m; .cmdfr.file.m unpost; activateHelpMenu }
bind .cmdfr.edit.m <Left> { grab release .cmdfr.edit.m; .cmdfr.edit.m unpost; activateFileMenu }
bind .cmdfr.tag.m <Left> { grab release .cmdfr.tag.m; .cmdfr.tag.m unpost; activateEditMenu }
bind .cmdfr.import.m <Left> { grab release .cmdfr.import.m; .cmdfr.import.m unpost; activateTagMenu }
bind .cmdfr.export.m <Left> { grab release .cmdfr.export.m; .cmdfr.export.m unpost; activateImportMenu }
bind .cmdfr.mail.m <Left> { grab release .cmdfr.mail.m; .cmdfr.mail.m unpost; activateExportMenu }
bind .cmdfr.option.m <Left> { grab release .cmdfr.option.m; .cmdfr.option.m unpost; activateMailMenu }
bind .cmdfr.help.m <Left> { grab release .cmdfr.help.m; .cmdfr.help.m unpost; activateOptionMenu }

bind . <Alt-a> { appendFile }
bind . <Alt-c> { manageCharMap }
bind . <Alt-d> { chooseBaseFont }
bind . <Alt-e> { activateEditMenu }
bind . <Alt-f> { activateFileMenu }
bind . <Alt-g> { activateTagMenu }
bind . <Alt-h> { activateHelpMenu }
bind . <Alt-i> { insertFile }
bind . <Alt-k> { viewKbdMap }
bind . <Alt-l> { loadFile }
bind . <Alt-m> { activateMailMenu }
bind . <Alt-n> { newFile }
bind . <Alt-o> { editOptions 0 }
bind . <Alt-p> { activateOptionMenu }
bind . <Alt-q> { quitEditor }
bind . <Alt-r> { activateImportMenu }
bind . <Alt-s> { saveFile }
bind . <Alt-t> { focus .mainfr.editfr.textarea }
bind . <Alt-v> { saveThisFile }
bind . <Alt-x> { activateExportMenu }
bind . <Alt-A> { appendFile }
bind . <Alt-C> { manageCharMap }
bind . <Alt-D> { chooseBaseFont }
bind . <Alt-E> { activateEditMenu }
bind . <Alt-F> { activateFileMenu }
bind . <Alt-G> { activateTagMenu }
bind . <Alt-H> { activateHelpMenu }
bind . <Alt-I> { insertFile }
bind . <Alt-K> { viewKbdMap }
bind . <Alt-L> { loadFile }
bind . <Alt-M> { activateMailMenu }
bind . <Alt-N> { newFile }
bind . <Alt-O> { editOptions 0 }
bind . <Alt-P> { activateOptionMenu }
bind . <Alt-Q> { quitEditor }
bind . <Alt-R> { activateImportMenu }
bind . <Alt-S> { saveFile }
bind . <Alt-T> { focus .mainfr.editfr.textarea }
bind . <Alt-V> { saveThisFile }
bind . <Alt-X> { activateExportMenu }
bind .cmdfr.logo <Button-1> { copyInfo }

menu .b2m -tearoff false -bg $appbg -fg $appfg
.b2m add command -label " Cut " -command {cutBuffer}
.b2m add command -label " Copy " -command {copyBuffer}
.b2m add command -label " Paste " -command {pasteBuffer}
.b2m add separator
.b2m add command -label " Normal " -command {normalSel}
.b2m add command -label " Underline " -command {ulSel}
.b2m add command -label " Superscript " -command {supSel}
.b2m add command -label " Supersuperscript " -command {supsupSel}
.b2m add command -label " Subsuperscript " -command {subsupSel}
.b2m add command -label " Subscript " -command {subSel}
.b2m add command -label " Subsubscript " -command {subsubSel}
.b2m add command -label " Supersubscript " -command {supsubSel}
.b2m add separator
.b2m add command -label " Selection Font " -command {fontSel}
.b2m add command -label " Document Font " -command {chooseBaseFont}

menu .b3m -tearoff false -bg $appbg -fg $appfg
.b3m add command -label " Load file " -command {loadFile}
.b3m add command -label " Save file " -command {saveThisFile}
.b3m add command -label " Save as file " -command {saveFile}
.b3m add separator
.b3m add command -label " Load Roman file " -command {importRoman 0}
.b3m add command -label " Insert Roman file " -command {importRoman 1}
.b3m add command -label " Edit Roman file " -command {editRoman}
.b3m add separator
.b3m add command -label " Load Tags " -command {loadTags}
.b3m add command -label " Save Tags " -command {saveTags}
.b3m add separator
.b3m add command -label " Export to HTML " -command {exportHTML}
.b3m add command -label " Export to LaTeX " -command {exportLaTeX}
.b3m add command -label " Export to PostScript " -command {exportPS}
.b3m add separator
.b3m add command -label " Send mail " -command {sendMail 0}
.b3m add command -label " Read dvencoded file " -command {readDV}
.b3m add command -label " Read MIME encoded file " -command {readMIME}
.b3m add command -label " Read uuencoded file " -command {readUU}
.b3m add separator
.b3m add command -label " Quit " -command {quitEditor}

bind .mainfr.editfr.textarea <ButtonPress-2> {
   .b2m post %X %Y
   .b2m activate 0
   grab set -global .b2m
}

bind .mainfr.editfr.textarea <ButtonPress-3> {
   .b3m post %X %Y
   .b3m activate 0
   grab set -global .b3m
}

bind .mainfr.editfr.textarea <Any-Key> {
   if { ([string compare %A " "] >= 0) && ([string compare %A "~"] <= 0) } {
      incr dirtybit 1
   }
   if {![string compare %A "\t"]} { incr dirtybit 1 }
   if {![string compare %A "\n"]} { incr dirtybit 1 }
   if {![string compare %A "\r"]} { incr dirtybit 1 }
   if {![string compare %A "\f"]} { incr dirtybit 1 }
}
bind .mainfr.editfr.textarea <Alt-Key> { }
bind .mainfr.editfr.textarea <Control-Key> { }
bind .mainfr.editfr.textarea <BackSpace> { incr dirtybit 1 }
bind .mainfr.editfr.textarea <Control-h> { incr dirtybit 1 }
bind .mainfr.editfr.textarea <Delete> { incr dirtybit 1 }
bind .mainfr.editfr.textarea <Control-d> { incr dirtybit 1 }
bind .mainfr.editfr.textarea <Meta-d> { incr dirtybit 1 }
bind .mainfr.editfr.textarea <Control-k> { incr dirtybit 1 }
bind .mainfr.editfr.textarea <Control-o> { incr dirtybit 1 }
bind .mainfr.editfr.textarea <Control-w> { incr dirtybit 1 }
bind .mainfr.editfr.textarea <Control-x> { incr dirtybit 1 }
bind .mainfr.editfr.textarea <Control-t> { incr dirtybit 1 }

wm iconname . "dvedit"
wm iconbitmap . @$installdir/images/dvedit-logo.xbm

proc vowel { c } {
   if {![string compare $c "-"]} { return 0 }
   switch -exact $c {
      a { return 1 }
      e { return 1 }
      i { return 1 }
      o { return 1 }
      u { return 1 }
      A { return 1 }
      E { return 1 }
      I { return 1 }
      O { return 1 }
      U { return 1 }
      R { return 1 }
      L { return 1 }
      default { return 0 }
   }
}

proc consonant { c } {
   if {[vowel $c]} { return 0 }
   scan $c "%c" asciival
   if {($asciival == 94)} { return 1 }
   if {($asciival > 65) && ($asciival <= 90)} { return 1 }
   if {($asciival > 97) && ($asciival <= 122)} { return 1 }
   return 0
}

set encread 0

proc readEnc { } {
   global encmap encread installdir

   if {!($encread)} {
      if {![file readable "$installdir/lib/dv.enc"]} {
         errmsg "ERROR:\nI cannot read the encoding file. The file $installdir/lib/dv.enc does not exist or does not have read permission."
         return
      }
      set encf [open "$installdir/lib/dv.enc" r]
      while {[gets $encf line] >= 0} {
         set idx [ string first "#" $line ]
         if {$idx >= 0} { set line [string range $line 0 [expr $idx - 1]] }
         set idx [ string first ":" $line ]
         if {$idx >= 0} {
            set code [string range $line 0 [expr $idx - 1]]
            set char [string range $line [expr $idx + 1] [expr [string length $line] - 1]]
            set code [string trim $code]
            set char [string trim $char]
            if {([string length $code] >= 0) && ([string length $char] >= 0)} {
               if {![string compare "\\" [string index $char 0]]} {
                  set ascval [string range $char 1 [expr [string length $char] - 1]]
               } else {
                  scan $char "%c" ascval
               }
               set encmap($code) $ascval
            }
         }
      }
      set encread 1
   }
}

readEnc

proc romanToBeng { txt } {
   global encmap

   set bntxt ""
   set idx 0
   set iplen [string length $txt]
   if {$iplen > 0} { set nextchar [string index $txt 0] }
   while {$idx < $iplen} {
      if {[vowel $nextchar]} {
         set swar ""
         while {[vowel $nextchar] && ($idx < $iplen)} {
            set swar $swar$nextchar
            incr idx 1
            if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
         }
         if [info exists encmap($swar)] {
            switch -exact $encmap($swar) {
                4 { set bntxt "${bntxt}a" }
               97 { set bntxt "${bntxt}a" }
               65 { set bntxt "${bntxt}aA" }
              105 { set bntxt "${bntxt}i" }
               73 { set bntxt "${bntxt}I" }
              117 { set bntxt "${bntxt}u" }
               85 { set bntxt "${bntxt}U" }
              101 { set bntxt "${bntxt}e" }
              123 { set bntxt "${bntxt}e\{" }
              111 { set bntxt "${bntxt}ao" }
               79 { set bntxt "${bntxt}aO" }
               27 { set bntxt $bntxt[format "%c" 27] }
               17 { set bntxt $bntxt[format "%c" 17] }
               24 { set bntxt $bntxt[format "%c" 24] }
               25 { set bntxt $bntxt[format "%c" 25] }
            }
         }
      }
      if {[consonant $nextchar]} {
         set swar ""
         set banjon ""
         while {[consonant $nextchar] && ($idx < $iplen)} {
            set banjon $banjon$nextchar
            incr idx 1
            if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
         }
         while {[vowel $nextchar] && ($idx < $iplen)} {
            set swar $swar$nextchar
            incr idx 1
            if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
         }
         if {[string compare "^" $banjon]} {
            set notdone 1
            set chandra ""
            set ref ""
            set rafala ""
            while {$notdone} {
               set notdone 0
               set len [string length $banjon]
               if {![string compare [string index $banjon [expr $len - 1]] "^"]} {
                  set chandra [format "%c" 255]
                  set banjon [string range $banjon 0 [expr $len - 2]]
                  incr len -1
                  set notdone 1
               }
               if {![string compare [string index $banjon [expr $len - 2]] "^"]} {
                  if {![string compare [string index $banjon [expr $len - 1]] "r"]} {
                     set rafala [format "%c" 126]
                     set banjon [string range $banjon 0 [expr $len - 3]]
                     incr len -2
                     set notdone 1
                  }
               }
               if {![string compare [string range $banjon 0 1] "^r"]} {
                  set ref [format "%c" 132]
                  set banjon [string range $banjon 2 [expr $len - 1]]
                  incr len -2
                  set notdone 1
               }
            }
            set prefix ""
            if {[info exists encmap($banjon)]} {
               set ban [format "%c" $encmap($banjon)]
            } else {
               set notdone 1
               while {$notdone} {
                  set notdone 0
                  if {![string compare $ref ""] && ![string compare [string index $banjon 0] "r"] } {
                     set ref [format "%c" 132]
                     set banjon [string range $banjon 1 [expr $len - 1]]
                     incr len -1
                     set notdone 1
                  }
                  if {($len > 1) && ![string compare $rafala ""]} {
                     set lastchar [string index $banjon [expr $len - 1]]
                     if {![string compare $lastchar "r"]} {
                        set rafala [format "%c" 126]
                        set banjon [string range $banjon 0 [expr $len - 2]]
                        incr len -1
                        set notdone 1
                     }
                  }
                  if {($len > 1) && ![string compare $chandra ""]} {
                     set lastchar [string index $banjon [expr $len - 1]]
                     if {![string compare $lastchar "^"]} {
                        set chandra [format "%c" 255]
                        set banjon [string range $banjon 0 [expr $len - 2]]
                        incr len -1
                        set notdone 1
                     }
                  }
               }
               if {![info exists encmap($banjon)]} {
                  if {([string length $banjon] > 4) && ![string compare [string range $banjon 0 3] "^Nch"]} {
                     set prefix [format "%c" 235]; set banjon [string range $banjon 4 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 4) && ![string compare [string range $banjon 0 3] "shch"]} {
                     set prefix [format "%c" 244]; set banjon [string range $banjon 4 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 3) && ![string compare [string range $banjon 0 2] "ghr"]} {
                     set prefix [format "%c" 242]; set banjon [string range $banjon 3 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 3) && ![string compare [string range $banjon 0 2] "^Nc"]} {
                     set prefix [format "%c" 235]; set banjon [string range $banjon 3 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 3) && ![string compare [string range $banjon 0 2] "ghn"]} {
                     set prefix [format "%c" 241]; set banjon [string range $banjon 3 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 3) && ![string compare [string range $banjon 0 2] "^kh"]} {
                     set prefix [format "%c" 7]; set banjon [string range $banjon 3 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 3) && ![string compare [string range $banjon 0 2] "ksh"]} {
                     set prefix [format "%c" 35]; set banjon [string range $banjon 3 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 3) && ![string compare [string range $banjon 0 2] "shr"]} {
                     set prefix [format "%c" 245]; set banjon [string range $banjon 3 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 3) && ![string compare [string range $banjon 0 2] "shw"]} {
                     set prefix [format "%c" 246]; set banjon [string range $banjon 3 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "Gn"]} {
                     set prefix [format "%c" 241]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "gh"]} {
                     set prefix [format "%c" 93]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "sh"]} {
                     set prefix [format "%c" 91]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "ch"]} {
                     set prefix [format "%c" 81]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "th"]} {
                     set prefix [format "%c" 76]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "dh"]} {
                     set prefix [format "%c" 64]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "bh"]} {
                     set prefix [format "%c" 60]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "^k"]} {
                     set prefix [format "%c" 30]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "^l"]} {
                     set prefix [format "%c" 16]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "^N"]} {
                     set prefix [format "%c" 22]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "^g"]} {
                     set prefix [format "%c" 28]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "^K"]} {
                     set prefix [format "%c" 7]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "jh"]} {
                     set prefix [format "%c" 36]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "ph"]} {
                     set prefix [format "%c" 37]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "gr"]} {
                     set prefix [format "%c" 243]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "tt"]} {
                     set prefix [format "%c" 246]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "Gr"]} {
                     set prefix [format "%c" 242]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 2) && ![string compare [string range $banjon 0 1] "pt"]} {
                     set prefix [format "%c" 243]; set banjon [string range $banjon 2 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "g"]} {
                     set prefix [format "%c" 96]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "G"]} {
                     set prefix [format "%c" 93]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "l"]} {
                     set prefix [format "%c" 83]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "c"]} {
                     set prefix [format "%c" 81]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "b"]} {
                     set prefix [format "%c" 78]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "m"]} {
                     set prefix [format "%c" 77]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "y"]} {
                     set prefix [format "%c" 5]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "n"]} {
                     set prefix [format "%c" 6]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "N"]} {
                     set prefix [format "%c" 23]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "r"]} {
                     set prefix [format "%c" 29]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "f"]} {
                     set prefix [format "%c" 37]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "w"]} {
                     set prefix [format "%c" 38]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "t"]} {
                     set prefix [format "%c" 40]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "s"]} {
                     set prefix [format "%c" 45]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "p"]} {
                     set prefix [format "%c" 61]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "j"]} {
                     set prefix [format "%c" 62]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  } elseif {([string length $banjon] > 1) && ![string compare [string range $banjon 0 0] "k"]} {
                     set prefix [format "%c" 63]; set banjon [string range $banjon 1 [expr [string length $banjon] - 1]]
                  }
               }
               if {[info exists encmap($banjon)]} {
                  set ban [format "%c" $encmap($banjon)]
               } else {
                  set ban " "
               }
            }
            set ban "$prefix$ban$ref$rafala$chandra"
         } else {
            set ban [format "%c" 255]
            set swar 97
         }
         if {[info exists encmap($swar)]} { set swar $encmap($swar) } else { set swar 97 }
         switch -exact $swar {
            97 { set bntxt "${bntxt}$ban" }
            65 { set bntxt "${bntxt}${ban}A" }
           105 { set bntxt "${bntxt}E$ban" }
            73 { set bntxt "${bntxt}${ban}F" }
           117 { set bntxt "${bntxt}$ban[format "%c" 8]" }
            85 { set bntxt "${bntxt}$ban[format "%c" 1]" }
           101 { set bntxt "${bntxt}$ban[format "%c" 3]" }
           123 { set bntxt "${bntxt}${ban}\{" }
           111 { set bntxt "${bntxt}${ban}o" }
            79 { set bntxt "${bntxt}${ban}O" }
            27 { set bntxt "${bntxt}$ban[format "%c" 2]" }
            17 { set bntxt "${bntxt}$ban[format "%c" 14]" }
            24 { set bntxt "${bntxt}$ban[format "%c" 31]" }
            25 { set bntxt "${bntxt}$ban[format "%c" 124]" }
             4 { set bntxt "${bntxt}$ban[format "%c" 4]" }
         }
      } else {
         if {![string compare $nextchar "_"]} {
            incr idx 1
            if {$idx < $iplen} { set nextnextchar [string index $txt $idx] } else { set nextchar "" }
            if {![string compare $nextnextchar "_"]} {
               incr idx 1
               set bntxt "${bntxt}^"
               if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
            } else { set nextchar $nextnextchar }
         } else {
            if {![string compare $nextchar "|"]} {
               incr idx 1
               if {$idx < $iplen} { set nextnextchar [string index $txt $idx] } else { set nextchar "" }
               if {![string compare $nextnextchar "|"]} {
                  incr idx 1
                  set bntxt "${bntxt};"
                  if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
               } else {
                  set bntxt "${bntxt}."
                  set nextchar $nextnextchar
               }
            } elseif {![string compare $nextchar "."]} {
               set bntxt "$bntxt[format "%c" 20]"
               incr idx 1
               if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
            } else {
               set bntxt "$bntxt$nextchar"
               incr idx 1
               if {$idx < $iplen} { set nextchar [string index $txt $idx] } else { set nextchar "" }
            }
         }
      }
   }
   return $bntxt
}

proc importRoman { flag } {
   global encread dirtybit

   set fn [getFileName "dvedit: Load"]
   if { [string compare $fn ""] != 0 } {
      if {!($encread)} { readEnc }
      if {![file readable $fn]} {
         errmsg "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         return
      }
      if {!($flag)} { .mainfr.editfr.textarea delete 1.0 end }
      set f [open $fn r]
      set txt [read $f]
      close $f
      .mainfr.editfr.textarea insert insert [romanToBeng $txt]
      .mainfr.editfr.textarea see insert
      incr dirtybit 1
   }
}

proc errmsg2 { msg win } {
   global btnbg btnfg

   set ewin [toplevel .error]

   message $ewin.msg -text $msg -relief flat -bg #006688 -fg #ffffff -width 250 -justify center
   button $ewin.btn -text "Ok" -relief raised -fg $btnfg -bg $btnbg \
          -activeforeground $btnfg -activebackground $btnbg \
          -command {set edone 1} -height 0

   pack $ewin.msg -padx 0 -pady 0 -expand yes -fill both
   pack $ewin.btn -pady 10

   bind $ewin <Escape> {set edone 1}
   bind $ewin <Return> {set edone 1}

   $ewin config -bg #004466

   wm transient $ewin $win
   set posx [winfo x $win]
   set posy [winfo y $win]
   incr posx [winfo x $win.mainfr]
   incr posy [winfo y $win.mainfr]
   set twd [winfo width $win.mainfr.editfr.textarea]
   set tht [winfo height $win.mainfr.editfr.textarea]
   set ewd 300
   set eht 150
   set posx [expr $posx + ($twd - $ewd) / 2]
   set posy [expr $posy + ($tht - $eht) / 2]
   wm geometry $ewin "${ewd}x${eht}+$posx+$posy"
   wm title $ewin "Diagnostic message"

   grab $ewin
   tkwait variable edone
   grab release $ewin
   destroy $ewin
}

set srcwinid -1
proc saveRomanConfirm { rwin } {
   global rscwin rdirtybit btnbg btnfg srcwinid rwinid

   if {[winfo exists $srcwinid]} {
      focus $srcwinid; tkwait variable rdirtybit; return;
   }
   while {$rdirtybit} {
      set rscwin [toplevel .rsc]
      set srcwinid $rscwin
      $rscwin config -bg #004466
      label $rscwin.l -text "Editor text has unsaved changes" -fg #ffffff -bg #006688
      frame $rscwin.bfr -bg #004466
      button $rscwin.bfr.b1 -text "Save" -command "saveRomanFile $rwin" -underline 0 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      button $rscwin.bfr.b2 -text "Save as" -command "saveasRomanFile $rwin" -underline 5 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      button $rscwin.bfr.b3 -text "Do not save" -command {set rdirtybit 0} -underline 3 \
         -bg $btnbg -fg $btnfg -activebackground $btnbg -activeforeground $btnfg \
         -relief raised
      pack $rscwin.l -expand yes -fill both -padx 0 -pady 0
      pack $rscwin.bfr.b1 $rscwin.bfr.b2 $rscwin.bfr.b3 -side left -padx 10 -pady 0
      pack $rscwin.bfr -expand no -padx 0 -pady 10

      bind $rscwin <Key-A> "saveasRomanFile $rwin"
      bind $rscwin <Key-N> "set rdirtybit 0"
      bind $rscwin <Key-S> "saveRomanFile $rwin"
      bind $rscwin <Key-a> "saveasRomanFile $rwin"
      bind $rscwin <Key-n> "set rdirtybit 0"
      bind $rscwin <Key-s> "saveRomanFile $rwin"

      wm transient $rscwin .
      wm title $rscwin "Options for unsaved changes"
      set posx [winfo x $rwin]
      set posy [winfo y $rwin]
      incr posx [winfo x $rwin.mainfr]
      incr posy [winfo y $rwin.mainfr]
      set twd [winfo width $rwin.mainfr.editfr.textarea]
      set tht [winfo height $rwin.mainfr.editfr.textarea]
      set ewd 350
      set eht 120
      set posx [expr $posx + ($twd - $ewd) / 2]
      set posy [expr $posy + ($tht - $eht) / 2]
      if {$posx <= 0} { set posx 0 }
      if {$posy <= 0} { set posy 0 }
      wm geometry $rscwin "${ewd}x${eht}+$posx+$posy"
      focus $rscwin

      tkwait variable rdirtybit
      destroy $rscwin
      set srcwinid -1
   }
}

proc loadRomanFile { rwin } {
   global rfname rdirtybit

   saveRomanConfirm $rwin
   set fn [getFileName "dvedit: Load Roman"]
   if {[string compare $fn ""] != 0} {
      if {![file readable $fn]} {
         errmsg2 "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission." $rwin
         return
      }
      if {![file isfile $fn]} {
         errmsg2 "ERROR:\nI cannot load the file. \"$fn\" is not a regular file." $rwin
         return
      }
      set f [open $fn r]
      set x [read $f]
      $rwin.mainfr.editfr.textarea delete 1.0 end
      $rwin.mainfr.editfr.textarea insert 1.0 $x
      close $f
      set rfname $fn
      $rwin.mainfr.editfr.textarea see insert
      set rdirtybit 0
      setbnstr $rwin
   }
}

proc saveRomanFile { rwin } {
   global rfname rdirtybit

   set rfname [string trim $rfname]
   if {![string compare "" $rfname]} {
      errmsg2 "ERROR:\nI cannot save file. No file name is given." $rwin
      return
   }
   set dnm [file dirname $rfname]
   if {![file isdirectory $dnm]} {
      errmsg2 "ERROR:\nI cannot save the file. \"$dnm\" is not a directory." $rwin
      return
   }
   if {![file writable $dnm]} {
      errmsg2 "ERROR:\nI cannot save the file. You do not have permission to write in the directory." $rwin
      return
   }
   if {[file exists $rfname] && ![file isfile $rfname]} {
      errmsg2 "ERROR:\nI cannot save the file. \"$rfname\" is not a regular file." $rwin
      return
   }
   if {[file exists $rfname] && ![file writable $rfname]} {
      errmsg2 "ERROR:\nI cannot save the file. You do not have permission to overwrite \"$rfname\"" $rwin
      return
   }

   set f [open $rfname w]
   set x [$rwin.mainfr.editfr.textarea get 1.0 end]
   puts -nonewline $f $x
   close $f
   set rdirtybit 0
   errmsg2 "$rfname saved" $rwin
}

proc saveasRomanFile { rwin } {
   global rfname rdirtybit

   set fn [getFileName "dvedit: Save Roman"]
   if { [string compare $fn ""] != 0 } {
      set dnm [file dirname $fn]
      if {![file isdirectory $dnm]} {
         errmsg2 "ERROR:\nI cannot save the file. \"$dnm\" is not a directory." $rwin
         return
      }
      if {![file writable $dnm]} {
         errmsg2 "ERROR:\nI cannot save the file. You do not have permission to write in the directory \"$dnm\"." $rwin
         return
      }
      if {[file exists $fn] && ![file isfile $fn]} {
         errmsg2 "ERROR:\nI cannot save the file. \"$fn\" is not a regular file." $rwin
         return
      }
      if {[file exists $fn] && ![file writable $fn]} {
         errmsg2 "ERROR:\nI cannot save the file. You do not have permission to overwrite \"$fn\"" $rwin
         return
      }
      set f [open $fn w]
      set x [$rwin.mainfr.editfr.textarea get 1.0 end]
      puts -nonewline $f $x
      close $f
      if {![string compare $rfname ""]} { set rfname $fn }
      set rdirtybit 0
      errmsg2 "$fn saved" $rwin
   }
}

proc applyRomanOptions { rwin } {
   global textbg2 textfg2 textsbg2 textsfg2 textibg2 textht2 textwd2 editrmn
   global olfg olbg

   $rwin.mainfr.editfr.textarea config -height $textht2 -width $textwd2 \
      -insertbackground $textibg2 \
      -background $textbg2 -foreground $textfg2 \
      -selectbackground $textsbg2 -selectforeground $textsfg2
   $rwin.mainfr.olview config -fg $olfg -bg $olbg \
      -selectforeground $olfg -selectbackground $olbg -selectborder 0
}

proc adddoc { twin fn appmode } {
   global installdir

   $twin tag configure bntag -font "-*-devnagari-medium-r-*-*-*-120-*-*-*-*-*-fontspecific"
   set bngmode 0
   if {![file readable "$installdir/help/$fn.hlp"]} {
      $twin delete 1.0 end
      $twin insert end "ERROR:\nI am unable to read the help file\n$installdir/help/$fn.hlp\n"
   } else {
      if {!($appmode)} { $twin delete 1.0 end }
      set bngmode 0
      set f [open "$installdir/help/$fn.hlp" r]
      while {![eof $f]} {
         set nextchar [read $f 1]
         if {$bngmode == 0} {
            if {![string compare "#" $nextchar]} {
               set bngmode 1
               set bnstr ""
            } else { $twin insert end $nextchar }
         } else {
            if {![string compare "#" $nextchar]} {
               if {[string length $bnstr] > 0} {
                  if {![string compare [string index $bnstr 0] "\\"]} {
                     $twin insert end [format "%c" [string range $bnstr 1 [expr [string length $bnstr] - 1]]] bntag
                  } else {
                     $twin insert end $bnstr bntag
                  }
               }
               set bngmode 0
            } else { set bnstr "$bnstr$nextchar" }
         }
      }
   }
}

set hwinrid -1
proc helpwinRoman { } {
   global installdir dveditlogo dpyfont appbg appfg hwinrid

   if {[winfo exists $hwinrid]} {focus $hwinrid; return}
   set hwin [toplevel .rhelp]
   set hwinrid $hwin
   $hwin config -bg $appbg
   frame $hwin.cmdfr -bg $appbg
   frame $hwin.dpyfr -bg $appbg
   menubutton $hwin.cmdfr.file -relief flat -fg $appfg -bg $appbg \
      -activebackground $appbg -activeforeground $appfg \
      -menu $hwin.cmdfr.file.m -text "File"
   menubutton $hwin.cmdfr.content -relief flat -fg $appfg -bg $appbg \
      -activebackground $appbg -activeforeground $appfg \
      -menu $hwin.cmdfr.content.m -text "Contents"
   menu $hwin.cmdfr.file.m -tearoff false -bg $appbg -fg $appfg
   $hwin.cmdfr.file.m add command -label "  Close  " -command "destroy $hwin; set hwinrid -1" -underline 2
   menu $hwin.cmdfr.content.m -tearoff false -bg $appbg -fg $appfg
   $hwin.cmdfr.content.m add command -label " 1. Introduction " -command "adddoc $hwin.dpyfr.textarea cr1 0"
   $hwin.cmdfr.content.m add command -label " 2. Conversion rules " -command "adddoc $hwin.dpyfr.textarea cr2 0"
   $hwin.cmdfr.content.m add command -label " 3. The default encoding " -command "adddoc $hwin.dpyfr.textarea cr3 0"
   $hwin.cmdfr.content.m add command -label "     3.1 Vowels and vowel forms " -command "adddoc $hwin.dpyfr.textarea cr3_1 0"
   $hwin.cmdfr.content.m add command -label "     3.2 Consonants " -command "adddoc $hwin.dpyfr.textarea cr3_2 0"
   $hwin.cmdfr.content.m add command -label "     3.3 Conjunct consonants " -command "adddoc $hwin.dpyfr.textarea cr3_3 0"
   $hwin.cmdfr.content.m add command -label "     3.4 Digits and punctuation symbols " -command "adddoc $hwin.dpyfr.textarea cr3_4 0"
   $hwin.cmdfr.content.m add command -label " 4. Customize encoding " -command "adddoc $hwin.dpyfr.textarea cr4 0"
   $hwin.cmdfr.content.m add command -label " 5. Conclusion " -command "adddoc $hwin.dpyfr.textarea cr5 0"
   label $hwin.cmdfr.space -fg $appfg -bg $appbg -text ""
   label $hwin.cmdfr.logo -relief flat -fg $appfg -bg $appbg -image "dveditlogo"
   
   text $hwin.dpyfr.textarea -relief sunken -height 20 -width 60 \
      -yscroll "$hwin.dpyfr.vscroll set" \
      -wrap none -relief flat -font $dpyfont \
      -background #ddddaa -foreground #000000 -borderwidth 2 \
      -selectbackground #000000 -selectforeground #ddddaa -selectborderwidth 0
   scrollbar $hwin.dpyfr.vscroll -relief sunken -orient vertical \
      -command "$hwin.dpyfr.textarea yview" -bg $appbg -width 12 \
      -activebackground $appbg

   pack $hwin.cmdfr.file $hwin.cmdfr.content -padx 0 -pady 0 -side left
   pack $hwin.cmdfr.space -padx 0 -pady 0 -side left -expand yes -fill x
   pack $hwin.cmdfr.logo -padx 5 -pady 0 -side left
   pack $hwin.dpyfr.vscroll $hwin.dpyfr.textarea -padx 0 -pady 0 -side right \
      -expand yes -fill y
   pack $hwin.cmdfr $hwin.dpyfr -padx 0 -pady 3 -side top -fill x

   bind $hwin <Escape> "destroy $hwin; set hwinrid -1"

   wm resizable $hwin false false
   wm title $hwin "dvedit: Roman-to-Devnagari conversion rules"

   adddoc $hwin.dpyfr.textarea cr1 0
}

proc setbnstr { rwin } {
   global bnstr

   set ipstr "[$rwin.mainfr.editfr.textarea get "insert linestart" "insert lineend"] "
   set bnstr [romanToBeng $ipstr]
}

proc transferText { rwin } {
   global dirtybit

   set ipstr "[$rwin.mainfr.editfr.textarea get 1.0 end]"
   .mainfr.editfr.textarea insert insert [romanToBeng $ipstr]
   .mainfr.editfr.textarea see insert
   incr dirtybit 1
}

proc transferLine { rwin } {
   global dirtybit

   set ipstr "[$rwin.mainfr.editfr.textarea get "insert linestart" "insert lineend"]\n"
   .mainfr.editfr.textarea insert insert [romanToBeng $ipstr]
   .mainfr.editfr.textarea see insert
   incr dirtybit 1
}

proc transferSelText { rwin } {
   global dirtybit

   set lsel [$rwin.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg2 "Text does not contain a selected region. Select text by left mouse button and retry." $rwin
      return
   }
   set ipstr "[$rwin.mainfr.editfr.textarea get sel.first sel.last]\n"
   .mainfr.editfr.textarea insert insert [romanToBeng $ipstr]
   .mainfr.editfr.textarea see insert
   incr dirtybit 1
}

set rwinid -1
proc editRoman { } {
   global textbg2 textfg2 textsbg2 textsfg2 textibg2 textht2 textwd2
   global olbg olfg
   global dveditlogo rfname installdir dpyfont
   global bnstr
   global rdirtybit
   global rwinid
   global appbg appfg opttype

   if {[winfo exists $rwinid]} {focus $rwinid.mainfr.editfr.textarea; return}
   set rfname ""
   set bnstr ""
   set rdirtybit 0
   set rwin [toplevel .roman]
   set rwinid $rwin
   $rwin config -bg $appbg
   frame $rwin.cmdfr -bg $appbg -relief raised -borderwidth 2
   menubutton $rwin.cmdfr.file -text "File" -height 1 -relief flat \
      -menu $rwin.cmdfr.file.m -bg $appbg -fg $appfg \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
   menu $rwin.cmdfr.file.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.file.m add command -label "  New " -accelerator " (Alt+N)  " -command "saveRomanConfirm $rwin; $rwin.mainfr.editfr.textarea delete 1.0 end; set rfname {}; set bnstr {}" -underline 4
   $rwin.cmdfr.file.m add command -label "  Load " -accelerator " (Alt+L)  " -command "loadRomanFile $rwin" -underline 2
   $rwin.cmdfr.file.m add command -label "  Save " -accelerator " (Alt+V)  " -command "saveRomanFile $rwin" -underline 4
   $rwin.cmdfr.file.m add command -label "  Save as " -accelerator " (Alt+S)  " -command "saveasRomanFile $rwin" -underline 2
   $rwin.cmdfr.file.m add separator
   $rwin.cmdfr.file.m add command -label "  Close " -accelerator " (Alt+C)  " -command "saveRomanConfirm $rwin; destroy $rwinid; set rwinid -1" -underline 2
   $rwin.cmdfr.file.m add command -label "  Quit " -accelerator " (Alt+Q)  " -command "quitEditor" -underline 2
   menubutton $rwin.cmdfr.edit -text "Edit" -height 1 -relief flat \
      -menu $rwin.cmdfr.edit.m -bg $appbg -fg $appfg \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
   menu $rwin.cmdfr.edit.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.edit.m add command -label "  Clear " -command "$rwin.mainfr.editfr.textarea delete 1.0 end; incr rdirtybit 1; set bnstr {}" -underline 2
   $rwin.cmdfr.edit.m add command -label "  Select all " -command "$rwin.mainfr.editfr.textarea tag add sel 1.0 end" -underline 9
   $rwin.cmdfr.edit.m add separator
   $rwin.cmdfr.edit.m add command -label "  Cut " -command "rcutBuffer" -underline 4
   $rwin.cmdfr.edit.m add command -label "  Copy " -command "rcopyBuffer" -underline 5
   $rwin.cmdfr.edit.m add command -label "  Paste " -command "rpasteBuffer" -underline 2
   menubutton $rwin.cmdfr.transfer -text "Transfer" -height 1 -relief flat \
      -menu $rwin.cmdfr.transfer.m -bg $appbg -fg $appfg \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
   menu $rwin.cmdfr.transfer.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.transfer.m add command -label "  Transfer text to main window " -accelerator " (Alt+T)  " -command "transferText $rwin" -underline 2
   $rwin.cmdfr.transfer.m add command -label "  Transfer line to main window " -accelerator " (Alt+F)  " -command "transferLine $rwin" -underline 7
   $rwin.cmdfr.transfer.m add command -label "  Transfer selected text to main window " -accelerator " (Alt+X)  " -command "transferSelText $rwin" -underline 22
   menubutton $rwin.cmdfr.mail -text "Mail" -height 1 -relief flat \
      -menu $rwin.cmdfr.mail.m -bg $appbg -fg $appfg \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
   menu $rwin.cmdfr.mail.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.mail.m add command -label "  Send mail " -accelerator "(Alt+M)" -command {sendMail 1} -underline 2
   $rwin.cmdfr.mail.m add command -label "  Read dvencoded text " -command {readDV} -underline 7
   $rwin.cmdfr.mail.m add command -label "  Edit mail options " -command {set opttype 3; editOptions 1} -underline 2
   menubutton $rwin.cmdfr.option -text "Option" -height 1 -relief flat \
      -menu $rwin.cmdfr.option.m -bg $appbg -fg $appfg \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
   menu $rwin.cmdfr.option.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.option.m add command -label "  Edit options " -accelerator " (Alt+O)  " -command "set opttype 2; editOptions 1" -underline 2
   $rwin.cmdfr.option.m add command -label "  Save options  " -command "saveOptions 1 $rwin" -underline 2
   menubutton $rwin.cmdfr.help -text "Help" -height 1 -relief flat \
      -menu $rwin.cmdfr.help.m -bg $appbg -fg $appfg \
      -activeforeground $appfg -activebackground $appbg \
      -highlightthickness 0
   menu $rwin.cmdfr.help.m -tearoff false -bg $appbg -fg $appfg
   $rwin.cmdfr.help.m add command -label "  Roman-to-Devnagari conversion rules (Alt+H)  " -command { helpwinRoman } -underline 2
   $rwin.cmdfr.help.m add separator
   $rwin.cmdfr.help.m add command -label "  About dvedit  " -command { helpwin } -underline 2
   $rwin.cmdfr.help.m add command -label "  Copyright notice  " -command { copyInfo } -underline 2
   label $rwin.cmdfr.space -text "" -text "" -fg $appbg -bg $appbg
   label $rwin.cmdfr.logo -image "dveditlogo" -relief flat -bg $appbg -fg $appfg
   bind $rwin.cmdfr.logo <Button-1> { copyInfo }
   frame $rwin.namefr -bg $appbg
   label $rwin.namefr.lbl -text " File name: " -relief flat -fg $appfg -bg $appbg
   entry $rwin.namefr.ent -textvariable rfname -relief sunken \
      -background #ffb6c1 -foreground #000000 -state disabled \
      -selectbackground #ffffcc -selectforeground #000000 -selectborderwidth 0
   frame $rwin.mainfr -bg $appbg
   frame $rwin.mainfr.editfr -bg $appbg
   text $rwin.mainfr.editfr.textarea -relief sunken -height $textht2 -width $textwd2 \
      -xscroll "$rwin.mainfr.editfr.hscroll set" -yscroll "$rwin.mainfr.editfr.scrbar set" \
      -wrap none -relief flat -font $dpyfont \
      -insertbackground $textibg2 -insertwidth 3 \
      -background $textbg2 -foreground $textfg2 -borderwidth 2 \
      -selectbackground $textsbg2 -selectforeground $textsfg2 -selectborderwidth 0
   scrollbar $rwin.mainfr.editfr.scrbar -relief sunken -orient vertical \
      -command "$rwin.mainfr.editfr.textarea yview" -bg $appbg -width 12 \
      -activebackground $appbg
   scrollbar $rwin.mainfr.editfr.hscroll -relief sunken -orient horizontal \
      -command "$rwin.mainfr.editfr.textarea xview" -bg $appbg -width 12 \
      -activebackground $appbg
   entry $rwin.mainfr.olview -bg $olbg -fg $olfg -state disabled -width 80 \
      -font "-*-devnagari-medium-r-*-*-*-120-*-*-*-*-*-fontspecific" \
      -textvariable bnstr -relief flat -selectforeground $olfg \
      -selectbackground $olbg -selectborder 0

   pack $rwin.cmdfr.file $rwin.cmdfr.edit $rwin.cmdfr.transfer \
      $rwin.cmdfr.mail $rwin.cmdfr.option $rwin.cmdfr.help \
      -side left -padx 5 -pady 0
   pack $rwin.cmdfr.space -side left -expand yes -fill both
   pack $rwin.cmdfr.logo -side left -padx 5 -pady 0 -side left
   pack $rwin.namefr.lbl -side left -padx 0 -pady 0
   pack $rwin.namefr.ent -side left -padx 0 -pady 0 -expand yes -fill x
   pack $rwin.mainfr.editfr.hscroll -padx 0 -pady 0 -fill x -side bottom
   pack $rwin.mainfr.editfr.scrbar -fill y -side right -padx 0 -pady 0
   pack $rwin.mainfr.editfr.textarea -expand yes -fill both -side right -padx 0 -pady 0
   pack $rwin.mainfr.olview -padx 0 -pady 0 -fill x -side bottom
   pack $rwin.mainfr.editfr -padx 0 -pady 0 -expand yes -fill both
   pack $rwin.cmdfr -padx 0 -pady 0 -fill x
   pack $rwin.namefr -padx 5 -pady 5 -fill x
   pack $rwin.mainfr -padx 2 -pady 2 -fill x -expand yes -fill both

   wm title $rwin "dvedit: Edit transliterated text"
   wm iconname $rwin "dvedit: help"
   wm iconbitmap $rwin @$installdir/images/dvedit-logo.xbm

   bind $rwin <Alt-KeyRelease-c> "saveRomanConfirm $rwin; destroy $rwinid"
   bind $rwin <Alt-f> "transferLine $rwin"
   bind $rwin <Alt-h> {helpwinRoman}
   bind $rwin <Alt-l> "loadRomanFile $rwin"
   bind $rwin <Alt-m> "sendMail 1"
   bind $rwin <Alt-n> "saveRomanConfirm $rwin; $rwin.mainfr.editfr.textarea delete 1.0 end; set rfname {}; set bnstr {}"
   bind $rwin <Alt-o> "set opttype 2; editOptions 1"
   bind $rwin <Alt-q> "quitEditor"
   bind $rwin <Alt-s> "saveasRomanFile $rwin"
   bind $rwin <Alt-t> "transferText $rwin"
   bind $rwin <Alt-v> "saveRomanFile $rwin"
   bind $rwin <Alt-x> "transferSelText $rwin"
   bind $rwin <Alt-KeyRelease-C> "saveRomanConfirm $rwin; destroy $rwinid; set rwinid -1"
   bind $rwin <Alt-F> "transferLine $rwin"
   bind $rwin <Alt-H> {helpwinRoman}
   bind $rwin <Alt-L> "loadRomanFile $rwin"
   bind $rwin <Alt-M> "sendMail 1"
   bind $rwin <Alt-N> "saveRomanConfirm $rwin; $rwin.mainfr.editfr.textarea delete 1.0 end; set rfname {}; set bnstr {}"
   bind $rwin <Alt-O> "set opttype 2; editOptions 1"
   bind $rwin <Alt-Q> "quitEditor"
   bind $rwin <Alt-S> "saveasRomanFile $rwin"
   bind $rwin <Alt-T> "transferText $rwin"
   bind $rwin <Alt-V> "saveRomanFile $rwin"
   bind $rwin <Alt-X> "transferSelText $rwin"
   bind $rwin.mainfr.editfr.textarea <Any-Key> {
      if { ([string compare %A " "] >= 0) && ([string compare %A "~"] <= 0) } {
         incr rdirtybit 1
      }
      if {![string compare %A "\t"]} { incr rdirtybit 1 }
      if {![string compare %A "\n"]} { incr rdirtybit 1 }
      if {![string compare %A "\r"]} { incr rdirtybit 1 }
      if {![string compare %A "\f"]} { incr rdirtybit 1 }
   }
   bind $rwin.mainfr.editfr.textarea <Alt-Key> { }
   bind $rwin.mainfr.editfr.textarea <Control-Key> { }
   bind $rwin.mainfr.editfr.textarea <BackSpace> { incr rdirtybit 1 }
   bind $rwin.mainfr.editfr.textarea <Control-h> { incr rdirtybit 1 }
   bind $rwin.mainfr.editfr.textarea <Delete> { incr rdirtybit 1 }
   bind $rwin.mainfr.editfr.textarea <Control-d> { incr rdirtybit 1 }
   bind $rwin.mainfr.editfr.textarea <Meta-d> { incr rdirtybit 1 }
   bind $rwin.mainfr.editfr.textarea <Control-k> { incr rdirtybit 1 }
   bind $rwin.mainfr.editfr.textarea <Control-o> { incr rdirtybit 1 }
   bind $rwin.mainfr.editfr.textarea <Control-w> { incr rdirtybit 1 }
   bind $rwin.mainfr.editfr.textarea <Control-x> { incr rdirtybit 1 }
   bind $rwin.mainfr.editfr.textarea <Control-t> { incr rdirtybit 1 }

   focus $rwin.mainfr.editfr.textarea

   menu $rwin.b2m  -tearoff false -bg $appbg -fg $appfg
   $rwin.b2m add command -label " Cut " -command "rcutBuffer"
   $rwin.b2m add command -label " Copy " -command "rcopyBuffer"
   $rwin.b2m add command -label " Paste " -command "rpasteBuffer"
   $rwin.b2m add separator
   $rwin.b2m add command -label " Transfer text " -command "transferText $rwin"
   $rwin.b2m add command -label " Transfer line " -command "transferLine $rwin"
   $rwin.b2m add command -label " Transfer selection " -command "transferSelText $rwin"
   $rwin.b2m add separator
   $rwin.b2m add command -label " Conversion rules " -command {helpwinRoman}

   menu $rwin.b3m  -tearoff false -bg $appbg -fg $appfg
   $rwin.b3m add command -label " Load file " -command "loadRomanFile $rwin"
   $rwin.b3m add command -label " Save file " -command "saveRomanFile $rwin"
   $rwin.b3m add command -label " Save as file " -command "saveasRomanFile $rwin"
   $rwin.b3m add separator
   $rwin.b3m add command -label " Send mail " -command "sendMail 1"
   $rwin.b3m add command -label " Read dvencoded file " -command "readDV"
   $rwin.b3m add separator
   $rwin.b3m add command -label " Close " -command "saveRomanConfirm $rwin; destroy $rwinid; set rwinid -1"
   $rwin.b3m add command -label " Quit " -command "quitEditor"

   bind $rwin.mainfr.editfr.textarea <ButtonPress-2> "$rwin.b2m post %X %Y; $rwin.b2m activate 0; grab set -global $rwin.b2m"
   bind $rwin.mainfr.editfr.textarea <ButtonPress-3> "$rwin.b3m post %X %Y; $rwin.b3m activate 0; grab set -global $rwin.b3m"
   bind $rwin.mainfr.editfr.textarea <Any-KeyRelease> "setbnstr $rwin"
   bind $rwin.mainfr.editfr.textarea <ButtonRelease-1> "setbnstr $rwin"
}

if {$editrmn} { editRoman }

proc sendMail { option } {
   global rwinid smwinid btnbg btnfg appbg appfg smoption
   global dvmaildir mailcmd mimen mimed uun uud

   set dbox [toplevel .mwin]
   set smwinid $dbox
   set smoption $option
   $dbox config -bg $appbg
   frame $dbox.fr1 -bg $appbg
   frame $dbox.fr2 -bg $appbg
   frame $dbox.fr3 -bg $appbg
   frame $dbox.fr4 -bg $appbg

   label $dbox.fr1.lbl -text "To:" -relief flat -anchor w -fg $appfg -bg $appbg
   entry $dbox.fr1.ent -textvariable mailto -bg #ddaaaa -fg #000000 -width 40
   label $dbox.fr2.lbl -text "Subject:" -relief flat -anchor w -fg $appfg -bg $appbg
   entry $dbox.fr2.ent -textvariable mailsub -bg #ddaaaa -fg #000000 -width 40
   label $dbox.fr3.lbl -text "Encoding:" -relief flat -anchor w -fg $appfg -bg $appbg
   menubutton $dbox.fr3.btn -text "Plain text" -height 1 -width 15 \
      -relief raised -menu $dbox.fr3.btn.m -bg $appbg -fg $appfg \
      -activebackground $appbg -activeforeground $appfg
   menu $dbox.fr3.btn.m -tearoff false -bg $appbg -fg $appfg
   $dbox.fr3.btn.m add command -label " Plain text " -command "$dbox.fr3.btn config -text {Plain text}"
   $dbox.fr3.btn.m add command -label " dvencode " -command "$dbox.fr3.btn config -text {dvencode}"
   if {($smoption == 0)} {
      $dbox.fr3.btn.m add command -label " MIME encoding " -command "$dbox.fr3.btn config -text {MIME encoding}"
      $dbox.fr3.btn.m add command -label " uuencode " -command "$dbox.fr3.btn config -text {uuencode}"
   }
   button $dbox.fr4.send -text "Send" -relief raised -command {
      if {![file exists $dvmaildir]} {
         exec mkdir $dvmaildir
         exec chmod 700 $dvmaildir
      }
      if {[file exists $dvmaildir] && [file isdirectory $dvmaildir] && [file writable $dvmaildir]} {
         set enctype [$smwinid.fr3.btn cget -text]
         set fno 1
         while {[file exists $dvmaildir/raw.$fno]} { incr fno 1 }
         if {($smoption == 0)} {
            set t [.mainfr.editfr.textarea get 1.0 end]
         } else {
            set t [$rwinid.mainfr.editfr.textarea get 1.0 end]
         }
         set rawfile [open $dvmaildir/raw.$fno w]
         puts -nonewline $rawfile $t
         close $rawfile
         if {![string compare $enctype "Plain text"]} {
            exec cp $dvmaildir/raw.$fno $dvmaildir/snd.$fno
         } elseif {![string compare $enctype "MIME encoding"]} {
            regsub -all "%f" $mimen $dvmaildir/raw.$fno enccmd
            set t [eval exec $enccmd]
            set sndfile [open $dvmaildir/snd.$fno w]
            puts $sndfile $t
            close $sndfile
         } elseif {![string compare $enctype "uuencode"]} {
            regsub -all "%f" $uun $dvmaildir/raw.$fno enccmd
            set t [eval exec $enccmd]
            set sndfile [open $dvmaildir/snd.$fno w]
            puts $sndfile $t
            close $sndfile
         } elseif {![string compare $enctype "dvencode"]} {
            dvenc $dvmaildir/raw.$fno $dvmaildir/snd.$fno $smoption
         }
         regsub -all "%f" $mailcmd  $dvmaildir/snd.$fno emc
         regsub -all "%s" $emc "\"$mailsub\"" emc
         regsub -all "%r" $emc "\"$mailto\"" emc
         set mailto [string trim $mailto]
         if {[string length $mailto] > 0} {
            eval exec $emc
            set ok 1
         } elseif {($smoption == 0)} {
            set ok 1
            errmsg "No recipient given"
         } else {
            set ok 1
            errmsg2 "No recipient given" $rwinid
         }
      } elseif {($smoption == 0)} {
         errmsg "Unable to access mail directory $dvmaildir"
         set ok 1
      } else {
         errmsg2 "Unable to access mail directory $dvmaildir" $rwinid
         set ok 1
      }
   } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg
   button $dbox.fr4.cancel -text "Cancel" -relief raised -command "set ok 0" \
      -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg
   label $dbox.fr4.space -text "" -fg $appfg -bg $appbg -relief flat

   pack $dbox.fr1.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr1.ent -padx 5 -pady 5
   pack $dbox.fr2.lbl -padx 5 -pady 5 -side left -expand yes -fill x
   pack $dbox.fr2.ent -padx 5 -pady 5
   pack $dbox.fr3.lbl $dbox.fr3.btn -padx 5 -pady 5 -expand no -side left
   pack $dbox.fr4.send -padx 5 -pady 5 -expand no -side left
   pack $dbox.fr4.space -padx 5 -pady 5 -expand yes -fill x -side left
   pack $dbox.fr4.cancel -padx 5 -pady 5 -expand no -side left
   pack $dbox.fr1 $dbox.fr2 -expand yes -fill x
   pack $dbox.fr3 -expand no
   pack $dbox.fr4 -expand yes -fill x
   

   wm title $dbox "dvedit: Send mail"
   wm resizable $dbox false false
   focus $dbox.fr1.ent
   bind $dbox <Escape> {set ok 1}
   bind $dbox.fr1.ent <Return> "focus $dbox.fr2.ent"
   bind $dbox.fr2.ent <Return> "focus $dbox.fr1.ent"
   grab $dbox
   tkwait variable ok
   grab release $dbox
   destroy $dbox
}

proc hexdigit { decimal } {
   if { ($decimal < 0) || ($decimal >= 16) } {
      return "?";
   }
   if { $decimal < 10 } { return "$decimal" }
   if { $decimal == 10 } { return "A" }
   if { $decimal == 11 } { return "B" }
   if { $decimal == 12 } { return "C" }
   if { $decimal == 13 } { return "D" }
   if { $decimal == 14 } { return "E" }
   return "F";
}

proc dvenc { inf outf option } {
   global customfontno customfid

   set f [open $inf r]
   set t [read $f]
   close $f
   set f [open $outf w]
   set tt "begin dvenc\n$option\n"
   set len [string length $t]
   for {set i 0} {$i < $len} {incr i 1} {
      set nextch [string range $t $i $i]
      if {![string compare $nextch "\n"]} {
         set tt "$tt\n"
      } else {
         scan $nextch "%c" asciival
         set tt "$tt[hexdigit [expr $asciival / 16]][hexdigit [expr $asciival % 16]]"
      }
   }
   puts $f $tt
   puts $f "end dvenc"
   if {($option == 0)} {
      foreach tagname { ultag suptag supsuptag subsuptag subtag subsubtag supsubtag english } {
         set tagranges [.mainfr.editfr.textarea tag ranges $tagname]
         if {[llength $tagranges] > 0} { puts $f "$tagname\t: $tagranges" }
      }
      foreach point {100 120 150 180 210 250 300 360} {
         set tagranges [.mainfr.editfr.textarea tag ranges devnagari${point}o ]
         if {[llength $tagranges] > 0} { puts $f "devnagari${point}o\t: $tagranges" }
         set tagranges [.mainfr.editfr.textarea tag ranges devnagari${point}r ]
         if {[llength $tagranges] > 0} { puts $f "devnagari${point}r\t: $tagranges" }
      }
      for {set i 0} {$i < $customfontno} {incr i 1} {
         set tagname customftag$i
         set tagranges [.mainfr.editfr.textarea tag ranges $tagname]
         if {[llength $tagranges] > 0} {
            set fid $customfid($i)
            puts $f "customfont\t: $fid\t$tagranges"
         }
      }
   }
   close $f
}

proc readMIME { } {
   global mimed fname dirtybit

   saveConfirm
   set fn [getFileName "dvedit: read MIME encoded file"]
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         errmsg "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         return
      }
      regsub -all "%f" $mimed $fn deccmd
      set x [eval exec $deccmd]
      clearTextArea
      .mainfr.editfr.textarea insert 1.0 $x
      set dirtybit 1
      set ext [file extension $fn]
      if {[string length $ext] == 0} {
         set fname "$fn.dvn"
      } else {
         set idx [string last $ext $fn]
         set fname "[string range $fn 0 [expr $idx - 1]].dvn"
      }
      wm title . "dvedit: $fname"
      .mainfr.editfr.textarea see insert
   }
}

proc readUU { } {
   global uud fname dirtybit

   saveConfirm
   set fn [getFileName "dvedit: read uuencoded file"]
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         errmsg "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         return
      }
      regsub -all "%f" $uud $fn deccmd
      set x [eval exec $deccmd]
      clearTextArea
      .mainfr.editfr.textarea insert 1.0 $x
      set dirtybit 1
      set ext [file extension $fn]
      if {[string length $ext] == 0} {
         set fname "$fn.dvn"
      } else {
         set idx [string last $ext $fn]
         set fname "[string range $fn 0 [expr $idx - 1]].dvn"
      }
      wm title . "dvedit: $fname"
      .mainfr.editfr.textarea see insert
   }
}

proc readDV { } {
   global rwinid fname rfname dirtybit rdirtybit

   set fn [getFileName "dvedit: read dvencoded file"]
   if { [string compare $fn ""] != 0 } {
      if {![file readable $fn]} {
         errmsg "ERROR:\nI cannot load the file \"$fn\". The file does not exist or does not have read permission."
         return
      }
      if {![file isfile $fn]} {
         errmsg "ERROR:\nI cannot load the file. \"$fn\" is not a regular file."
         return
      }
      set f [open $fn r]
      set status 0
      set x ""
      while { [gets $f line] >= 0 } {
         switch -exact $status {
            "0" {
               if {![string compare $line "begin dvenc"]} {set status 1}
            }
            "1" {
               set status 2
               if {![string compare $line "0"]} {incr status 2}
            }
            "2" {
               if {![string compare $line "end dvenc"]} {
                  if {![winfo exists $rwinid]} { editRoman }
                  saveRomanConfirm $rwinid
                  $rwinid.mainfr.editfr.textarea delete 1.0 end
                  $rwinid.mainfr.editfr.textarea insert 1.0 $x
                  $rwinid.mainfr.editfr.textarea see insert
                  set rdirtybit 1
                  setbnstr $rwinid
                  set status 3
               } else {
                  set len [expr [string length $line] - 1]
                  for {set i 0} {$i < $len} {incr i 2} {
                     set x "$x[hextochar [string range $line $i [expr $i + 1]]]"
                  }
                  set x "$x\n"
               }
            }
            "3" { }
            "4" {
               if {![string compare $line "end dvenc"]} {
                  saveConfirm
                  .mainfr.editfr.textarea delete 1.0 end
                  .mainfr.editfr.textarea insert 1.0 $x
                  .mainfr.editfr.textarea see insert
                  set dirtybit 1
                  set status 5
               } else {
                  set len [expr [string length $line] - 1]
                  for {set i 0} {$i < $len} {incr i 2} {
                     set x "$x[hextochar [string range $line $i [expr $i + 1]]]"
                  }
                  set x "$x\n"
               }
            }
            "5" {
               addTag $line
            }
         }
      }

      set ext [file extension $fn]
      if { ($status == 2) || ($status == 3) } {
         if {[string length $ext] == 0} {
            set rfname "$fn.dtx"
         } else {
            set idx [string last $ext $fn]
            set rfname "[string range $fn 0 [expr $idx - 1]].dtx"
         }
         $rwinid.mainfr.editfr.textarea see insert
      } elseif { ($status >= 4) } {
         if {[string length $ext] == 0} {
            set fname "$fn.dvn"
         } else {
            set idx [string last $ext $fn]
            set fname "[string range $fn 0 [expr $idx - 1]].dvn"
         }
         wm title . "dvedit: $fname"
         .mainfr.editfr.textarea see insert
      }
   }
}

proc hextochar { hexval } {
   set hhex [string range $hexval 0 0]
   set lhex [string range $hexval 1 1]
   switch -exact $hhex {
      "A" { set hval 10 }
      "B" { set hval 11 }
      "C" { set hval 12 }
      "D" { set hval 13 }
      "E" { set hval 14 }
      "F" { set hval 15 }
      default { set hval $hhex }
   }
   switch -exact $lhex {
      "A" { set lval 10 }
      "B" { set lval 11 }
      "C" { set lval 12 }
      "D" { set lval 13 }
      "E" { set lval 14 }
      "F" { set lval 15 }
      default { set lval $lhex }
   }
   return [format "%c" [expr 16 * $hval + $lval]]
}

proc addTag { line } {
   global customfontno customfid fontlist scriptlist

   set endidx [.mainfr.editfr.textarea index end]
   set colonidx [ string first ":" $line ]
   if {$colonidx > 0} {
      set tagname [ string range $line 0 [expr $colonidx - 1] ]
      set tagranges [ string range $line [expr $colonidx + 1] [ expr [string length $line] - 1] ]
      set tagname [ string trim $tagname ]
      set tagranges [ string trim $tagranges ]
      set cfidx -1
      if {![string compare $tagname "customfont"]} {
         set tabidx [string first "\t" $tagranges]
         if {$tabidx > 0} {
            set tagname [string trim [string range $tagranges 0 [expr $tabidx - 1]]]
            set tagranges [string trim [string range $tagranges [expr $tabidx + 1] [expr [string length $tagranges] - 1]]]
            for {set i 0} {$i < $customfontno} {incr i 1} {
               if {![string compare $tagname $customfid($i)]} { set cfidx $i }
            }
            if {$cfidx == -1} {
               set cfidx $customfontno
               incr customfontno 1
               set customfid($cfidx) $tagname
               if {[lsearch -exact $fontlist $tagname] < 0} {
                  puts "Unable to find font $tagname.. using fixed instead"
                  .mainfr.editfr.textarea tag config customftag$cfidx -font fixed
               } else {
                  .mainfr.editfr.textarea tag config customftag$cfidx -font $tagname
               }
            }
         } else { set cfidx -2 }
      }
      set tagranges [split $tagranges " "]
      if {$cfidx != 2} {
         while {[llength $tagranges] > 1} {
            set tagfirst [lindex $tagranges 0]
            set taglast [lindex $tagranges 1]
            set tagranges [lreplace $tagranges 0 1]
            if { [regexp {[0-9]+\.[0-9]+} $tagfirst] && [regexp {[0-9]+\.[0-9]+} $taglast] && ($tagfirst <= $taglast) && ($tagfirst >= 1.0) && ($taglast <= $endidx)} {
               if {[lsearch -exact $scriptlist $tagname] >= 0} {
                  .mainfr.editfr.textarea tag remove suptag $tagfirst $taglast
                  .mainfr.editfr.textarea tag remove supsuptag $tagfirst $taglast
                  .mainfr.editfr.textarea tag remove subsuptag $tagfirst $taglast
                  .mainfr.editfr.textarea tag remove subtag $tagfirst $taglast
                  .mainfr.editfr.textarea tag remove subsubtag $tagfirst $taglast
                  .mainfr.editfr.textarea tag remove supsubtag $tagfirst $taglast
               }
               foreach point {100 120 150 180 210 250 300 360} {
                  .mainfr.editfr.textarea tag remove devnagari${point}o $tagfirst $taglast
                  .mainfr.editfr.textarea tag remove devnagari${point}r $tagfirst $taglast
               }
               .mainfr.editfr.textarea tag remove english $tagfirst $taglast
               for {set i 0} {$i < $customfontno} {incr i 1} {
                  .mainfr.editfr.textarea tag remove customftag$i $tagfirst $taglast
               }
               if {$cfidx == -1} {
                  .mainfr.editfr.textarea tag add $tagname $tagfirst $taglast
               } else {
                  .mainfr.editfr.textarea tag add customftag$cfidx $tagfirst $taglast
               }
            }
         }
      }
   }
}

set opttype 1
proc editOptions { wo } {
   global appfg appbg btnfg btnbg opttype rwinid hdrtxt
   global textbg textfg textsbg textsfg textibg textht textwd ptsize slant charmap charmap2
   global oldtextbg oldtextfg oldtextsbg oldtextsfg oldtextibg oldtextht oldtextwd oldptsize oldslant oldcharmap
   global textbg2 textfg2 textsbg2 textsfg2 textibg2 textht2 textwd2 editrmn
   global oldtextbg2 oldtextfg2 oldtextsbg2 oldtextsfg2 oldtextibg2 oldtextht2 oldtextwd2 oldeditrmn
   global oldolfg oldolbg olfg olbg
   global dvmaildir mailcmd mimen mimed uun uud
   global olddvmaildir oldmailcmd oldmimen oldmimed olduun olduud
   global opwinid where hdrfont

   set where $wo
   set oldtextbg $textbg
   set oldtextfg $textfg
   set oldtextsbg $textsbg
   set oldtextsfg $textsfg
   set oldtextibg $textibg
   set oldtextht $textht
   set oldtextwd $textwd
   set oldptsize $ptsize
   set oldslant $slant
   set oldcharmap $charmap
   set tempcharmap $charmap
   set charmap2 $charmap
   set oldtextbg2 $textbg2
   set oldtextfg2 $textfg2
   set oldtextsbg2 $textsbg2
   set oldtextsfg2 $textsfg2
   set oldtextibg2 $textibg2
   set oldtextht2 $textht2
   set oldtextwd2 $textwd2
   set oldeditrmn $editrmn
   set oldolfg $olfg
   set oldolbg $olbg
   set olddvmaildir $dvmaildir
   set oldmailcmd $mailcmd
   set oldmimen $mimen
   set oldmimed $mimed
   set olduun $uun
   set olduud $uud
   set ok 0

   set dbox [toplevel .option]
   set opwinid $dbox
   $dbox config -bg $appbg

   frame $dbox.selfr -bg $appbg -relief raised
   radiobutton $dbox.selfr.main -relief flat -highlightthickness 0 \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activebackground $appbg -activeforeground $appfg \
      -variable opttype -value 1 -text "Main"
   radiobutton $dbox.selfr.roman -relief flat -highlightthickness 0 \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activebackground $appbg -activeforeground $appfg \
      -variable opttype -value 2 -text "Transliterator"
   radiobutton $dbox.selfr.mail -relief flat -highlightthickness 0 \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activebackground $appbg -activeforeground $appfg \
      -variable opttype -value 3 -text "Mail"

   bind $dbox.selfr.main <ButtonPress-1> {
      if {$opttype != 1} {
         pack forget $opwinid.roman $opwinid.mail $opwinid.sep2 $opwinid.btnfr
         pack $opwinid.main -expand yes -fill both -pady 5
         pack $opwinid.sep2 -expand yes -fill x -padx 5 -pady 5
         pack $opwinid.btnfr -expand no -pady 5
         set hdrtxt "Main window options"
         set opttype 1
      }
   }
   bind $dbox.selfr.roman <ButtonPress-1> {
      if {$opttype != 2} {
         pack forget $opwinid.main $opwinid.mail $opwinid.sep2 $opwinid.btnfr
         pack $opwinid.roman -expand yes -fill both -pady 5
         pack $opwinid.sep2 -expand yes -fill x -padx 5 -pady 5
         pack $opwinid.btnfr -expand no -pady 5
         set hdrtxt "Transliterator window options"
         set opttype 2
      }
   }
   bind $dbox.selfr.mail <ButtonPress-1> {
      if {$opttype != 3} {
         pack forget $opwinid.main $opwinid.roman $opwinid.sep2 $opwinid.btnfr
         pack $opwinid.mail -expand yes -fill both -pady 5
         pack $opwinid.sep2 -expand yes -fill x -padx 5 -pady 5
         pack $opwinid.btnfr -expand no -pady 5
         set hdrtxt "Mail options"
         set opttype 3
      }
   }

   frame $dbox.sep1 -bg $appfg -height 3 -relief flat
   frame $dbox.sep2 -bg $appfg -height 3 -relief flat

   switch -exact $opttype {
      2 { set hdrtxt "Transliterator window options" }
      3 { set hdrtxt "Mail options" }
      default { set hdrtxt "Main window options" }
   }
   label $dbox.hdr -bg $appbg -fg #8800AA -relief flat -textvariable hdrtxt -font $hdrfont

   frame $dbox.main -bg $appbg
   frame $dbox.main.fr1 -bg $appbg
   frame $dbox.main.fr2 -bg $appbg
   frame $dbox.main.fr3 -bg $appbg
   frame $dbox.main.fr4 -bg $appbg
   frame $dbox.main.fr5 -bg $appbg
   frame $dbox.main.fr6 -bg $appbg
   frame $dbox.main.fr7 -bg $appbg
   frame $dbox.main.fr8 -bg $appbg
   frame $dbox.main.fr9 -bg $appbg
   label $dbox.main.fr1.lbl -text "Text background color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr1.ent -textvariable textbg -bg #ddaaaa -fg #000000
   label $dbox.main.fr2.lbl -text "Text foreground color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr2.ent -textvariable textfg -bg #ddaaaa -fg #000000
   label $dbox.main.fr3.lbl -text "Selection background color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr3.ent -textvariable textsbg -bg #ddaaaa -fg #000000
   label $dbox.main.fr4.lbl -text "Selection foreground color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr4.ent -textvariable textsfg -bg #ddaaaa -fg #000000
   label $dbox.main.fr5.lbl -text "Cursor color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr5.ent -textvariable textibg -bg #ddaaaa -fg #000000
   label $dbox.main.fr6.lbl -text "Text height (number of lines): " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr6.ent -textvariable textht -bg #ddaaaa -fg #000000
   label $dbox.main.fr7.lbl -text "Text width (in avg char width): " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.main.fr7.ent -textvariable textwd -bg #ddaaaa -fg #000000
   label $dbox.main.fr8.lbl -text "Default point size: " -relief flat -anchor e -fg $appfg -bg $appbg
   menubutton $dbox.main.fr8.pt -textvariable ptsize -height 1 -width 8 \
      -relief raised -menu $dbox.main.fr8.pt.m -bg $appbg -fg $appfg \
      -activebackground $appbg -activeforeground $appfg
   menu $dbox.main.fr8.pt.m -tearoff false -bg $appbg -fg $appfg
   $dbox.main.fr8.pt.m add command -label " 100 " -command {set ptsize 100}
   $dbox.main.fr8.pt.m add command -label " 120 " -command {set ptsize 120}
   $dbox.main.fr8.pt.m add command -label " 150 " -command {set ptsize 150}
   $dbox.main.fr8.pt.m add command -label " 180 " -command {set ptsize 180}
   $dbox.main.fr8.pt.m add command -label " 210 " -command {set ptsize 210}
   $dbox.main.fr8.pt.m add command -label " 250 " -command {set ptsize 250}
   $dbox.main.fr8.pt.m add command -label " 300 " -command {set ptsize 300}
   $dbox.main.fr8.pt.m add command -label " 360 " -command {set ptsize 360}
   checkbutton $dbox.main.fr9.cb1 -text " Slanted " \
      -variable slant -onvalue "o" -offvalue "r" -relief ridge \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg
   checkbutton $dbox.main.fr9.cb2 -text " Show character array " \
      -variable charmap2 -onvalue 1 -offvalue 0 -relief ridge \
      -selectcolor #bbff00 -fg $appfg -bg $appbg \
      -activeforeground $appfg -activebackground $appbg

   for {set i 1} {$i <= 7} {incr i 1} {
      pack $dbox.main.fr$i.lbl -padx 5 -pady 5 -side left -expand yes -fill x
      pack $dbox.main.fr$i.ent -padx 5 -pady 5
      pack $dbox.main.fr$i -padx 5 -pady 2 -expand yes -fill x
   }
   pack $dbox.main.fr8.lbl $dbox.main.fr8.pt -padx 5 -pady 5 -side left
   pack $dbox.main.fr8 -padx 5 -pady 2
   pack $dbox.main.fr9.cb1 $dbox.main.fr9.cb2 -padx 5 -pady 5 -side left
   pack $dbox.main.fr9 -padx 5 -pady 2
   bind $dbox.main.fr1.ent <Return>  "focus $dbox.main.fr2.ent"
   bind $dbox.main.fr2.ent <Return>  "focus $dbox.main.fr3.ent"
   bind $dbox.main.fr3.ent <Return>  "focus $dbox.main.fr4.ent"
   bind $dbox.main.fr4.ent <Return>  "focus $dbox.main.fr5.ent"
   bind $dbox.main.fr5.ent <Return>  "focus $dbox.main.fr6.ent"
   bind $dbox.main.fr6.ent <Return>  "focus $dbox.main.fr7.ent"
   bind $dbox.main.fr7.ent <Return>  "focus $dbox.main.fr1.ent"

   frame $dbox.roman -bg $appbg
   frame $dbox.roman.fr1 -bg $appbg
   frame $dbox.roman.fr2 -bg $appbg
   frame $dbox.roman.fr3 -bg $appbg
   frame $dbox.roman.fr4 -bg $appbg
   frame $dbox.roman.fr5 -bg $appbg
   frame $dbox.roman.fr6 -bg $appbg
   frame $dbox.roman.fr7 -bg $appbg
   frame $dbox.roman.fr8 -bg $appbg
   frame $dbox.roman.fr9 -bg $appbg
   label $dbox.roman.fr1.lbl -text "Text background color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr1.ent -textvariable textbg2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr2.lbl -text "Text foreground color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr2.ent -textvariable textfg2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr3.lbl -text "Selection background color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr3.ent -textvariable textsbg2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr4.lbl -text "Selection foreground color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr4.ent -textvariable textsfg2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr5.lbl -text "Cursor color: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr5.ent -textvariable textibg2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr6.lbl -text "Text height (number of lines): " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr6.ent -textvariable textht2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr7.lbl -text "Text width (in avg char width): " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr7.ent -textvariable textwd2 -bg #ddaaaa -fg #000000
   label $dbox.roman.fr8.lbl -text "Background color for online text: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr8.ent -textvariable olbg -bg #ddaaaa -fg #000000
   label $dbox.roman.fr9.lbl -text "Foreground color for online text: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.roman.fr9.ent -textvariable olfg -bg #ddaaaa -fg #000000
   checkbutton $dbox.roman.cb -text " Show edit window for Roman text at start-up " \
         -variable editrmn -onvalue 1 -offvalue 0 -relief ridge \
         -selectcolor #bbff00 -fg $appfg -bg $appbg \
         -activeforeground $appfg -activebackground $appbg

   for {set i 1} {$i <= 9} {incr i 1} {
      pack $dbox.roman.fr$i.lbl -padx 5 -pady 5 -side left -expand yes -fill x
      pack $dbox.roman.fr$i.ent -padx 5 -pady 5
      pack $dbox.roman.fr$i -padx 5 -pady 2 -expand yes -fill x
   }
   pack $dbox.roman.cb -padx 5 -pady 5

   bind $dbox.roman.fr1.ent <Return> "focus $dbox.roman.fr2.ent"
   bind $dbox.roman.fr2.ent <Return> "focus $dbox.roman.fr3.ent"
   bind $dbox.roman.fr3.ent <Return> "focus $dbox.roman.fr4.ent"
   bind $dbox.roman.fr4.ent <Return> "focus $dbox.roman.fr5.ent"
   bind $dbox.roman.fr5.ent <Return> "focus $dbox.roman.fr6.ent"
   bind $dbox.roman.fr6.ent <Return> "focus $dbox.roman.fr7.ent"
   bind $dbox.roman.fr7.ent <Return> "focus $dbox.roman.fr8.ent"
   bind $dbox.roman.fr8.ent <Return> "focus $dbox.roman.fr9.ent"
   bind $dbox.roman.fr9.ent <Return> "focus $dbox.roman.fr1.ent"

   frame $dbox.mail -bg $appbg
   frame $dbox.mail.fr1 -bg $appbg
   frame $dbox.mail.fr2 -bg $appbg
   frame $dbox.mail.fr3 -bg $appbg
   frame $dbox.mail.fr4 -bg $appbg
   frame $dbox.mail.fr5 -bg $appbg
   frame $dbox.mail.fr6 -bg $appbg

   label $dbox.mail.fr1.lbl -text "Mail cache directory: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr1.ent -textvariable dvmaildir -bg #ddaaaa -fg #000000 -width 30
   label $dbox.mail.fr2.lbl -text "Send mail command: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr2.ent -textvariable mailcmd -bg #ddaaaa -fg #000000 -width 30
   label $dbox.mail.fr3.lbl -text "MIME encoding command: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr3.ent -textvariable mimen -bg #ddaaaa -fg #000000 -width 30
   label $dbox.mail.fr4.lbl -text "MIME decoding command: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr4.ent -textvariable mimed -bg #ddaaaa -fg #000000 -width 30
   label $dbox.mail.fr5.lbl -text "uuencoding command: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr5.ent -textvariable uun -bg #ddaaaa -fg #000000 -width 30
   label $dbox.mail.fr6.lbl -text "uudecoding command: " -relief flat -anchor e -fg $appfg -bg $appbg
   entry $dbox.mail.fr6.ent -textvariable uud -bg #ddaaaa -fg #000000 -width 30
   button $dbox.mail.clear -text "Clear mail cache" -relief raised -command {
      foreach file [glob -nocomplain $dvmaildir/raw.* $dvmaildir/snd.*] {
         exec rm -f $file
      }
   } -fg $appfg -bg $appbg -activeforeground $appfg -activebackground $appbg

   for {set i 1} {$i <= 6} {incr i 1} {
      pack $dbox.mail.fr$i.lbl -padx 5 -pady 5 -side left -expand yes -fill x
      pack $dbox.mail.fr$i.ent -padx 5 -pady 5
      pack $dbox.mail.fr$i -padx 5 -pady 2 -expand yes -fill x
   }
   pack $dbox.mail.clear -pady 2 -expand no

   bind $dbox.mail.fr1.ent <Return>  "focus $dbox.mail.fr2.ent"
   bind $dbox.mail.fr2.ent <Return>  "focus $dbox.mail.fr3.ent"
   bind $dbox.mail.fr3.ent <Return>  "focus $dbox.mail.fr4.ent"
   bind $dbox.mail.fr4.ent <Return>  "focus $dbox.mail.fr5.ent"
   bind $dbox.mail.fr5.ent <Return>  "focus $dbox.mail.fr6.ent"
   bind $dbox.mail.fr6.ent <Return>  "focus $dbox.mail.fr1.ent"

   frame $dbox.btnfr -bg $appbg -relief flat
   button $dbox.btnfr.apply -text "Apply" -relief raised -command {
      switch -exact $opttype {
         2 {
            if {[winfo exists $rwinid]} { applyRomanOptions $rwinid }
            set oldtextbg2 $textbg2
            set oldtextfg2 $textfg2
            set oldtextsbg2 $textsbg2
            set oldtextsfg2 $textsfg2
            set oldtextibg2 $textibg2
            set oldtextht2 $textht2
            set oldtextwd2 $textwd2
            set oldeditrmn $editrmn
            set oldolbg $olbg
            set oldolfg $olfg
         }
         3 {
            set olddvmaildir $dvmaildir
            set oldmailcmd $mailcmd
            set oldmimen $mimen
            set oldmimed $mimed
            set olduun $uun
            set olduud $uud
         }
         default {
            applyMainOptions
            set oldtextbg $textbg
            set oldtextfg $textfg
            set oldtextsbg $textsbg
            set oldtextsfg $textsfg
            set oldtextibg $textibg
            set oldtextht $textht
            set oldtextwd $textwd
            set oldptsize $ptsize
            set oldslant $slant
            set oldcharmap $charmap
         }
      }
   } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg
   button $dbox.btnfr.default -text "Default" -relief raised -command {
      if {$opttype == 1} { set oldcharmap $charmap }
      readOptions
      if {$opttype == 1} { set charmap2 $charmap; set charmap $oldcharmap }
   } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg
   button $dbox.btnfr.save -text "Save" -relief raised -command {
      if {$opttype == 1} { set tempcharmap $charmap; set charmap $charmap2 }
      if {$where == 0} { saveOptions 0 } else { saveOptions 1 $rwinid }
      if {$opttype == 1} { set charmap $tempcharmap }
      grab $opwinid
   } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg
   button $dbox.btnfr.cancel -text "Cancel" -relief raised -command {
      set textbg $oldtextbg
      set textfg $oldtextfg
      set textsbg $oldtextsbg
      set textsfg $oldtextsfg
      set textibg $oldtextibg
      set textht $oldtextht
      set textwd $oldtextwd
      set ptsize $oldptsize
      set slant $oldslant
      set charmap $oldcharmap
      set textbg2 $oldtextbg2
      set textfg2 $oldtextfg2
      set textsbg2 $oldtextsbg2
      set textsfg2 $oldtextsfg2
      set textibg2 $oldtextibg2
      set textht2 $oldtextht2
      set textwd2 $oldtextwd2
      set editrmn $oldeditrmn
      set olbg $oldolbg
      set olfg $oldolfg
      set dvmaildir $olddvmaildir
      set mailcmd $oldmailcmd
      set mimen $oldmimen
      set mimed $oldmimed
      set uun $olduun
      set uud $olduud
      set ok 1
   } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg
   button $dbox.btnfr.done -text "Done" -relief raised -command {
      if {$opttype == 1} {applyMainOptions}
      if {($opttype == 2) && [winfo exists $rwinid]} {applyRomanOptions $rwinid}
      set ok 1
   } -fg $btnfg -bg $btnbg -activeforeground $btnfg -activebackground $btnbg

   pack $dbox.selfr.main $dbox.selfr.roman $dbox.selfr.mail -padx 10 -expand no -side left
   pack $dbox.btnfr.apply $dbox.btnfr.default $dbox.btnfr.save $dbox.btnfr.cancel $dbox.btnfr.done -padx 5 -side left
   pack $dbox.selfr -expand no -pady 5
   pack $dbox.sep1 -expand yes -fill x -padx 5 -pady 5
   pack $dbox.hdr -expand no -pady 5
   switch -exact $opttype {
      2 { pack $dbox.roman -expand yes -fill both -pady 5 }
      3 { pack $dbox.mail -expand yes -fill both -pady 5 }
      default { pack $dbox.main -expand yes -fill both -pady 5 }
   }
   pack $dbox.sep2 -expand yes -fill x -padx 5 -pady 5
   pack $dbox.btnfr -expand no -pady 5

   bind $dbox <Escape> {set ok 1}
   wm resizable $dbox false false
   wm title $dbox "dvedit: Edit options"
   grab $dbox
   tkwait variable ok
   grab release $dbox
   destroy $dbox
}

set rbuffer ""

proc rcutBuffer {} {
   global rbuffer rdirtybit rwinid

   set lsel [$rwinid.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg2 "Text does not contain a selected region. Select text by left mouse button and retry." $rwinid
      return
   }

   incr rdirtybit 1
   set rbuffer [$rwinid.mainfr.editfr.textarea get sel.first sel.last]
   $rwinid.mainfr.editfr.textarea delete sel.first sel.last
   setbnstr $rwinid
   $rwinid.mainfr.editfr.textarea see insert
}

proc rcopyBuffer {} {
   global rbuffer rwinid

   set lsel [$rwinid.mainfr.editfr.textarea tag ranges sel]
   if {[llength $lsel] != 2} {
      errmsg2 "Text does not contain a selected region. Select text by left mouse button and retry." $rwinid
      return
   }

   set rbuffer [$rwinid.mainfr.editfr.textarea get sel.first sel.last]
}

proc rpasteBuffer {} {
   global rbuffer rdirtybit rwinid

   $rwinid.mainfr.editfr.textarea insert insert $rbuffer
   incr rdirtybit 1
   setbnstr $rwinid
   $rwinid.mainfr.editfr.textarea see insert
}

###########################################################################
# Copyright 1998 by Abhijit Das (abhij@csa.iisc.ernet.in).
# dvedit is a freeware. Permission is hereby granted to distribute and
# mirror it free of charge as long as the original author gets credit
# and this copyright notice remains intact.
###########################################################################
#
# End of dvedit
