checker_toc.tcl

Go to the documentation of this file.
00001 /*  -*- tcl -*-*/
00002 /*  checker_toc.tcl*/
00003 /* */
00004 /*  Code used inside of a checker interpreter to ensure correct usage of*/
00005 /*  doctoc formatting commands.*/
00006 /* */
00007 /*  Copyright (c) 2003 Andreas Kupries <andreas_kupries@sourceforge.net>*/
00008 
00009 /*  L10N*/
00010 
00011 package require msgcat
00012 
00013 ret  ::msgcat::mcunknown (type locale , type code) {
00014     return "unknown error code \"$code\" (for locale $locale)"
00015 }
00016 
00017 if {0} {
00018     puts stderr "Locale [::msgcat::mcpreferences]"
00019     foreach path [dt_search] {
00020     puts stderr "Catalogs: [::msgcat::mc
00021     }
00022 } else {
00023     foreach path [dt_search] {
00024     ::msgcat::mc
00025     }
00026 }
00027 
00028 /*  State, and checker commands.*/
00029 /*  -------------------------------------------------------------*/
00030 /* */
00031 /*  Note that the code below assumes that a command XXX provided by the*/
00032 /*  formatter engine is accessible under the name 'fmt_XXX'.*/
00033 /* */
00034 /*  -------------------------------------------------------------*/
00035 
00036 global state
00037 
00038 /*  State machine ... State centered*/
00039 /*  --------------+-----------------------+----------------------*/
00040 /*  state       | allowed commands  | new state (if any)*/
00041 /*  --------------+-----------------------+----------------------*/
00042 /*  all except  | include vset      |*/
00043 /*  ==============+=======================+======================*/
00044 /*  toc_begin   | toc_begin     | -> contents*/
00045 /*  --------------+-----------------------+----------------------*/
00046 /*  contents    | item          | -> item_series*/
00047 /*      +-----------------------+-----------*/
00048 /*      | division_start    | -> end, PUSH division*/
00049 /*  --------------+-----------------------+----------------------*/
00050 /*  item_series | item          | -> item_series*/
00051 /*      +-----------------------+-----------*/
00052 /*      | toc_end       | -> done*/
00053 /*  --------------+-----------------------+----------------------*/
00054 /*  division    | item          | -> div_items*/
00055 /*      +-----------------------+-----------*/
00056 /*      | division_start    | -> div_series, PUSH division*/
00057 /*  --------------+-----------------------+----------------------*/
00058 /*  div_series  | division_start    | -> div_series, PUSH division*/
00059 /*  --------------+-----------------------+----------------------*/
00060 /*  div_items   | item          | -> div_items*/
00061 /*      +-----------------------+-----------*/
00062 /*      | division_end      | POP (-> div_series / -> end)*/
00063 /*  --------------+-----------------------+----------------------*/
00064 /*  end     | toc_end       | -> done*/
00065 /*      +-----------------------+-----------*/
00066 /*      | division_start    | PUSH division*/
00067 /*  --------------+-----------------------+----------------------*/
00068 
00069 /*  State machine, as above ... Command centered*/
00070 /*  --------------+-----------------------+----------------------*/
00071 /*  state       | allowed commands  | new state (if any)*/
00072 /*  --------------+-----------------------+----------------------*/
00073 /*  all except  | include vset      |*/
00074 /*  ==============+=======================+======================*/
00075 /*  toc_begin   | toc_begin     | -> contents*/
00076 /*  --------------+-----------------------+----------------------*/
00077 /*  contents    | item          | -> item_series*/
00078 /*  item_series |           | -> item_series*/
00079 /*  div_items   |           | -> div_items*/
00080 /*  division      |                       | -> div_items*/
00081 /*  --------------+-----------------------+----------------------*/
00082 /*  contents    | division_start    | -> end, PUSH division*/
00083 /*  div_series  |           | -> div_series, PUSH division*/
00084 /*  end     |           | PUSH division*/
00085 /*  division      |                       | PUSH division*/
00086 /*  --------------+-----------------------+----------------------*/
00087 /*  div_items   | division_end      | POP (-> div_series / -> end)*/
00088 /*  --------------+-----------------------+----------------------*/
00089 /*  item_series | toc_end       | -> done*/
00090 /*  end     |           | -> done*/
00091 /*  --------------+-----------------------+----------------------*/
00092 
00093 /*  -------------------------------------------------------------*/
00094 /*  Helpers*/
00095 ret  Error (type code , optional text ={)} {
00096     global state
00097 
00098     # Problematic command with all arguments (we strip the "ck_" prefix!)
00099     # -*- future -*- count lines of input, maintain history buffer, use
00100     # -*- future -*- that to provide some context here.
00101 
00102     set cmd  [lindex [info level 1] 0]
00103     set args [lrange [info level 1] 1 end]
00104     if {$args != {}} {append cmd " [join $args]"}
00105 
00106     /*  Use a message catalog to map the error code into a legible message.*/
00107      msg =  [::msgcat::mc $code]
00108 
00109     if {$text != {}} {
00110      msg =  [string map [list @ $text] $msg]
00111     }
00112 
00113     dt_error "TOC error ($code), \"$cmd\" : ${msg}."
00114     return
00115 }
00116 ret  Warn (type code , type text) {
00117     set msg [::msgcat::mc $code]
00118     dt_warning "TOC warning ($code): [join [split [format $msg $text] \n] "\nTOC warning ($code): "]"
00119     return
00120 }
00121 
00122 ret  Is    (type s) {global state ; return [string equal $state $s]}
00123 ret  IsNot (type s) {global state ; return [expr {![string equal $state $s]}]}
00124 ret  Go    (type s) {Log " >>\[$s\]" ; global state ; set state $s; return}
00125 ret  Push  (type s) {Log " //\[$s\]" ; global state stack ; lappend stack $state ; set state $s; return}
00126 ret  Pop   ()  {Log* " pop" ;  global state stack ; set state [lindex $stack end] ; set stack [lrange $stack 0 end-1] ; Log " \\\\\[$state\]" ; return}
00127 ret  State () {global state stack ; return "$stack || $state"}
00128 
00129 ret  Enter (type cmd) {Log* "\[[State]\] $cmd"}
00130 
00131 /* proc Log* {text} {puts -nonewline $text}*/
00132 /* proc Log  {text} {puts            $text}*/
00133 ret  Log* (type text) {}
00134 ret  Log  (type text) {}
00135 
00136 /*  -------------------------------------------------------------*/
00137 /*  Framing*/
00138 ret  ck_initialize () {
00139     global state   ; set state toc_begin
00140     global stack   ; set stack [list]
00141 }
00142 ret  ck_complete () {
00143     if {[Is done]} {
00144     return
00145     } else {
00146     Error end/open/toc
00147     }
00148     return
00149 }
00150 /*  -------------------------------------------------------------*/
00151 /*  Plain text*/
00152 ret  plain_text (type text) {
00153     # Ignore everything which is only whitespace ...
00154     # Beyond that plain text is not allowed.
00155 
00156     set redux [string map [list " " "" "\t" "" "\n" ""] $text]
00157     if {$redux == {}} {return [fmt_plain_text $text]}
00158     Error toc/plaintext
00159     return ""
00160 }
00161 
00162 /*  -------------------------------------------------------------*/
00163 /*  Variable handling ...*/
00164 
00165 ret  vset (type var , type args) {
00166     switch -exact -- [llength $args] {
00167     0 {
00168         # Retrieve contents of variable VAR
00169         upvar #0 __$var data
00170         return $data
00171     }
00172     1 {
00173         # Set contents of variable VAR
00174         global __$var
00175         set    __$var [lindex $args 0]
00176         return "" ; # Empty string ! Nothing for output.
00177     }
00178     default {
00179         return -code error "wrong#args: set var ?value?"
00180     }
00181     }
00182 }
00183 
00184 /*  -------------------------------------------------------------*/
00185 /*  Formatting commands*/
00186 ret  toc_begin (type label , type title) {
00187     Enter toc_begin
00188     if {[IsNot toc_begin]} {Error toc/begincmd}
00189     Go contents
00190     fmt_toc_begin $label $title
00191 }
00192 ret  toc_end () {
00193     Enter toc_end
00194     if {[IsNot end] && [IsNot item_series]} {Error toc/endcmd}
00195     Go done
00196     fmt_toc_end
00197 }
00198 ret  division_start (type title , optional symfile ={)} {
00199     Enter division_start
00200     if {
00201     [IsNot contents] && [IsNot div_series] && [IsNot end] && [IsNot division]
00202     } {Error toc/sectcmd}
00203     if {[Is contents] || [Is end]} {Go end} else {Go div_series}
00204     Push div_series
00205     fmt_division_start $title $symfile
00206 }
00207 ret  division_end () {
00208     Enter division_end
00209     if {[IsNot div_items] && [IsNot div_series]} {Error toc/sectecmd [State]}
00210     Pop
00211     fmt_division_end
00212 }
00213 ret  item (type file , type label , type desc) {
00214     Enter item
00215     if {
00216     [IsNot div_series] && [IsNot contents] && [IsNot item_series] && [IsNot div_items]
00217     } {
00218     Error toc/itemcmd
00219     }
00220     if {[Is div_items] || [Is div_series]} {Go div_items} else {Go item_series}
00221     fmt_item $file $label $desc
00222 }
00223 ret  comment (type text) {
00224     if {[Is done]} {Error toc/nodonecmd}
00225     return ; #fmt_comment $text
00226 }
00227 
00228 /*  -------------------------------------------------------------*/
00229 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1