namespace eval hl {

variable initialized 0
variable lexer

# Autogenerated with DRAKON Editor 1.28

proc add_token { result_name type text } {
    #item 127
    upvar 1 $result_name result
    #item 128
    set token [ list $type $text ]
    #item 129
    lappend result $token
}

proc contains { list item } {
    #item 367
    set pos \
    [lsearch $list $item]
    #item 368
    if {$pos == -1} {
        #item 371
        return 0
    } else {
        #item 372
        return 1
    }
}

proc flush { result_name state buffer_name } {
    #item 148
    upvar 1 $result_name result
    upvar 1 $buffer_name buffer
    #item 149
    if {$buffer == ""} {
        
    } else {
        #item 152
        add_token result $state $buffer
        #item 153
        set buffer ""
    }
}

proc init { } {
    #item 176
    variable initialized
    variable lexer
    #item 177
    if {$initialized} {
        
    } else {
        #item 175
        set initialized 1
        #item 184
        array set properties [ mwc::get_file_properties ]
        #item 180
        if {[info exists properties(language)]} {
            #item 186
            set language $properties(language)
            #item 183
            array set generators [ gen::get_generators ]
            #item 187
            if {[info exists generators($language)]} {
                #item 188
                lassign $generators($language) generator extension
                #item 189
                set parts [ split $generator ":" ]
                #item 190
                set name "::[ lindex $parts 0 ]::highlight"
                #item 197
                set commands [ info procs $name ]
                #item 195
                if {$commands == {}} {
                    #item 185
                    set lexer ""
                } else {
                    #item 198
                    set lexer [ lindex $commands 0 ]
                }
            } else {
                #item 185
                set lexer ""
            }
        } else {
            #item 185
            set lexer ""
        }
    }
}

proc lex { text } {
    #item 387
    set tokens [ to_tokens $text ]
    #item 388
    set state "idle"
    set tokens2 {}
    set buffer ""
    foreach token $tokens {
        #item 391
        lassign $token type text
        #item 3920001
        if {$state == "idle"} {
            #item 405
            if {$text == "\'"} {
                #item 412
                set buffer $text
                #item 407
                set state "string"
            } else {
                #item 464
                if {$text == "\""} {
                    #item 467
                    set buffer $text
                    #item 466
                    set state "dstring"
                } else {
                    #item 404
                    lappend tokens2 $token
                }
            }
        } else {
            #item 3920002
            if {$state == "string"} {
                #item 4130001
                if {$text == "\'"} {
                    #item 420
                    append buffer $text
                    #item 421
                    add_token tokens2 "string" $buffer
                    #item 422
                    set state "idle"
                } else {
                    #item 4130002
                    if {$text == "\\"} {
                        #item 423
                        append buffer $text
                        #item 424
                        set state "escaping"
                    } else {
                        #item 425
                        append buffer $text
                    }
                }
            } else {
                #item 3920003
                if {$state == "dstring"} {
                    #item 4740001
                    if {$text == "\""} {
                        #item 481
                        append buffer $text
                        #item 482
                        add_token tokens2 "string" $buffer
                        #item 483
                        set state "idle"
                    } else {
                        #item 4740002
                        if {$text == "\\"} {
                            #item 484
                            append buffer $text
                            #item 485
                            set state "descaping"
                        } else {
                            #item 486
                            append buffer $text
                        }
                    }
                } else {
                    #item 3920004
                    if {$state == "descaping"} {
                        #item 470
                        append buffer $text
                        #item 471
                        set state "dstring"
                    } else {
                        #item 3920005
                        if {$state == "escaping"} {
                            
                        } else {
                            #item 3920006
                            error "Unexpected switch value: $state"
                        }
                        #item 426
                        append buffer $text
                        #item 427
                        set state "string"
                    }
                }
            }
        }
    }
    #item 446
    set long "!=<>|&"
    #item 428
    set state "idle"
    set tokens3 {}
    set buffer ""
    foreach token $tokens2 {
        #item 430
        lassign $token type text
        #item 434
        if {$state == "idle"} {
            #item 437
            if {[string_contains $long $text]} {
                #item 440
                set buffer $text
                #item 441
                set state "op"
            } else {
                #item 442
                lappend tokens3 $token
            }
        } else {
            #item 458
            if {[string_contains $long $text]} {
                #item 462
                append buffer $text
            } else {
                #item 460
                add_token tokens3 "op" $buffer
                #item 463
                lappend tokens3 $token
                #item 461
                set state "idle"
            }
        }
    }
    #item 433
    return $tokens3
}

proc make_oper_list { } {
    #item 59
    set ops {
    	"," "." ";" ":" "\(" "\)" "\{" "\}" "|" "@"
    	"\[" "\]" "'" "\\" "\"" "/" "+" "-" "*" "!"
    	"#" "$" "%" "^" "&" "=" ">" "<" "?" "~" "`"
    }
    #item 62
    set result {}
    foreach op $ops {
        #item 63
        lappend result $op 1
    }
    #item 64
    return $result
}

proc render_text { surface coords text font fill anchor } {
    #item 271
    set ids {}
    #item 297
    if {$text == ""} {
        #item 15
        set main [ $surface create text \
        	$coords \
        	-text $text \
        	-font $font \
        	-fill $fill \
        	-anchor $anchor ]
        #item 34
        set ids [ list $main ]
    } else {
        #item 224
        variable lexer
        #item 192
        init
        #item 221
        if {$lexer == ""} {
            #item 15
            set main [ $surface create text \
            	$coords \
            	-text $text \
            	-font $font \
            	-fill $fill \
            	-anchor $anchor ]
            #item 34
            set ids [ list $main ]
        } else {
            #item 36
            set tokens \
            [to_tokens $text]
            #item 225
            set colors \
            [$lexer $tokens]
            #item 235
            set tokens2 {}
            #item 226
            set length [ llength $tokens ]
            #item 2270001
            set i 0
            while { 1 } {
                #item 2270002
                if {$i < $length} {
                    
                } else {
                    break
                }
                #item 229
                set token [ lindex $tokens $i ]
                set color [ lindex $colors $i ]
                #item 231
                if {$color == ""} {
                    #item 234
                    lappend token $fill
                } else {
                    #item 230
                    lappend token $color
                }
                #item 236
                lappend tokens2 $token
                #item 2270003
                incr i
            }
            #item 251
            set tokens_ws {}
            set lcount 0
            #item 272
            set line_width 0
            set widths {}
            foreach token $tokens2 {
                #item 255
                lassign $token type ttext color
                #item 256
                set width [ font measure $font $ttext ]
                #item 257
                set token_ws [ list $type $ttext $color $width ]
                lappend tokens_ws $token_ws
                #item 259
                if {$ttext == "\n"} {
                    #item 262
                    incr lcount
                    lappend widths $line_width
                    set line_width 0
                } else {
                    #item 274
                    set line_width \
                    [expr {$line_width + $width}]
                }
            }
            #item 298
            lappend widths $line_width
            #item 292
            if {$anchor == "center"} {
                #item 242
                lassign $coords x y
                #item 252
                set line_height [ font metrics $font -linespace ]
                #item 258
                set cy \
                [expr {$y - int($line_height * $lcount / 2)}]
                #item 263
                set line_width [ lindex $widths 0 ]
                set cx [ expr { int($x - $line_width / 2) } ]
                set line_id 0
                foreach token $tokens_ws {
                    #item 245
                    lassign $token type ttext color width
                    #item 270
                    set tcoords [ list $cx $cy ]
                    #item 269
                    lappend ids [ $surface create text \
                    	$tcoords \
                    	-text $ttext \
                    	-font $font \
                    	-fill $color \
                    	-anchor "w" ]
                    #item 268
                    incr cx $width
                    #item 264
                    if {$ttext == "\n"} {
                        #item 267
                        incr cy $line_height
                        incr line_id
                        set line_width [ lindex $widths $line_id ]
                        set cx [ expr { int($x - $line_width / 2) } ]
                    } else {
                        
                    }
                }
            } else {
                #item 278
                lassign $coords x y
                #item 282
                set line_height [ font metrics $font -linespace ]
                #item 283
                set cy \
                [expr {$y - int($line_height * $lcount / 2)}]
                #item 284
                set cx $x
                foreach token $tokens_ws {
                    #item 281
                    lassign $token type ttext color width
                    #item 291
                    set tcoords [ list $cx $cy ]
                    #item 290
                    lappend ids [ $surface create text \
                    	$tcoords \
                    	-text $ttext \
                    	-font $font \
                    	-fill $color \
                    	-anchor "w" ]
                    #item 289
                    incr cx $width
                    #item 285
                    if {$ttext == "\n"} {
                        #item 288
                        set cx $x
                        incr cy $line_height
                    } else {
                        
                    }
                }
            }
        }
    }
    #item 220
    return $ids
}

proc reset { } {
    #item 300
    variable initialized
    variable lexer
    #item 166
    set initialized 0
    #item 299
    set lexer ""
}

proc string_contains { haystack needle } {
    #item 452
    set pos \
    [string first $needle $haystack]
    #item 453
    if {$pos == -1} {
        #item 456
        return 0
    } else {
        #item 457
        return 1
    }
}

proc to_lines { text } {
    #item 204
    set tokens \
    [to_tokens $text]
    #item 205
    set result {}
    set line {}
    foreach token $tokens {
        #item 212
        lassign $token type text
        #item 209
        if {$text == "\n"} {
            #item 214
            lappend result $line
            set line {}
        } else {
            #item 213
            lappend line $token
        }
    }
    #item 216
    if {$line == {}} {
        
    } else {
        #item 215
        lappend result $line
        set line {}
    }
    #item 206
    return $result
}

proc to_tokens { text } {
    #item 91
    set result {}
    #item 65
    array set ops [ make_oper_list ]
    #item 66
    set state "space"
    #item 67
    set length [ string length $text ]
    #item 119
    set buffer ""
    #item 680001
    set i 0
    while { 1 } {
        #item 680002
        if {$i < $length} {
            
        } else {
            break
        }
        #item 77
        set c [ string index $text $i ]
        #item 88
        if {$c == "\r"} {
            
        } else {
            #item 700001
            if {[info exists ops($c)]} {
                #item 83
                set type "op"
            } else {
                #item 700002
                if {$c == "\t"} {
                    #item 109
                    set type "space"
                    #item 108
                    set c "    "
                } else {
                    #item 700003
                    if {[string is space $c]} {
                        #item 87
                        set type "space"
                    } else {
                        #item 700004
                        if {[string is digit $c]} {
                            #item 107
                            set type "digit"
                        } else {
                            #item 82
                            set type "alpha"
                        }
                    }
                }
            }
            #item 160
            if {$state == "space"} {
                #item 1100001
                if {($type == "op") || ($type == "space")} {
                    #item 121
                    add_token result $type $c
                } else {
                    #item 1100003
                    if {$type == "digit"} {
                        #item 130
                        append buffer $c
                        #item 132
                        set state "number"
                    } else {
                        #item 1100004
                        if {$type == "alpha"} {
                            
                        } else {
                            #item 1100005
                            error "Unexpected switch value: $type"
                        }
                        #item 131
                        append buffer $c
                        #item 133
                        set state "token"
                    }
                }
            } else {
                #item 1340001
                if {($type == "op") || ($type == "space")} {
                    #item 154
                    flush result $state buffer
                    #item 156
                    add_token result $type $c
                    #item 157
                    set state "space"
                } else {
                    #item 1340003
                    if {($type == "digit") || ($type == "alpha")} {
                        
                    } else {
                        #item 1340005
                        error "Unexpected switch value: $type"
                    }
                    #item 158
                    append buffer $c
                }
            }
        }
        #item 680003
        incr i
    }
    #item 161
    flush result $state buffer
    #item 92
    return $result
}

}
