home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 December / PCWorld_2000-12_cd.bin / Komunikace / Comanche / comanche.exe / lib / iwidgets2.2.0 / scripts / scrolledhtml.itk < prev    next >
Text File  |  1999-02-24  |  61KB  |  1,899 lines

  1. # Scrolledhtml
  2. # ----------------------------------------------------------------------
  3. # Implements a scrolled html text widget by inheritance from scrolledtext
  4. # Import reads from an html file, while export still writes plain text
  5. # Also provides a render command, to display html text passed in as an
  6. # argument.
  7. #
  8. # WISH LIST:
  9. #   This section lists possible future enhancements.
  10. #
  11. #   1) make images scroll smoothly off top like they do off bottom.
  12. #   2) support color of 'none' in images
  13. #   3) support for imagemaps
  14. #   4) add ability to get non-local URLs
  15. #   5) keep track of visited links
  16. #   6) add html 2.0 and 3.0 support (there are a few features supported now)
  17. #   7) add java applets support
  18. #
  19. # ----------------------------------------------------------------------
  20. #  AUTHOR: Kris Raney                    EMAIL: kraney@spd.dsccc.com
  21. #
  22. #  @(#) $Id: scrolledhtml.itk,v 1.2 1998/08/11 14:46:41 welch Exp $
  23. # ----------------------------------------------------------------------
  24. #            Copyright (c) 1996 DSC Technologies Corporation
  25. # ======================================================================
  26. # Permission to use, copy, modify, distribute and license this software
  27. # and its documentation for any purpose, and without fee or written
  28. # agreement with DSC, is hereby granted, provided that the above copyright
  29. # notice appears in all copies and that both the copyright notice and
  30. # warranty disclaimer below appear in supporting documentation, and that
  31. # the names of DSC Technologies Corporation or DSC Communications
  32. # Corporation not be used in advertising or publicity pertaining to the
  33. # software without specific, written prior permission.
  34. #
  35. # DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  36. # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
  37. # INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
  38. # AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE,
  39. # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL
  40. # DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  41. # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  42. # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
  43. # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  44. # SOFTWARE.
  45. # ======================================================================
  46.  
  47. # Acknowledgements:
  48. #
  49. # Special thanks go to Sam Shen(SLShen@lbl.gov), as this code is based on his
  50. # tkhtml.tcl code from tk inspect. The original code is copyright 1995
  51. # Lawrence Berkeley Laboratory.
  52. #
  53. # This software is copyright (C) 1995 by the Lawrence Berkeley Laboratory.
  54. #
  55. # Redistribution and use in source and binary forms, with or without
  56. # modification, are permitted provided that: (1) source code distributions
  57. # retain the above copyright notice and this paragraph in its entirety, (2)
  58. # distributions including binary code include the above copyright notice and
  59. # this paragraph in its entirety in the documentation or other materials
  60. # provided with the distribution, and (3) all advertising materials mentioning
  61. # features or use of this software display the following acknowledgement:
  62. # ``This product includes software developed by the University of California,
  63. # Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  64. # the University nor the names of its contributors may be used to endorse
  65. # or promote products derived from this software without specific prior
  66. # written permission.
  67. #
  68. # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  69. # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  70. # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  71. #
  72. # This code is based on Angel Li's (angel@flipper.rsmas.miami.edu) HTML
  73.  
  74.  
  75. #
  76. # Default resources.
  77. #
  78. option add *Scrolledhtml.borderWidth 2 widgetDefault
  79. option add *Scrolledhtml.relief sunken widgetDefault
  80. option add *Scrolledhtml.scrollMargin 3 widgetDefault
  81. option add *Scrolledhtml.width 500 widgetDefault
  82. option add *Scrolledhtml.height 600 widgetDefault
  83. option add *Scrolledhtml.visibleItems 80x24 widgetDefault
  84. option add *Scrolledhtml.vscrollMode static widgetDefault
  85. option add *Scrolledhtml.hscrollMode static widgetDefault
  86. option add *Scrolledhtml.labelPos n widgetDefault
  87. option add *Scrolledhtml.wrap word widgetDefault
  88.  
  89. #
  90. # Usual options.
  91. #
  92. itk::usual Scrolledhtml {
  93.     keep -fontname -fontsize -fixedfont -link  -linkhighlight \
  94.          -activebackground -activerelief -background -borderwidth -cursor \
  95.          -elementborderwidth -foreground -highlightcolor -highlightthickness \
  96.          -insertbackground -insertborderwidth -insertofftime -insertontime \
  97.          -insertwidth -jump -labelfont -selectbackground -selectborderwidth \
  98.          -selectforeground -textbackground -textfont -troughcolor -unknownimage
  99. }
  100.  
  101. # ------------------------------------------------------------------
  102. #                           SCROLLEDHTML
  103. # ------------------------------------------------------------------
  104. class ::iwidgets::Scrolledhtml {
  105.   inherit ::iwidgets::Scrolledtext
  106.  
  107.   constructor {args} {}
  108.  
  109.   itk_option define -feedback feedBack FeedBack {}
  110.   itk_option define -linkcommand linkCommand LinkCommand {}
  111.   itk_option define -fontname fontname FontName times
  112.   itk_option define -fixedfont fixedFont FixedFont courier
  113.   itk_option define -fontsize fontSize FontSize medium
  114.   itk_option define -link link Link blue
  115.   itk_option define -linkhighlight linkhighlight LinkHighLight red
  116.   itk_option define -unknownimage unknownimage File {}
  117.   itk_option define -textbackground textBackground Background {}
  118.  
  119.   public method import {args}
  120.   public method clear {}
  121.   public method render {html {wd .}}
  122.   public method title {} {return $_title}
  123.   public method pwd {} {return $_cwd}
  124.  
  125.   protected method _setup {}
  126.   protected method _set_tag {}
  127.   protected method _reconfig_tags {}
  128.   protected method _append_text {text}
  129.   protected method _definefont {name foundry family weight slant registry}
  130.   protected method _peek {instack}
  131.   protected method _push {instack value}
  132.   protected method _pop {instack}
  133.   protected method _parse_fields {array_var string}
  134.   protected method _href_click {cmd href}
  135.  
  136.   protected method _feedback {{val "next"}}
  137.   private variable _fbmax 0
  138.   private variable _fbcount 0
  139.  
  140.   protected method _header {level args}
  141.   protected method _/header {level}
  142.  
  143.   protected method _entity_a {args}
  144.   protected method _entity_/a {}
  145.   protected method _entity_address {}
  146.   protected method _entity_/address {}
  147.   protected method _entity_b {}
  148.   protected method _entity_/b {} 
  149.   protected method _entity_base {{args {}}}
  150.   protected method _entity_big {}
  151.   protected method _entity_/big {} 
  152.   protected method _entity_blockquote {}
  153.   protected method _entity_/blockquote {} 
  154.   protected method _entity_body {{args {}}}
  155.   protected method _entity_/body {}
  156.   protected method _entity_br {{args {}}}
  157.   protected method _entity_center {}
  158.   protected method _entity_/center {}
  159.   protected method _entity_cite {}
  160.   protected method _entity_/cite {}
  161.   protected method _entity_code {}
  162.   protected method _entity_/code {}
  163.   protected method _entity_dir {{args {}}}
  164.   protected method _entity_/dir {}
  165.   protected method _entity_dl {{args {}}}
  166.   protected method _entity_/dl {}
  167.   protected method _entity_dt {}
  168.   protected method _entity_dd {}
  169.   protected method _entity_dfn {}
  170.   protected method _entity_/dfn {}
  171.   protected method _entity_em {}
  172.   protected method _entity_/em {}
  173.   protected method _entity_h1 {{args {}}}
  174.   protected method _entity_/h1 {}
  175.   protected method _entity_h2 {{args {}}}
  176.   protected method _entity_/h2 {}
  177.   protected method _entity_h3 {{args {}}}
  178.   protected method _entity_/h3 {}
  179.   protected method _entity_h4 {{args {}}}
  180.   protected method _entity_/h4 {}
  181.   protected method _entity_h5 {{args {}}}
  182.   protected method _entity_/h5 {}
  183.   protected method _entity_h6 {{args {}}}
  184.   protected method _entity_/h6 {}
  185.   protected method _entity_hr {{args {}}}
  186.   protected method _entity_i {}
  187.   protected method _entity_/i {}
  188.   protected method _entity_img {args}
  189.   protected method _entity_kbd {}
  190.   protected method _entity_/kbd {}
  191.   protected method _entity_li {}
  192.   protected method _entity_listing {}
  193.   protected method _entity_/listing {}
  194.   protected method _entity_menu {{args {}}}
  195.   protected method _entity_/menu {}
  196.   protected method _entity_ol {{args {}}}
  197.   protected method _entity_/ol {}
  198.   protected method _entity_p {{args {}}}
  199.   protected method _entity_pre {{args {}}}
  200.   protected method _entity_/pre {}
  201.   protected method _entity_samp {}
  202.   protected method _entity_/samp {}
  203.   protected method _entity_small {}
  204.   protected method _entity_/small {} 
  205.   protected method _entity_sub {}
  206.   protected method _entity_/sub {} 
  207.   protected method _entity_sup {}
  208.   protected method _entity_/sup {} 
  209.   protected method _entity_strong {}
  210.   protected method _entity_/strong {}
  211.   protected method _entity_title {}
  212.   protected method _entity_/title {}
  213.   protected method _entity_tt {}
  214.   protected method _entity_/tt {}
  215.   protected method _entity_u {}
  216.   protected method _entity_/u {}
  217.   protected method _entity_ul {{args {}}}
  218.   protected method _entity_/ul {}
  219.   protected method _entity_var {}
  220.   protected method _entity_/var {}
  221.  
  222.   protected variable _title {}             ;# The title of the html document
  223.   protected variable _listyle bullet       ;# list element style
  224.   protected variable _lipic {}             ;# picture to use as bullet
  225.   protected variable _color black          ;# current text color
  226.   protected variable _bgcolor #d9d9d9      ;# current background color
  227.   protected variable _link blue            ;# current link color
  228.   protected variable _smallpoints "60 80 100 120 140 180 240"   ;# font point
  229.   protected variable _mediumpoints "80 100 120 140 180 240 360" ;# sizes for
  230.   protected variable _largepoints "100 120 140 180 240 360 480" ;# various
  231.   protected variable _hugepoints "120 140 180 240 360 480 640"  ;# fontsizes
  232.   protected variable _font times           ;# name of current font
  233.   protected variable _rulerheight 6        ;#
  234.   protected variable _indentincr 4         ;# increment to indent by
  235.   protected variable _counter -1           ;# counter to give unique numbers
  236.   protected variable _left 0               ;# initial left margin
  237.   protected variable _left2 0              ;# subsequent left margin
  238.   protected variable _right 0              ;# right margin
  239.   protected variable _justify L            ;# text justification
  240.   protected variable _offset 0             ;# text offset (super/subscript)
  241.   protected variable _textweight 0         ;# boldness of text
  242.   protected variable _textslant 0          ;# whether to use italics
  243.   protected variable _underline 0          ;# whether to use underline
  244.   protected variable _verbatim 0           ;# whether to skip formatting
  245.   protected variable _pre 0                ;# preformatted text
  246.   protected variable _intitle 0            ;# in <title>...</title>
  247.   protected variable _anchorcount 0        ;# number of anchors
  248.   protected variable _stack                ;# array of stacks
  249.   protected variable _pointsndx 2          ;# 
  250.   protected variable _fontnames            ;# list of accepted font names
  251.   protected variable _fontinfo             ;# array of font info given font name
  252.   protected variable _tag                  ;# 
  253.   protected variable _tagl                 ;#
  254.   protected variable _tagfont              ;#
  255.   protected variable _cwd .                ;# base directory of current page
  256.   protected variable _anchor               ;# array of indexes by anchorname
  257.   protected variable _defaulttextbackground;# default text background
  258.  
  259.   private variable _initialized 0
  260.  
  261.   private variable _defUnknownImg [image create photo -data {
  262. R0lGODdhHwAgAPQAAP///wAAAMzMzC9PT76+vvnTogCR/1WRVaoAVf//qvT09OKdcWlcx19f
  263. X9/f339/f8vN/J2d/aq2qoKCggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  264. ACwAAAAAHwAgAAAF/iAgjqRDnmiKmqOkqsTaToDjvudTttLjOITJbTQhGI+iQE0xMvZqQIDw
  265. NAEiAcqRVdKAGh0NyVCkuyqZBEmwofgRrFIxSaI0JmuA9KTrthIicWMTAQ8xWHgSe15AVgcJ
  266. eVMjDwECOkome22Mb0cHCzEPOiQPgwGXCjomakedA0VgY1IPDZcuP3l5YkcRDwMHqDQoEzq2
  267. Pz8IQkK7Bw8HDg+xO26PCAgRDcpGswEK2Dh9ItUMDdirPYUKwTKMjwDV1gHlR2oCkSmcI9UE
  268. BabYrGnQoolgBCGckX7yWJWDYaUMAYSRFECAwMXeiU1BHpKTB4CBR4+oBOb5By1UNgUfXj0C
  269. 8HaP079sBCCkZIAKWst/OGPOhNBNHQmXOeftJBASRVCcEiIojQDBwIOeRo+SpGXKFFGbP6Xi
  270. nLWxEMsmWpEOC9XDYtigYtKSwsH2xdq2cEfRmFS1rt27eE09CAEAOw==
  271. }]
  272. }
  273.  
  274. #
  275. # Provide a lowercased access method for the Scrolledhtml class.
  276. #
  277. proc ::iwidgets::scrolledhtml {pathName args} {
  278.     uplevel ::iwidgets::Scrolledhtml $pathName $args
  279. }
  280.  
  281. # ------------------------------------------------------------------
  282. #                        CONSTRUCTOR
  283. # ------------------------------------------------------------------
  284. body iwidgets::Scrolledhtml::constructor {args} {
  285.   # define the fonts we're going to use
  286.   set _fontnames ""
  287.   _definefont helvetica adobe helvetica "medium bold" "r o" iso8859
  288.   _definefont courier adobe courier "medium bold" "r o" iso8859
  289.   _definefont times adobe times "medium bold" "r i" iso8859
  290.   _definefont symbol adobe symbol "medium medium" "r r" adobe
  291.  
  292.   $itk_component(text) configure -state disabled
  293.  
  294.   eval itk_initialize $args
  295.   set _initialized 1
  296. }
  297.  
  298. # ------------------------------------------------------------------
  299. #                             OPTIONS
  300. # ------------------------------------------------------------------
  301.  
  302. # ------------------------------------------------------------------
  303. # OPTION: -fontsize
  304. #
  305. # Set the general size of the font.
  306. # ------------------------------------------------------------------
  307. configbody iwidgets::Scrolledhtml::fontsize {
  308.     switch $itk_option(-fontsize) {
  309.         small { }
  310.         medium { }
  311.         large { }
  312.         huge { }
  313.         default {
  314.             error "bad fontsize option\
  315.                    \"$itk_option(-fontsize)\": should\
  316.                    be small, medium, large, or huge"
  317.         }
  318.     }
  319.     _reconfig_tags
  320. }
  321.  
  322. # ------------------------------------------------------------------
  323. # OPTION: -fixedfont
  324. #
  325. # Set the fixed font name
  326. # ------------------------------------------------------------------
  327. configbody iwidgets::Scrolledhtml::fixedfont {
  328.    if {[lsearch -exact $_fontnames $itk_option(-fixedfont)] == -1} {
  329.      error "Invalid font name \"$itk_option(-fixedfont)\". Must be one of \
  330.          $_fontnames"
  331.   }
  332. }
  333.  
  334. # ------------------------------------------------------------------
  335. # OPTION: -fontname
  336. #
  337. # Set the default font name
  338. # ------------------------------------------------------------------
  339. configbody iwidgets::Scrolledhtml::fontname {
  340.    if {[lsearch -exact $_fontnames $itk_option(-fontname)] == -1} {
  341.      error "Invalid font name \"$itk_option(-fontname)\". Must be one of \
  342.          $_fontnames"
  343.   }
  344. }
  345.  
  346. # ------------------------------------------------------------------
  347. # OPTION: -textbackground
  348. #
  349. # Set the default text background
  350. # ------------------------------------------------------------------
  351. configbody iwidgets::Scrolledhtml::textbackground {
  352.   set _defaulttextbackground $itk_option(-textbackground)
  353. }
  354.  
  355. # ------------------------------------------------------------------
  356. #                            METHODS
  357. # ------------------------------------------------------------------
  358.  
  359. # ------------------------------------------------------------------
  360. # METHOD: clear
  361. #
  362. # Clears the text out
  363. # ------------------------------------------------------------------
  364. body iwidgets::Scrolledhtml::clear {} {
  365.     $itk_component(text) config -state normal
  366.     $itk_component(text) delete 1.0 end
  367.     _setup
  368.     $itk_component(text) config -state disabled
  369. }
  370.  
  371. # ------------------------------------------------------------------
  372. # METHOD import ?-link? filename?#anchorname?
  373. #
  374. # read html text from a file (import filename) if the keyword link is present, 
  375. # pathname is relative to last page, otherwise it is relative to current 
  376. # directory. This allows the user to use a linkcommand of 
  377. # "<widgetname> import -link"
  378. #
  379. # if '#anchorname' is appended to the filename, the page is displayed starting
  380. # at the anchor named 'anchorname' If an anchor is specified without a filename,
  381. # the current page is assumed.
  382. # ------------------------------------------------------------------
  383. body iwidgets::Scrolledhtml::import {args} {
  384.   set len [llength $args]
  385.   if {$len != 1 && $len != 2} {
  386.       error "wrong # args: should be \
  387.               \"$itk_component(hull) import ?-link? filename\""
  388.   }
  389.   set linkname [lindex $args [expr $len - 1]]
  390.  
  391.   #
  392.   # Seperate filename#anchorname
  393.   #
  394.   if ![regexp {(.*)#(.*)} $linkname dummy filename anchorname] {
  395.     set filename $linkname
  396.   }
  397.   if {$filename!=""} {
  398.     #
  399.     # Check for -link option
  400.     #
  401.     switch -- $len {
  402.       1 {
  403.         #
  404.         # open file & set cwd to that file's directory
  405.         #
  406.         set f [open $filename r]
  407.         set _cwd [file dirname $filename]
  408.       }
  409.       2 {
  410.         switch -- [lindex $args 0] {
  411.           -link {
  412.               #
  413.               # got -link, so set path relative to current locale, if path
  414.               # is a relative pathname
  415.               #
  416.               if {[string compare "." [file dirname $filename]] == 0} {
  417.                 set f [open [file join $_cwd $filename] r]
  418.               } else {
  419.                 if {[string index [file dirname $filename] 0] != "/" &&\
  420.                     [string index [file dirname $filename] 0] != "~"} {
  421.                   set f [open [file join $_cwd $filename] r]
  422.                   set _cwd [file join _cwd [file dirname $filename]]
  423.                 } else {
  424.                   set f [open $filename r]
  425.                   set _cwd [file dirname $filename]
  426.                 }
  427.               }
  428.           }
  429.           default {
  430.             # got something other than -link
  431.             error "invalid format: should be \
  432.                   \"$itk_component(hull) import ?-link? filename\""
  433.           }
  434.         }
  435.       }
  436.     }
  437.     set txt [read $f]
  438.     close $f
  439.     render $txt $_cwd
  440.   }
  441.  
  442.   #
  443.   # if an anchor was requested, move that anchor into view
  444.   #
  445.   if [ info exists anchorname] {
  446.     if {$anchorname!=""} {
  447.       if [info exists _anchor($anchorname)] {
  448.         $itk_component(text) see $_anchor($anchorname)
  449.       }
  450.     } else {
  451.       $itk_component(text) see 0.0
  452.     }
  453.   }
  454. }
  455.  
  456. # ------------------------------------------------------------------
  457. # METHOD: render text ?wd?
  458. #
  459. # Clear the text, then render html formatted text. Optional wd argument 
  460. # sets the base directory for any links or images. 
  461. # ------------------------------------------------------------------
  462. body iwidgets::Scrolledhtml::render {html {wd .}} {
  463.     #
  464.     # blank text and reset all state variables
  465.     #
  466.     clear
  467.     set _cwd $wd
  468.     _set_tag
  469.  
  470.     #
  471.     # Convert the text from something like this:
  472.     #   Put <strong>bold</strong> text in {}'s.
  473.     #
  474.     # to something like this:
  475.     #   _append_text {Put }
  476.     #   catch {_entity_[string tolower {strong}]}
  477.     #   _append_text {bold}
  478.     #   catch {_entity_[string tolower {/strong}]}
  479.     #   _append_text { text in &bl;&br;'s.}
  480.     #
  481.     # But first, convert all of the <p> markers to
  482.     # "&pp;" so we can count them and substitute
  483.     # them back later, like this:
  484.     #
  485.     #   _entity_p
  486.     #   _feedback next
  487.     #
  488.     regsub -all \{ $html {\&bl;} html
  489.     regsub -all \} $html {\&br;} html
  490.     regsub -all {\\} $html {\&bs;} html
  491.     set html "_append_text {$html}"
  492.  
  493.     _feedback [regsub -nocase -all "<p>" $html {\&pp;} html]
  494.     regsub -all "&pp;" $html "\}\n_entity_p\n_feedback next\n_append_text \{" html
  495.  
  496.     regsub -all {<([^> ]*) *([^>]*)>} $html \
  497.         "\}\ncatch \{_entity_\[string tolower \{\\1\}\] \\2\}\n_append_text \{" html
  498.  
  499.     $itk_component(text) config -state normal
  500.     eval $html
  501.     $itk_component(text) config -state disabled
  502. }
  503.  
  504. # ------------------------------------------------------------------
  505. # PRIVATE METHOD: _setup
  506. #
  507. # Reset all state variables to prepare for a new page.
  508. # ------------------------------------------------------------------
  509. body iwidgets::Scrolledhtml::_setup {} {
  510.     set _font $itk_option(-fontname)
  511.     set _left 0
  512.     set _left2 0
  513.     set _right 0
  514.     set _justify L
  515.     set _textweight 0
  516.     set _textslant 0
  517.     set _underline 0
  518.     set _verbatim 0
  519.     set _pre 0
  520.     set _title {}
  521.     set _intitle 0
  522.     set _anchorcount 0
  523.     set _stack(font) {}
  524.     set _stack(color) {}
  525.     set _stack(justify) {}
  526.     set _stack(listyle) {}
  527.     set _stack(lipic) {}
  528.     set _stack(href) {}
  529.     set _stack(pointsndx) {}
  530.     set _stack(left) {}
  531.     set _stack(left2) {}
  532.     set _stack(offset) {}
  533.     set _pointsndx 2
  534.     set _bgcolor $_defaulttextbackground
  535.     set _color $itk_option(-foreground)
  536.     set _link $itk_option(-link)
  537.     config -textbackground $_bgcolor
  538.     foreach x [array names _anchor] { unset _anchor($x) }
  539.     $itk_component(text) tag config hr -relief sunken -borderwidth 2 \
  540.             -font -*-*-*-*-*-*-$_rulerheight-*-*-*-*-*-*-*
  541. }
  542.  
  543. # ------------------------------------------------------------------
  544. # PRIVATE METHOD: _definefont name foundry family weight slant registry
  545. #
  546. # define font information used to generate font value from font name
  547. # ------------------------------------------------------------------
  548. body iwidgets::Scrolledhtml::_definefont \
  549.             {name foundry family weight slant registry} {
  550.     if {[lsearch -exact $_fontnames $name] == -1 } {
  551.       lappend _fontnames $name
  552.     }
  553.     set _fontinfo($name) \
  554.     [list $foundry $family $weight $slant $registry]
  555. }
  556.  
  557. # ------------------------------------------------------------------
  558. # PRIVATE METHOD: _append_text text
  559. #
  560. # append text in the format described by the state variables
  561. # ------------------------------------------------------------------
  562. body iwidgets::Scrolledhtml::_append_text {text} {
  563.     if {$text == ""} {
  564.         return
  565.     }
  566.     regsub -nocase -all "&?" $text {\&} text
  567.     regsub -nocase -all "<?" $text "<" text
  568.     regsub -nocase -all ">?" $text ">" text
  569.     regsub -nocase -all ""?" $text "\"" text
  570.     regsub -nocase -all "&bl;?" $text "\{" text
  571.     regsub -nocase -all "&br;?" $text "\}" text
  572.     regsub -nocase -all "&bs;?" $text {\\} text
  573.     if !$_verbatim {
  574.     if !$_pre {
  575.             set text [string trim $text "\n\r"]
  576.         regsub -all "\[ \n\r\t\]+" $text " " text
  577.     }
  578.     if ![string length $text] return
  579.     }
  580.     if {!$_pre && !$_intitle} {
  581.     set p [$itk_component(text) get "end - 2c"]
  582.     set n [string index $text 0]
  583.         if {$n == " " && $p == " "} {
  584.           set text [string range $text 1 end]
  585.         }
  586.     $itk_component(text) insert end $text $_tag
  587.     return
  588.     }
  589.     if {$_pre && !$_intitle} {
  590.     $itk_component(text) insert end $text $_tag
  591.     return
  592.     }
  593.     append _title $text
  594. }
  595.  
  596. # ------------------------------------------------------------------
  597. # PRIVATE METHOD: _set_tag
  598. #
  599. # generate a tag
  600. # ------------------------------------------------------------------
  601. # a tag is constructed as: font?B?I?U?Points-LeftLeft2RightColorJustify
  602. body iwidgets::Scrolledhtml::_set_tag {} {
  603.     set i -1
  604.     foreach var {foundry family weight slant registry} {
  605.     set $var [lindex $_fontinfo($_font) \
  606.                [incr i]]
  607.     }
  608.     set x_font "-$foundry-$family-"
  609.     set _tag $_font
  610.     set args {}
  611.     if {$_textweight > 0} {
  612.     append _tag "B"
  613.     append x_font [lindex $weight 1]-
  614.     } else {
  615.     append x_font [lindex $weight 0]-
  616.     }
  617.     if {$_textslant > 0} {
  618.     append _tag "I"
  619.     append x_font [lindex $slant 1]-
  620.     } else {
  621.     append x_font [lindex $slant 0]-
  622.     }
  623.     if {$_underline > 0} {
  624.     append _tag "U"
  625.     append args " -underline 1"
  626.     }
  627.     switch $_justify {
  628.     L { append args " -justify left" }
  629.     R { append args " -justify right" }
  630.     C { append args " -justify center" }
  631.     }
  632.     append args " -offset $_offset"
  633.         
  634.     set pts [lindex [set [format "_%spoints" $itk_option(-fontsize)]] \
  635.                   $_pointsndx]
  636.     append _tag $_pointsndx - $_left \
  637.     $_left2 $_right \
  638.     $_color $_justify
  639.     append x_font "normal-*-*-$pts-*-*-*-*-$registry-*"
  640.     if $_anchorcount {
  641.     set href [_peek href]
  642.     set href_tag href[incr _counter]
  643.     set tags [list $_tag $href_tag]
  644.     if { $itk_option(-linkcommand)!= {} } {
  645.         $itk_component(text) tag bind $href_tag <1> \
  646.         [list uplevel #0 $itk_option(-linkcommand) $href]
  647.     }
  648.     $itk_component(text) tag bind $href_tag <Enter> \
  649.         [list $itk_component(text) tag configure $href_tag \
  650.                   -foreground $itk_option(-linkhighlight)]
  651.     $itk_component(text) tag bind $href_tag <Leave> \
  652.         [list $itk_component(text) tag configure $href_tag \
  653.          -foreground $_color]
  654.     } else {
  655.     set tags $_tag
  656.     }
  657.     if {![info exists _tagl($_tag)]} {
  658.     set _tagfont($_tag) 1
  659.     eval $itk_component(text) tag configure $_tag \
  660.         -foreground $_color \
  661.         -lmargin1 ${_left}m \
  662.         -lmargin2 ${_left2}m $args
  663.     if [catch {eval $itk_component(text) tag configure $_tag \
  664.         -font $x_font} err] {
  665.           _definefont $_font * $family $weight $slant *
  666.           regsub \$foundry $x_font * x_font
  667.           regsub \$registry $x_font * x_font
  668.       catch {eval $itk_component(text) tag configure $_tag -font $x_font}
  669.         }
  670.     }
  671.     if [info exists href_tag] {
  672.     $itk_component(text) tag raise $href_tag $_tag
  673.     }
  674.     set _tag $tags
  675. }
  676.  
  677. # ------------------------------------------------------------------
  678. # PRIVATE METHOD: _reconfig_tags
  679. #
  680. # reconfigure tags following a configuration change
  681. # ------------------------------------------------------------------
  682. body iwidgets::Scrolledhtml::_reconfig_tags {} {
  683.   if $_initialized {
  684.     foreach tag [$itk_component(text) tag names] {
  685.     foreach efont $_fontnames {
  686.         if [regexp "${efont}(B?)(I?)(U?)(\[1-9\]\[0-9\]*)-" $tag t b i u points] {
  687.         set j -1
  688.         set _font $efont
  689.         foreach var {foundry family weight slant registry} {
  690.             set $var [lindex $_fontinfo($_font) [incr j]]
  691.         }
  692.         set x_font "-$foundry-$family-"
  693.         if {$b == "B"} {
  694.             append x_font [lindex $weight 1]-
  695.         } else {
  696.             append x_font [lindex $weight 0]-
  697.         }
  698.         if {$i == "I"} {
  699.             append x_font [lindex $slant 1]-
  700.         } else {
  701.             append x_font [lindex $slant 0]-
  702.         }
  703.         set pts [lindex [set [format \
  704.                      "_%spoints" $itk_option(-fontsize)]] $points]
  705.         append x_font "normal-*-*-$pts-*-*-*-*-$registry-*"
  706.         $itk_component(text) tag config $tag -font $x_font
  707.         break
  708.         }
  709.     }
  710.     }
  711.   }
  712. }
  713.  
  714. # ------------------------------------------------------------------
  715. # PRIVATE METHOD: _push instack value
  716. #
  717. # push value onto stack(instack)
  718. # ------------------------------------------------------------------
  719. body iwidgets::Scrolledhtml::_push {instack value} {
  720.     lappend _stack($instack) $value
  721. }
  722.  
  723. # ------------------------------------------------------------------
  724. # PRIVATE METHOD: _pop instack
  725. #
  726. # pop value from stack(instack)
  727. # ------------------------------------------------------------------
  728. body iwidgets::Scrolledhtml::_pop {instack} {
  729.     set n [expr [llength $_stack($instack)]-1]
  730.     if {$n < 0} {
  731.     return ""
  732.     }
  733.     set val [lindex $_stack($instack) $n]
  734.     set _stack($instack) [lreplace $_stack($instack) $n $n]
  735.     return $val
  736. }
  737.  
  738. # ------------------------------------------------------------------
  739. # PRIVATE METHOD: _peek instack
  740. #
  741. # peek at top value on stack(instack)
  742. # ------------------------------------------------------------------
  743. body iwidgets::Scrolledhtml::_peek {instack} {
  744.     return [lindex $_stack($instack) end]
  745. }
  746.  
  747. # ------------------------------------------------------------------
  748. # PRIVATE METHOD: _parse_fields array_var string
  749. #
  750. # parse fields from a href or image tag. At the moment, doesn't support
  751. # spaces in field values. (e.g. alt="not avaliable")
  752. # ------------------------------------------------------------------
  753. body iwidgets::Scrolledhtml::_parse_fields {array_var string} {
  754.   upvar $array_var array
  755.   if {$string != "{}" } {
  756.     regsub -all "( *)=( *)" $string = string
  757.     regsub -all {\\\"} $string \" string
  758.     while {$string != ""} {
  759.       if ![regexp "(\[^ \n\r=\]+)=\"(\[^\"\n\r\t\]*)(.*)" $string \
  760.                       dummy field value newstring] {
  761.         if ![regexp "(\[^ \n\r=\]+)=(\[^\n\r\t \]*)(.*)" $string \
  762.                       dummy field value newstring] {
  763.           if ![regexp "(\[^ \n\r\]+)(.*)" $string dummy field newstring] {
  764.             error "malformed command field; field = \"$string\""
  765.             continue
  766.           }
  767.           set value ""
  768.         }
  769.       }
  770.       set array([string tolower $field]) $value
  771.       set string "$newstring"
  772.     }
  773.   }
  774. }
  775.  
  776. # ------------------------------------------------------------------
  777. # PRIVATE METHOD: _href_click
  778. #
  779. # process a click on an href
  780. # ------------------------------------------------------------------
  781. body iwidgets::Scrolledhtml::_href_click {cmd href} {
  782.   uplevel #0 $cmd $href
  783. }
  784.  
  785. # ------------------------------------------------------------------
  786. # PRIVATE METHOD: _feedback ?val?
  787. #
  788. # Called from time to time while the text is being rendered to
  789. # handle feedback via the "-feedback" option.  If "val" is "next",
  790. # then the counter is incremented and the feedback command is
  791. # executed.  Otherwise, "val" is taken as the maximum counter
  792. # value, and the counter is reset.
  793. # ------------------------------------------------------------------
  794. body iwidgets::Scrolledhtml::_feedback {{val "next"}} {
  795.     if {$val == "next"} {
  796.         incr _fbcount
  797.         if {$itk_option(-feedback) != ""} {
  798.             uplevel #0 $itk_option(-feedback) $_fbcount $_fbmax
  799.         }
  800.     } elseif {[catch {expr 1*$val}] != 0} {
  801.         error "bad value \"$val\": should be a number"
  802.     } else {
  803.         set _fbmax $val
  804.         set _fbcount 0
  805.     }
  806. }
  807.  
  808. # ------------------------------------------------------------------
  809. # PRIVATE METHOD: _header level
  810. #
  811. # generic entity to set state for <hn> tag
  812. # Accepts argument of the form ?align=[left,right,center]? ?src=<image pname>?
  813. # ------------------------------------------------------------------
  814. body iwidgets::Scrolledhtml::_header {level args} {
  815.     eval _parse_fields ar $args
  816.     _push justify $_justify
  817.     if [info exists ar(align)] {
  818.       _entity_p align=$ar(align)
  819.     } else {
  820.       _entity_p 
  821.     }
  822.     if [info exists ar(src)] {
  823.         _entity_img src=$ar(src)
  824.     }
  825.     _push pointsndx $_pointsndx
  826.     set _pointsndx [expr 7-$level]
  827.     incr _textweight
  828.     _set_tag
  829. }
  830.  
  831. # ------------------------------------------------------------------
  832. # PRIVATE METHOD: _/header level
  833. #
  834. # generic entity to set state for </hn> tag
  835. # ------------------------------------------------------------------
  836. body iwidgets::Scrolledhtml::_/header {level} {
  837.     set _justify [_pop justify]
  838.     set _pointsndx [_pop pointsndx]
  839.     incr _textweight -1
  840.     _set_tag
  841.     _entity_p
  842. }
  843.  
  844. # ------------------------------------------------------------------
  845. # PRIVATE METHOD: _entity_a
  846. #
  847. # add an anchor. Accepts arguments of the form ?href=filename#anchorpoint?
  848. # ?name=anchorname?
  849. # ------------------------------------------------------------------
  850. body iwidgets::Scrolledhtml::_entity_a {args} {
  851.     _parse_fields ar $args
  852.     _push color $_color
  853.     if [info exists ar(href)] {
  854.       _push href $ar(href)
  855.       incr _anchorcount
  856.       set _color $_link
  857.       _entity_u
  858.     } else {
  859.       _push href {}
  860.     }
  861.     if [info exists ar(name)] {
  862.       set _anchor($ar(name)) [$itk_component(text) index end]
  863.     }
  864.     if [info exists ar(id)] {
  865.       set _anchor($ar(id)) [$itk_component(text) index end]
  866.     }
  867. }
  868.  
  869. # ------------------------------------------------------------------
  870. # PRIVATE METHOD: _entity_/a
  871. #
  872. # End anchor
  873. # ------------------------------------------------------------------
  874. body iwidgets::Scrolledhtml::_entity_/a {} {
  875.   set href [_pop href]
  876.   if {$href != {}} {
  877.     incr _anchorcount -1
  878.     set _color [_pop color]
  879.     _entity_/u
  880.   }
  881. }
  882.  
  883. # ------------------------------------------------------------------
  884. # PRIVATE METHOD: _entity_address
  885. #
  886. # display an address
  887. # ------------------------------------------------------------------
  888. body iwidgets::Scrolledhtml::_entity_address {} {
  889.     _entity_br
  890.     _entity_i
  891. }
  892.  
  893. # ------------------------------------------------------------------
  894. # PRIVATE METHOD: _entity_/address
  895. #
  896. # change state back from address display
  897. # ------------------------------------------------------------------
  898. body iwidgets::Scrolledhtml::_entity_/address {} {
  899.   _entity_/i
  900.   _entity_br
  901. }
  902.  
  903. # ------------------------------------------------------------------
  904. # PRIVATE METHOD: _entity_b
  905. #
  906. # Change current font to bold
  907. # ------------------------------------------------------------------
  908. body iwidgets::Scrolledhtml::_entity_b {} { 
  909.     incr _textweight
  910.     _set_tag 
  911. }
  912.  
  913. # ------------------------------------------------------------------
  914. # PRIVATE METHOD: _entity_/b
  915. #
  916. # change current font back from bold
  917. # ------------------------------------------------------------------
  918. body iwidgets::Scrolledhtml::_entity_/b {} {
  919.     incr _textweight -1
  920.     _set_tag
  921. }
  922.  
  923. # ------------------------------------------------------------------
  924. # PRIVATE METHOD: _entity_big
  925. #
  926. # Change current font to a bigger size
  927. # ------------------------------------------------------------------
  928. body iwidgets::Scrolledhtml::_entity_big {} { 
  929.     _push pointsndx $_pointsndx
  930.     if {[incr _pointsndx 2] > 6} {
  931.        set _pointsndx 6
  932.     }
  933.     _set_tag 
  934. }
  935.  
  936. # ------------------------------------------------------------------
  937. # PRIVATE METHOD: _entity_/big
  938. #
  939. # change current font back from bigger size
  940. # ------------------------------------------------------------------
  941. body iwidgets::Scrolledhtml::_entity_/big {} {
  942.     set _pointsndx [_pop pointsndx]
  943.     _set_tag
  944. }
  945.  
  946. # ------------------------------------------------------------------
  947. # PRIVATE METHOD: _entity_base
  948. #
  949. # set the cwd of the document
  950. # ------------------------------------------------------------------
  951. body iwidgets::Scrolledhtml::_entity_base {{args {}}} { 
  952.     _parse_fields ar $args
  953.     if [info exists ar(href)] {
  954.       set cwd [file dirname $ar(href)]
  955.     }
  956. }
  957.  
  958. # ------------------------------------------------------------------
  959. # PRIVATE METHOD: _entity_blockquote
  960. #
  961. # display a block quote
  962. # ------------------------------------------------------------------
  963. body iwidgets::Scrolledhtml::_entity_blockquote {} { 
  964.     _entity_p
  965.     _push left $_left
  966.     incr _left $_indentincr
  967.     _push left2 $_left2
  968.     set _left2 $_left
  969.     _set_tag 
  970. }
  971.  
  972. # ------------------------------------------------------------------
  973. # PRIVATE METHOD: _entity_/blockquote
  974. #
  975. # change back from blockquote
  976. # ------------------------------------------------------------------
  977. body iwidgets::Scrolledhtml::_entity_/blockquote {} {
  978.     _entity_p
  979.     set _left [_pop left]
  980.     set _left2 [_pop left2]
  981.     _set_tag
  982. }
  983.  
  984. # ------------------------------------------------------------------
  985. # PRIVATE METHOD: _entity_body
  986. #
  987. # begin body text. Takes argument of the form ?bgcolor=<color>? ?text=<color>?
  988. # ?link=<color>?
  989. # ------------------------------------------------------------------
  990. body iwidgets::Scrolledhtml::_entity_body {{args {}}} {
  991.     _parse_fields ar $args
  992.     if [info exists ar(bgcolor)] {
  993.        set _bgcolor $ar(bgcolor)
  994.        set temp $itk_option(-textbackground)
  995.        config -textbackground $_bgcolor
  996.        set _defaulttextbackground $temp
  997.     }
  998.     if [info exists ar(text)] {
  999.        set _color $ar(text)
  1000.     }
  1001.     if [info exists ar(link)] {
  1002.        set _link $ar(link)
  1003.     }
  1004. }
  1005.  
  1006. # ------------------------------------------------------------------
  1007. # PRIVATE METHOD: _entity_/body
  1008. #
  1009. # end body text
  1010. # ------------------------------------------------------------------
  1011. body iwidgets::Scrolledhtml::_entity_/body {} {
  1012. }
  1013.  
  1014. # ------------------------------------------------------------------
  1015. # PRIVATE METHOD: _entity_br
  1016. #
  1017. # line break
  1018. # ------------------------------------------------------------------
  1019. body iwidgets::Scrolledhtml::_entity_br {{args {}}} {
  1020.   if {[$itk_component(text) get end-2c] != "\n"} {
  1021.     $itk_component(text) insert end "\n"
  1022.   }
  1023. }
  1024.  
  1025. # ------------------------------------------------------------------
  1026. # PRIVATE METHOD: _entity_center
  1027. #
  1028. # change justification to center
  1029. # ------------------------------------------------------------------
  1030. body iwidgets::Scrolledhtml::_entity_center {} {
  1031.     _push justify $_justify
  1032.     set _justify C
  1033.     _set_tag
  1034. }
  1035.  
  1036. # ------------------------------------------------------------------
  1037. # PRIVATE METHOD: _entity_/center
  1038. #
  1039. # change state back from center
  1040. # ------------------------------------------------------------------
  1041. body iwidgets::Scrolledhtml::_entity_/center {} {
  1042.   set _justify [_pop justify]
  1043.   _set_tag
  1044. }
  1045.  
  1046. # ------------------------------------------------------------------
  1047. # PRIVATE METHOD: _entity_cite
  1048. #
  1049. # display citation
  1050. # ------------------------------------------------------------------
  1051. body iwidgets::Scrolledhtml::_entity_cite {} {
  1052.     _entity_i
  1053. }
  1054.  
  1055. # ------------------------------------------------------------------
  1056. # PRIVATE METHOD: _entity_/cite
  1057. #
  1058. # change state back from citation
  1059. # ------------------------------------------------------------------
  1060. body iwidgets::Scrolledhtml::_entity_/cite {} {
  1061.     _entity_/i
  1062. }
  1063.  
  1064. # ------------------------------------------------------------------
  1065. # PRIVATE METHOD: _entity_code
  1066. #
  1067. # display code listing
  1068. # ------------------------------------------------------------------
  1069. body iwidgets::Scrolledhtml::_entity_code {} {
  1070.     _entity_pre
  1071. }
  1072.  
  1073. # ------------------------------------------------------------------
  1074. # PRIVATE METHOD: _entity_/code
  1075. #
  1076. # end code listing
  1077. # ------------------------------------------------------------------
  1078. body iwidgets::Scrolledhtml::_entity_/code {} {
  1079.     _entity_/pre
  1080. }
  1081.  
  1082. # ------------------------------------------------------------------
  1083. # PRIVATE METHOD: _entity_dir
  1084. #
  1085. # display dir list
  1086. # ------------------------------------------------------------------
  1087. body iwidgets::Scrolledhtml::_entity_dir {{args {}}} {
  1088.     _entity_ul plain $args
  1089. }
  1090.  
  1091. # ------------------------------------------------------------------
  1092. # PRIVATE METHOD: _entity_/dir
  1093. #
  1094. # end dir list
  1095. # ------------------------------------------------------------------
  1096. body iwidgets::Scrolledhtml::_entity_/dir {} {
  1097.     _entity_/ul
  1098. }
  1099.  
  1100. # ------------------------------------------------------------------
  1101. # PRIVATE METHOD: _entity_dl
  1102. #
  1103. # begin definition list
  1104. # ------------------------------------------------------------------
  1105. body iwidgets::Scrolledhtml::_entity_dl {{args {}}} {
  1106.     if $_left {
  1107.       _entity_br
  1108.     } else {
  1109.       _entity_p
  1110.     }
  1111.     _push left $_left
  1112.     _push left2 $_left2
  1113.     if {$_left2 == $_left } {
  1114.       incr _left2 [expr $_indentincr+3]
  1115.     } else {
  1116.       incr _left2 $_indentincr
  1117.     }
  1118.     incr _left $_indentincr
  1119.     _push listyle $_listyle
  1120.     set _listyle none
  1121.     _set_tag
  1122. }
  1123.  
  1124. # ------------------------------------------------------------------
  1125. # PRIVATE METHOD: _entity_/dl
  1126. #
  1127. # end definition list
  1128. # ------------------------------------------------------------------
  1129. body iwidgets::Scrolledhtml::_entity_/dl {} {
  1130.     set _left [_pop left]
  1131.     set _left2 [_pop left2]
  1132.     set _listyle [_pop listyle]
  1133.     _set_tag
  1134.     _entity_p
  1135. }
  1136.  
  1137. # ------------------------------------------------------------------
  1138. # PRIVATE METHOD: _entity_dt
  1139. #
  1140. # definition term
  1141. # ------------------------------------------------------------------
  1142. body iwidgets::Scrolledhtml::_entity_dt {} {
  1143.   set _left [expr $_left2 - 3]
  1144.   _set_tag
  1145.   _entity_p
  1146. }
  1147.  
  1148. # ------------------------------------------------------------------
  1149. # PRIVATE METHOD: _entity_dd
  1150. #
  1151. # definition definition
  1152. # ------------------------------------------------------------------
  1153. body iwidgets::Scrolledhtml::_entity_dd {} {
  1154.   set _left $_left2
  1155.   _set_tag
  1156.    _entity_br
  1157. }
  1158.  
  1159. # ------------------------------------------------------------------
  1160. # PRIVATE METHOD: _entity_dfn
  1161. #
  1162. # display defining instance of a term
  1163. # ------------------------------------------------------------------
  1164. body iwidgets::Scrolledhtml::_entity_dfn {} {
  1165.     _entity_i
  1166.     _entity_b
  1167. }
  1168.  
  1169. # ------------------------------------------------------------------
  1170. # PRIVATE METHOD: _entity_/dfn
  1171. #
  1172. # change state back from defining instance of term
  1173. # ------------------------------------------------------------------
  1174. body iwidgets::Scrolledhtml::_entity_/dfn {} {
  1175.     _entity_/b
  1176.     _entity_/i
  1177. }
  1178.  
  1179. # ------------------------------------------------------------------
  1180. # PRIVATE METHOD: _entity_em
  1181. #
  1182. # display emphasized text
  1183. # ------------------------------------------------------------------
  1184. body iwidgets::Scrolledhtml::_entity_em {} {
  1185.     _entity_i
  1186. }
  1187.  
  1188. # ------------------------------------------------------------------
  1189. # PRIVATE METHOD: _entity_/em
  1190. #
  1191. # change state back from emphasized text
  1192. # ------------------------------------------------------------------
  1193. body iwidgets::Scrolledhtml::_entity_/em {} {
  1194.     _entity_/i
  1195. }
  1196.  
  1197. # ------------------------------------------------------------------
  1198. # PRIVATE METHOD: _entity_h1
  1199. #
  1200. # display header level 1. 
  1201. # Accepts argument of the form ?align=[left,right,center]? ?src=<image pname>?
  1202. # ------------------------------------------------------------------
  1203. body iwidgets::Scrolledhtml::_entity_h1 {{args {}}} {
  1204.     _header 1 $args
  1205. }
  1206.  
  1207. # ------------------------------------------------------------------
  1208. # PRIVATE METHOD: _entity_/h1
  1209. #
  1210. # change state back from header 1
  1211. # ------------------------------------------------------------------
  1212. body iwidgets::Scrolledhtml::_entity_/h1 {} {
  1213.     _/header 1
  1214. }
  1215.  
  1216. # ------------------------------------------------------------------
  1217. # PRIVATE METHOD: _entity_h2
  1218. #
  1219. # display header level 2
  1220. # Accepts argument of the form ?align=[left,right,center]? ?src=<image pname>?
  1221. # ------------------------------------------------------------------
  1222. body iwidgets::Scrolledhtml::_entity_h2 {{args {}}} {
  1223.     _header 2 $args
  1224. }
  1225.  
  1226. # ------------------------------------------------------------------
  1227. # PRIVATE METHOD: _entity_/h2
  1228. #
  1229. # change state back from header 2
  1230. # ------------------------------------------------------------------
  1231. body iwidgets::Scrolledhtml::_entity_/h2 {} {
  1232.     _/header 2 
  1233. }
  1234.  
  1235. # ------------------------------------------------------------------
  1236. # PRIVATE METHOD: _entity_h3
  1237. #
  1238. # display header level 3
  1239. # Accepts argument of the form ?align=[left,right,center]? ?src=<image pname>?
  1240. # ------------------------------------------------------------------
  1241. body iwidgets::Scrolledhtml::_entity_h3 {{args {}}} {
  1242.     _header 3 $args
  1243. }
  1244.  
  1245. # ------------------------------------------------------------------
  1246. # PRIVATE METHOD: _entity_/h3
  1247. #
  1248. # change state back from header 3
  1249. # ------------------------------------------------------------------
  1250. body iwidgets::Scrolledhtml::_entity_/h3 {} {
  1251.     _/header 3 
  1252. }
  1253.  
  1254. # ------------------------------------------------------------------
  1255. # PRIVATE METHOD: _entity_h4
  1256. #
  1257. # display header level 4
  1258. # Accepts argument of the form ?align=[left,right,center]? ?src=<image pname>?
  1259. # ------------------------------------------------------------------
  1260. body iwidgets::Scrolledhtml::_entity_h4 {{args {}}} { 
  1261.     _header 4 $args
  1262. }
  1263.  
  1264. # ------------------------------------------------------------------
  1265. # PRIVATE METHOD: _entity_/h4
  1266. #
  1267. # change state back from header 4
  1268. # ------------------------------------------------------------------
  1269. body iwidgets::Scrolledhtml::_entity_/h4 {} {
  1270.     _/header 4
  1271. }
  1272.  
  1273. # ------------------------------------------------------------------
  1274. # PRIVATE METHOD: _entity_h5
  1275. #
  1276. # display header level 5
  1277. # Accepts argument of the form ?align=[left,right,center]? ?src=<image pname>?
  1278. # ------------------------------------------------------------------
  1279. body iwidgets::Scrolledhtml::_entity_h5 {{args {}}} {
  1280.     _header 5 $args
  1281. }
  1282.  
  1283. # ------------------------------------------------------------------
  1284. # PRIVATE METHOD: _entity_/h5
  1285. #
  1286. # change state back from header 5
  1287. # ------------------------------------------------------------------
  1288. body iwidgets::Scrolledhtml::_entity_/h5 {} {
  1289.     _/header 5
  1290. }
  1291.  
  1292. # ------------------------------------------------------------------
  1293. # PRIVATE METHOD: _entity_h6
  1294. #
  1295. # display header level 6
  1296. # ------------------------------------------------------------------
  1297. body iwidgets::Scrolledhtml::_entity_h6 {{args {}}} {
  1298.     _header 6 $args
  1299. }
  1300.  
  1301. # ------------------------------------------------------------------
  1302. # PRIVATE METHOD: _entity_/h6
  1303. #
  1304. # change state back from header 6
  1305. # ------------------------------------------------------------------
  1306. body iwidgets::Scrolledhtml::_entity_/h6 {} {
  1307.     _/header 6
  1308. }
  1309.  
  1310. # ------------------------------------------------------------------
  1311. # PRIVATE METHOD: _entity_hr
  1312. #
  1313. # Add a horizontal rule
  1314. # ------------------------------------------------------------------
  1315. body iwidgets::Scrolledhtml::_entity_hr {{args {}}} {
  1316.     _parse_fields ar $args
  1317.     $itk_component(text) tag config hr[incr _counter] -relief sunken \
  1318.             -borderwidth 2 \
  1319.             -font -*-*-*-*-*-*-2-*-*-*-*-*-*-*
  1320.     if [info exists ar(size)] {
  1321.        $itk_component(text) tag config hr$_counter -font \
  1322.             -*-*-*-*-*-*-$ar(size)-*-*-*-*-*-*-*
  1323.     }
  1324.     if [info exists ar(width)] {
  1325.     }
  1326.     if [info exists ar(noshade)] {
  1327.        $itk_component(text) tag config hr$_counter -relief flat \
  1328.                -background black
  1329.     }
  1330. #    if [info exists ar(align)] {
  1331. #       $itk_component(text) tag config hr$_counter -justify $ar(align)
  1332. #    }
  1333.     _entity_p
  1334.     $itk_component(text) insert end "   \n" hr$_counter
  1335. }
  1336.  
  1337. # ------------------------------------------------------------------
  1338. # PRIVATE METHOD: _entity_i
  1339. #
  1340. # display italicized text
  1341. # ------------------------------------------------------------------
  1342. body iwidgets::Scrolledhtml::_entity_i {} {
  1343.     incr _textslant
  1344.     _set_tag
  1345. }
  1346.  
  1347. # ------------------------------------------------------------------
  1348. # PRIVATE METHOD: _entity_/i
  1349. #
  1350. # change state back from italicized text
  1351. # ------------------------------------------------------------------
  1352. body iwidgets::Scrolledhtml::_entity_/i {} {
  1353.     incr _textslant -1
  1354.     _set_tag
  1355. }
  1356.  
  1357. # ------------------------------------------------------------------
  1358. # PRIVATE METHOD: _entity_img
  1359. #
  1360. # display an image. takes argument of the form img=<filename>
  1361. # ------------------------------------------------------------------
  1362. body iwidgets::Scrolledhtml::_entity_img {args} {
  1363.   _parse_fields ar $args
  1364.   set alttext "<image>"
  1365.  
  1366.   #
  1367.   # If proper argument exists
  1368.   #
  1369.   if [info exists ar(src)] {
  1370.     #
  1371.     # if this is an anchor
  1372.     #
  1373.     if $_anchorcount {
  1374.       # create link colored border
  1375.       set imgframe $itk_component(text).img[incr _counter]
  1376.       frame $imgframe -borderwidth 2 -background $_link
  1377.       bind $imgframe <Enter> \
  1378.             [list $imgframe configure -background $itk_option(-linkhighlight)]
  1379.       bind $imgframe <Leave> \
  1380.             [list $imgframe configure -background $_link]
  1381.     } else {
  1382.       # create plain frame
  1383.       set imgframe $itk_component(text).img[incr _counter]
  1384.       frame $imgframe -borderwidth 0 -background $_color
  1385.     }
  1386.  
  1387.     #
  1388.     # try to load image
  1389.     #
  1390.     set file [file join $_cwd $ar(src)]
  1391.     if [catch {set img [image create photo -file $file]} err] {
  1392.       # got an error. Check for width & height suggestions.
  1393.  
  1394.       if {[info exists ar(width)] && [info exists ar(height)] } {
  1395.         # suggestions exist, so make frame appropriate size and add a border
  1396.         $imgframe configure -width $ar(width) -height $ar(height) -borderwidth 2
  1397.         pack propagate $imgframe false
  1398.       }
  1399.  
  1400.  
  1401.       #
  1402.       # If alt text is specified, display that
  1403.       #
  1404.       if [info exists ar(alt)] {
  1405.         set win $imgframe.text
  1406.         # add a border
  1407.         $imgframe configure -borderwidth 2
  1408.         label $win -text "$ar(alt)" -background $_bgcolor \
  1409.                -foreground $_color
  1410.         pack $win -expand true -fill both
  1411.       } else {
  1412.         #
  1413.         # Load 'unknown image'
  1414.         #
  1415.         if {$itk_option(-unknownimage) != {}} {
  1416.            set uki $itk_option(-unknownimage)
  1417.            if [catch { set img [image create photo -file $uki] } err] {
  1418.               error "Couldn't create image $uki:\n$err\nUnknown image not found"
  1419.            }
  1420.         } else {
  1421.            set img $_defUnknownImg
  1422.         }
  1423.  
  1424.         set win $imgframe.$img
  1425.         #
  1426.         # make label containing image
  1427.         #
  1428.         label $win -image $img -borderwidth 0 -background $_bgcolor
  1429.         pack $win -expand true -fill both
  1430.       }
  1431.     } else {   ;# no error loading image
  1432.       set win $imgframe.$img
  1433.  
  1434.       #
  1435.       # make label containing image
  1436.       #
  1437.       label $win -image $img -borderwidth 0
  1438.     }
  1439.     pack $win
  1440.  
  1441.     #
  1442.     # set alignment
  1443.     #
  1444.     set align bottom
  1445.     if [info exists ar(align)] {
  1446.       switch $ar(align) {
  1447.         middle {
  1448.           set align center
  1449.         }
  1450.         default {
  1451.           set align [string tolower $ar(align)]
  1452.         }
  1453.       }
  1454.     }
  1455.  
  1456.     #
  1457.     # create window in text to display image
  1458.     #
  1459.     $itk_component(text) window create end -window \
  1460.             $imgframe -align $align
  1461.  
  1462.     #
  1463.     # set tag for window
  1464.     #
  1465.     $itk_component(text) tag add $_tag $imgframe
  1466.     if $_anchorcount {
  1467.         set href [_peek href]
  1468.         set href_tag href[incr _counter]
  1469.         set tags [list $_tag $href_tag]
  1470.         if { $itk_option(-linkcommand)!= {} } {
  1471.           bind $win <1> [list uplevel #0 $itk_option(-linkcommand) $href]
  1472.         }
  1473.     }
  1474.   }
  1475. }
  1476.  
  1477. # ------------------------------------------------------------------
  1478. # PRIVATE METHOD: _entity_kbd
  1479. #
  1480. # Display keyboard input
  1481. # ------------------------------------------------------------------
  1482. body iwidgets::Scrolledhtml::_entity_kbd {} {
  1483.     incr _textweight
  1484.     _entity_tt 
  1485.     _set_tag
  1486. }
  1487.  
  1488. # ------------------------------------------------------------------
  1489. # PRIVATE METHOD: _entity_/kbd
  1490. #
  1491. # change state back from displaying keyboard input
  1492. # ------------------------------------------------------------------
  1493. body iwidgets::Scrolledhtml::_entity_/kbd {} {
  1494.     _entity_/tt
  1495.     incr _textweight -1
  1496.     _set_tag
  1497. }
  1498.  
  1499. # ------------------------------------------------------------------
  1500. # PRIVATE METHOD: _entity_li
  1501. #
  1502. # begin new list entry
  1503. # ------------------------------------------------------------------
  1504. body iwidgets::Scrolledhtml::_entity_li {} {
  1505.     _entity_br
  1506.     switch -exact $_listyle {
  1507.       bullet {
  1508.         set old_font $_font
  1509.         set _font symbol
  1510.         _set_tag
  1511.         $itk_component(text) insert end "\xb7" $_tag
  1512.         set _font $old_font
  1513.         _set_tag
  1514.       }
  1515.       none {
  1516.       }
  1517.       picture {
  1518.         _entity_img src="$_lipic"
  1519.       }
  1520.       default {
  1521.         incr _listyle
  1522.         _entity_b
  1523.         $itk_component(text) insert end "$_listyle) " $_tag
  1524.         _entity_/b
  1525.       }
  1526.     }
  1527. }
  1528.  
  1529. # ------------------------------------------------------------------
  1530. # PRIVATE METHOD: _entity_listing
  1531. #
  1532. # diplay code listing
  1533. # ------------------------------------------------------------------
  1534. body iwidgets::Scrolledhtml::_entity_listing {} {
  1535.     _entity_pre
  1536. }
  1537.  
  1538. # ------------------------------------------------------------------
  1539. # PRIVATE METHOD: _entity_/listing
  1540. #
  1541. # end code listing
  1542. # ------------------------------------------------------------------
  1543. body iwidgets::Scrolledhtml::_entity_/listing {} {
  1544.     _entity_/pre
  1545. }
  1546.  
  1547. # ------------------------------------------------------------------
  1548. # PRIVATE METHOD: _entity_menu
  1549. #
  1550. # diplay menu list
  1551. # ------------------------------------------------------------------
  1552. body iwidgets::Scrolledhtml::_entity_menu {{args {}}} {
  1553.     _entity_ul plain $args
  1554. }
  1555.  
  1556. # ------------------------------------------------------------------
  1557. # PRIVATE METHOD: _entity_/menu
  1558. #
  1559. # end menu list
  1560. # ------------------------------------------------------------------
  1561. body iwidgets::Scrolledhtml::_entity_/menu {} {
  1562.     _entity_/ul
  1563. }
  1564.  
  1565. # ------------------------------------------------------------------
  1566. # PRIVATE METHOD: _entity_ol
  1567. #
  1568. # begin ordered list
  1569. # ------------------------------------------------------------------
  1570. body iwidgets::Scrolledhtml::_entity_ol {{args {}}} {
  1571.     if $_left {
  1572.       _entity_br
  1573.     } else {
  1574.       _entity_p
  1575.     }
  1576.     _push left $_left
  1577.     _push left2 $_left2
  1578.     if {$_left2 == $_left } {
  1579.       incr _left2 [expr $_indentincr+3]
  1580.     } else {
  1581.       incr _left2 $_indentincr
  1582.     }
  1583.     incr _left $_indentincr
  1584.     _push listyle $_listyle
  1585.     set _listyle 0
  1586.     _set_tag
  1587. }
  1588.  
  1589. # ------------------------------------------------------------------
  1590. # PRIVATE METHOD: _entity_/ol
  1591. #
  1592. # end ordered list
  1593. # ------------------------------------------------------------------
  1594. body iwidgets::Scrolledhtml::_entity_/ol {} {
  1595.     set _left [_pop left]
  1596.     set _left2 [_pop left2]
  1597.     set _listyle [_pop listyle]
  1598.     _set_tag
  1599.     _entity_p
  1600. }
  1601.  
  1602. # ------------------------------------------------------------------
  1603. # PRIVATE METHOD: _entity_p
  1604. #
  1605. # paragraph break
  1606. # ------------------------------------------------------------------
  1607. body iwidgets::Scrolledhtml::_entity_p {{args {}}} {
  1608.   _parse_fields ar $args
  1609.   if [info exists ar(align)] {
  1610.       switch [string tolower $ar(align)] {
  1611.         center {
  1612.           set _justify C
  1613.         }
  1614.         left {
  1615.           set _justify L
  1616.         }
  1617.         right {
  1618.           set _justify R
  1619.         }
  1620.         default {}
  1621.       }
  1622.   }
  1623.   _set_tag
  1624.   if [info exists ar(id)] {
  1625.     set _anchor($ar(id)) [$itk_component(text) index end]
  1626.   }
  1627.   set x [$itk_component(text) get end-3c]
  1628.   set y [$itk_component(text) get end-2c]
  1629.   if {$x == "" && $y == ""} return
  1630.   if {$y == ""} {
  1631.     $itk_component(text) insert end "\n\n"
  1632.     return
  1633.   }
  1634.   if {$x == "\n" && $y == "\n"} return
  1635.   if {$y == "\n"} {
  1636.     $itk_component(text) insert end "\n"
  1637.   return
  1638.   }
  1639.   $itk_component(text) insert end "\n\n"
  1640. }
  1641.  
  1642. # ------------------------------------------------------------------
  1643. # PRIVATE METHOD: _entity_pre
  1644. #
  1645. # display preformatted text
  1646. # ------------------------------------------------------------------
  1647. body iwidgets::Scrolledhtml::_entity_pre {{args {}}} { 
  1648.     _entity_tt
  1649.     _entity_br
  1650.     incr _pre
  1651. }
  1652.  
  1653. # ------------------------------------------------------------------
  1654. # PRIVATE METHOD: _entity_/pre
  1655. #
  1656. # change state back from preformatted text
  1657. # ------------------------------------------------------------------
  1658. body iwidgets::Scrolledhtml::_entity_/pre {} {
  1659.     _entity_/tt
  1660.     set _pre 0
  1661.     _entity_p
  1662. }
  1663.  
  1664. # ------------------------------------------------------------------
  1665. # PRIVATE METHOD: _entity_samp
  1666. #
  1667. # display sample text.
  1668. # ------------------------------------------------------------------
  1669. body iwidgets::Scrolledhtml::_entity_samp {} {
  1670.     _entity_kbd
  1671. }
  1672.  
  1673. # ------------------------------------------------------------------
  1674. # PRIVATE METHOD: _entity_/samp
  1675. #
  1676. # switch back to non-sample text
  1677. # ------------------------------------------------------------------
  1678. body iwidgets::Scrolledhtml::_entity_/samp {} {
  1679.    _entity_/kbd
  1680. }
  1681.  
  1682. # ------------------------------------------------------------------
  1683. # PRIVATE METHOD: _entity_small
  1684. #
  1685. # Change current font to a smaller size
  1686. # ------------------------------------------------------------------
  1687. body iwidgets::Scrolledhtml::_entity_small {} { 
  1688.     _push pointsndx $_pointsndx
  1689.     if {[incr _pointsndx -2] < 0} {
  1690.        set _pointsndx 0
  1691.     }
  1692.     _set_tag 
  1693. }
  1694.  
  1695. # ------------------------------------------------------------------
  1696. # PRIVATE METHOD: _entity_/small
  1697. #
  1698. # change current font back from smaller size
  1699. # ------------------------------------------------------------------
  1700. body iwidgets::Scrolledhtml::_entity_/small {} {
  1701.     set _pointsndx [_pop pointsndx]
  1702.     _set_tag
  1703. }
  1704.  
  1705. # ------------------------------------------------------------------
  1706. # PRIVATE METHOD: _entity_sub
  1707. #
  1708. # display subscript
  1709. # ------------------------------------------------------------------
  1710. body iwidgets::Scrolledhtml::_entity_sub {} {
  1711.     _push offset $_offset
  1712.     incr _offset -2
  1713.     _entity_small
  1714. }
  1715.  
  1716. # ------------------------------------------------------------------
  1717. # PRIVATE METHOD: _entity_/sub
  1718. #
  1719. # switch back to non-subscript
  1720. # ------------------------------------------------------------------
  1721. body iwidgets::Scrolledhtml::_entity_/sub {} {
  1722.    set _offset [_pop offset]
  1723.    _entity_/small
  1724. }
  1725.  
  1726. # ------------------------------------------------------------------
  1727. # PRIVATE METHOD: _entity_sup
  1728. #
  1729. # display superscript
  1730. # ------------------------------------------------------------------
  1731. body iwidgets::Scrolledhtml::_entity_sup {} {
  1732.     _push offset $_offset
  1733.     incr _offset 4
  1734.     _entity_small
  1735. }
  1736.  
  1737. # ------------------------------------------------------------------
  1738. # PRIVATE METHOD: _entity_/sup
  1739. #
  1740. # switch back to non-superscript
  1741. # ------------------------------------------------------------------
  1742. body iwidgets::Scrolledhtml::_entity_/sup {} {
  1743.    set _offset [_pop offset]
  1744.    _entity_/small
  1745. }
  1746.  
  1747. # ------------------------------------------------------------------
  1748. # PRIVATE METHOD: _entity_strong
  1749. #
  1750. # display strong text. (i.e. make font bold)
  1751. # ------------------------------------------------------------------
  1752. body iwidgets::Scrolledhtml::_entity_strong {} {
  1753.     incr _textweight
  1754.     _set_tag
  1755. }
  1756.  
  1757. # ------------------------------------------------------------------
  1758. # PRIVATE METHOD: _entity_/strong
  1759. #
  1760. # switch back to non-strong text
  1761. # ------------------------------------------------------------------
  1762. body iwidgets::Scrolledhtml::_entity_/strong {} {
  1763.     incr _textweight -1
  1764.     _set_tag 
  1765. }
  1766.  
  1767. # ------------------------------------------------------------------
  1768. # PRIVATE METHOD: _entity_title
  1769. #
  1770. # begin title of document
  1771. # ------------------------------------------------------------------
  1772. body iwidgets::Scrolledhtml::_entity_title {} {
  1773.     set _intitle 1 
  1774. }
  1775.  
  1776. # ------------------------------------------------------------------
  1777. # PRIVATE METHOD: _entity_/title
  1778. #
  1779. # end title
  1780. # ------------------------------------------------------------------
  1781. body iwidgets::Scrolledhtml::_entity_/title {} {
  1782.     set _intitle 0
  1783. }
  1784.  
  1785. # ------------------------------------------------------------------
  1786. # PRIVATE METHOD: _entity_tt
  1787. #
  1788. # Show typewriter text, using the font given by -fixedfont
  1789. # ------------------------------------------------------------------
  1790. body iwidgets::Scrolledhtml::_entity_tt {} {
  1791.     _push font $_font
  1792.     set _font $itk_option(-fixedfont)
  1793.     set _verbatim 1
  1794.     _set_tag
  1795. }
  1796.  
  1797. # ------------------------------------------------------------------
  1798. # PRIVATE METHOD: _entity_/tt
  1799. #
  1800. # Change back to non-typewriter mode to display text
  1801. # ------------------------------------------------------------------
  1802. body iwidgets::Scrolledhtml::_entity_/tt {} {
  1803.     set _font [_pop font]
  1804.     set _verbatim 0
  1805.     _set_tag
  1806. }
  1807.  
  1808. # ------------------------------------------------------------------
  1809. # PRIVATE METHOD: _entity_u
  1810. #
  1811. # display underlined text
  1812. # ------------------------------------------------------------------
  1813. body iwidgets::Scrolledhtml::_entity_u {} { 
  1814.     incr _underline
  1815.     _set_tag
  1816. }
  1817.  
  1818. # ------------------------------------------------------------------
  1819. # PRIVATE METHOD: _entity_/u
  1820. #
  1821. # change back from underlined text
  1822. # ------------------------------------------------------------------
  1823. body iwidgets::Scrolledhtml::_entity_/u {} { 
  1824.     incr _underline -1
  1825.     _set_tag
  1826. }
  1827.  
  1828. # ------------------------------------------------------------------
  1829. # PRIVATE METHOD: _entity_ul
  1830. #
  1831. # begin unordered list
  1832. # ------------------------------------------------------------------
  1833. body iwidgets::Scrolledhtml::_entity_ul {{args {}}} {
  1834.     _parse_fields ar $args
  1835.     if $_left {
  1836.       _entity_br
  1837.     } else {
  1838.       _entity_p
  1839.     }
  1840.     if [info exists ar(id)] {
  1841.       set _anchor($ar(id)) [$itk_component(text) index end]
  1842.     }
  1843.     _push left $_left
  1844.     _push left2 $_left2
  1845.     if {$_left2 == $_left } {
  1846.       incr _left2 [expr $_indentincr+3]
  1847.     } else {
  1848.       incr _left2 $_indentincr
  1849.     }
  1850.     incr _left $_indentincr
  1851.     _push listyle $_listyle
  1852.     if [info exists ar(plain)] {
  1853.       set _listyle none
  1854.     } {
  1855.       set _listyle bullet
  1856.     }
  1857.     if [info exists ar(dingbat)] {
  1858.       set ar(src) $ar(dingbat)
  1859.     }
  1860.     _push lipic $_lipic
  1861.     if [info exists ar(src)] {
  1862.         set _listyle picture
  1863.         set _lipic $ar(src)
  1864.     }
  1865.     _set_tag
  1866. }
  1867.  
  1868. # ------------------------------------------------------------------
  1869. # PRIVATE METHOD: _entity_/ul
  1870. #
  1871. # end unordered list
  1872. # ------------------------------------------------------------------
  1873. body iwidgets::Scrolledhtml::_entity_/ul {} {
  1874.     set _left [_pop left]
  1875.     set _left2 [_pop left2]
  1876.     set _listyle [_pop listyle]
  1877.     set _lipic [_pop lipic]
  1878.     _set_tag
  1879.     _entity_p
  1880. }
  1881.  
  1882. # ------------------------------------------------------------------
  1883. # PRIVATE METHOD: _entity_var
  1884. #
  1885. # Display variable
  1886. # ------------------------------------------------------------------
  1887. body iwidgets::Scrolledhtml::_entity_var {} {
  1888.     _entity_i
  1889. }
  1890.  
  1891. # ------------------------------------------------------------------
  1892. # PRIVATE METHOD: _entity_/var
  1893. #
  1894. # change state back from variable display
  1895. # ------------------------------------------------------------------
  1896. body iwidgets::Scrolledhtml::_entity_/var {} {
  1897.     _entity_/i
  1898. }
  1899.