summaryrefslogtreecommitdiff
path: root/lib/editor/exports.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/editor/exports.tcl')
-rwxr-xr-xlib/editor/exports.tcl486
1 files changed, 486 insertions, 0 deletions
diff --git a/lib/editor/exports.tcl b/lib/editor/exports.tcl
new file mode 100755
index 0000000..2ce2ed4
--- /dev/null
+++ b/lib/editor/exports.tcl
@@ -0,0 +1,486 @@
+#!/usr/bin/tclsh
+# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
+
+############################################################################
+# Copyright (C) 2007-2009 by Martin Ošmera #
+# martin.osmera@gmail.com #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+# --------------------------------------------------------------------------
+# DESCRIPTION
+# Implements exports to other data formats (XHTML && LaTeX)
+# This file should be loaded into class Editor in file "editor.tcl"
+# --------------------------------------------------------------------------
+
+## Get maximum value for progressbar showing highlightion progress (proc. highlight_all)
+ # @return Int - Number of lines to highlight divided by 50
+public method highlight_all_count_of_iterations {} {
+ set result 0
+ for {set i 1} {$i < [string bytelength $highlighted_lines]} {incr i} {
+ if {[string index $highlighted_lines $i] == 0} {
+ incr result
+ }
+ if {![expr {$i % 1000}]} {update}
+ }
+ return [expr {$result / 50}]
+}
+
+## Highlight all lines in the editor (can take a long time !)
+ # @return void
+public method highlight_all {} {
+ # Reset abort variables
+ set getDataAsLaTeX_abort 0
+
+ # Highlight all lines
+ set len [string bytelength $highlighted_lines]
+ for {set i 1} {$i < $len} {incr i} {
+ if {[string index $highlighted_lines $i]} {continue}
+
+ # Highlight line
+ parse $i
+
+ # Update progress bar
+ if {![expr {$i % 50}]} {
+ incr ::X::compilation_progress
+ update
+ }
+
+ # Conditional abort
+ if {$getDataAsLaTeX_abort} {
+ set getDataAsLaTeX_abort 0
+ return
+ }
+ }
+}
+
+## Get maximum value for export progress bar
+ # @return Int - the value
+public method getDataAsXHTML_count_of_iterations {} {
+ set result 0
+ foreach tag_def [concat \
+ ${ASMsyntaxHighlight::hightlight_tags} \
+ ${CsyntaxHighlight::hightlight_tags} \
+ ${LSTsyntaxHighlight::hightlight_tags} \
+ ] {
+ set range [$editor tag ranges [lindex $tag_def 0]]
+ incr result [llength $range]
+ if {![expr {$result % 1000}]} {update}
+ }
+ return [expr {$result / 50}]
+}
+
+## Abort export to LaTeX
+ # @return void
+public method getDataAsLaTeX_abort_now {} {
+ set getDataAsLaTeX_abort 1
+}
+
+## Export editor content as LaTeX source (include colors)
+ # @return String - LaTeX source code
+public method getDataAsLaTeX {} {
+
+ # Reset abort variables
+ set getDataAsLaTeX_abort 0
+
+ # Local variables
+ set end [$editor index end] ;# Editor end index
+ set last_index 0 ;# Current position (by characters)
+ set line(1) 0 ;# Map of indexes ($line(num) == scalar_index)
+
+ # Create map of indexes
+ for {set i 1; set j 2} {$i < $end} {incr i; incr j} {
+
+ # Conditional abort
+ if {$getDataAsLaTeX_abort} {
+ set getDataAsLaTeX_abort 0
+ return {}
+ }
+
+ # Determinate last column of the line
+ set idx [$editor index "$i.0 lineend"]
+ regexp {\d+$} $idx idx
+
+ # Adjust map of indexes
+ incr last_index $idx
+ incr last_index
+ set line($j) $last_index
+ }
+
+ # Create LaTeX preamble
+ set latex "\\documentclass\[a4paper,12pt\]{article}"
+ append latex "\n\n% Creator: ${::APPNAME}\n\n"
+ append latex "\\usepackage\[utf-8\]{inputenc}\n"
+ append latex "\\usepackage\[T1\]{fontenc}\n"
+ append latex "\\usepackage{color}\n"
+ append latex "\\title{$filename}\n"
+ append latex "\\date{[clock format [clock seconds] -format {%D}]}\n"
+ append latex "\n% define highlighting\n"
+
+ ## Determinate highlighting tag ranges and define colors for 'color' package
+ set ranges {}
+ # Iterate over predefined highlighting tags
+ foreach tag_def [concat \
+ ${ASMsyntaxHighlight::hightlight_tags} \
+ ${CsyntaxHighlight::hightlight_tags} \
+ ${LSTsyntaxHighlight::hightlight_tags} \
+ ] {
+
+ # Conditional abort
+ if {$getDataAsLaTeX_abort} {
+ set getDataAsLaTeX_abort 0
+ return {}
+ }
+
+ # Local variables
+ set color [lindex $tag_def 1] ;# RGB color
+ set red [string range $color 1 2] ;# Color - RED
+ set green [string range $color 3 4] ;# Color - GREEN
+ set blue [string range $color 5 6] ;# Color - BLUE
+ set tag [lindex $tag_def 0] ;# Tag name
+ set range [$editor tag ranges $tag] ;# List of tag ranges
+ set len [llength $range] ;# Number of ranges
+ set mirror_tag {} ;# Tag with exatly the same highlight
+
+ # Determinate mirror tag
+ switch -- $tag {
+ {tag_constant} {set mirror_tag tag_constant_def}
+ {tag_macro} {set mirror_tag tag_macro_def}
+ }
+ if {$mirror_tag != {}} {
+ set mirror_range [$editor tag ranges $mirror_tag]
+ } {
+ set mirror_range {}
+ }
+
+ # If the tag isn't present in the text -> skip
+ if {$len == 0 && ![llength $mirror_range]} {
+ continue
+ }
+ # Adjust tag name
+ set tag [string replace $tag 0 3]
+
+ # Convert hexadecimal color values to decimal representation
+ set red [string range [expr "0x$red / 255.0"] 0 4]
+ set green [string range [expr "0x$green / 255.0"] 0 4]
+ set blue [string range [expr "0x$blue / 255.0"] 0 4]
+ # Define color (for package color)
+ append latex "\\definecolor{highlight_$tag}{rgb}{$red, $green, $blue}\n"
+
+ # Adjust map of text tags
+ set mirror_tag {}
+ switch -- $tag {
+ {constant} {set mirror_tag tag_constant_def}
+ {macro} {set mirror_tag tag_macro_def}
+ }
+ for {set i 0} {$i < $len} {incr i} {
+ lappend ranges [list [lindex $range $i] $tag 1]
+ incr i
+ lappend ranges [list [lindex $range $i] $tag 0]
+ }
+ if {$mirror_tag != {}} {
+ set range [$editor tag ranges $mirror_tag]
+ set len [llength $range]
+ for {set i 0} {$i < $len} {incr i} {
+ lappend ranges [list [lindex $range $i] $tag 1]
+ incr i
+ lappend ranges [list [lindex $range $i] $tag 0]
+ }
+ }
+ }
+
+ # Sort map of text tags (recursive)
+ set ranges [lsort -command "::FileList::editor__sort_tag_ranges" $ranges]
+
+ # Get plain text
+ set text [$editor get 1.0 end]
+ regsub -all {'} $text "\a" text
+
+ ## Create map of tabulators ("\t")
+ set tab_map {}
+ # Iterate ovet lines in editor
+ foreach textLine [split $text "\n"] {
+
+ if {$textLine == {}} {continue}
+ set idx -1
+ set spaces 0
+ set correction 0
+
+ while 1 {
+ set idx [string first "\t" $textLine [expr {$idx + 1}]]
+ if {$idx == -1} {break}
+
+ set spaces [expr {8 - (($idx + $correction) % 8)}]
+ incr correction [expr {$spaces - 1}]
+
+ lappend tab_map $spaces
+ }
+ }
+
+ # Write LaTeX control sequences
+ set i 0
+ foreach range $ranges {
+
+ # Conditional abort
+ if {$getDataAsLaTeX_abort} {
+ set getDataAsLaTeX_abort 0
+ return {}
+ }
+
+ # Update progress bar
+ if {![expr {$i % 50}]} {
+ incr ::X::compilation_progress
+ update
+ }
+
+ set idx [split [lindex $range 0] {.}] ;# Text index
+ set row [lindex $idx 0] ;# Line number
+ set col [lindex $idx 1] ;# Column number
+
+ # Determinate scalar text index
+ set idx [expr {$line($row) + $col}]
+ if {$idx < 0} {set idx 0}
+
+ # Determinate string to insert
+ if {[lindex $range 2]} {
+ set tag "'\{\\color{highlight_[lindex $range 1]}\\verb'"
+ } {
+ set tag "'\}\\verb'"
+ }
+
+ # Insert control sequence into plain text
+ set char [string index $text $idx]
+ set text [string replace $text $idx $idx "$tag$char"]
+
+ incr i
+ }
+
+ # Covert tabs to spaces
+ set i 0
+ foreach spaces $tab_map {
+ set idx [string first "\t" $text]
+ if {$idx == -1} {break}
+
+ set text [string replace $text $idx $idx [string repeat { } $spaces]]
+ if {![expr {$i % 1000}]} {update}
+ incr i
+ }
+
+ # Adjust lines
+ regsub -all -line {^} $text {\\verb'} text
+ regsub -all -line {$} $text "'\\\\\\" text
+ regsub -all -line {\s+'\\\\$} $text {'\\\\} text
+ regsub -all {\\verb''} $text {} text
+ regsub -all -line {^\\\\$} $text {\\verb''&} text
+ regsub -all "\a" $text {'\\verb"'"\\verb'} text
+
+ # Create final LaTeX document
+ append latex "\n\n\\begin{document}\n"
+ append latex "\\ \\\\\n"
+ append latex $text
+ append latex "\n\\end{document}"
+
+ # Return result
+ return $latex
+}
+
+## Abort export to XHTML
+ # @return void
+public method getDataAsXHTML_abort_now {} {
+ set getDataAsXHTML_abort 1
+}
+
+## Export editor content as XHTML source (include colors)
+ # @return String - XHTML source code
+public method getDataAsXHTML {} {
+
+ # Reset abort variables
+ set getDataAsXHTML_abort 0
+
+ # Local variables
+ set end [$editor index end] ;# Editor end index
+ set last_index 0 ;# Current position (by characters)
+ set line(1) 0 ;# Map of indexes ($line(num) == scalar_index)
+
+ # Create map of indexes
+ for {set i 1; set j 2} {$i < $end} {incr i; incr j} {
+
+ # Conditional abort
+ if {$getDataAsXHTML_abort} {
+ set getDataAsXHTML_abort 0
+ return {}
+ }
+
+ # Determinate last column of the line
+ set idx [$editor index [list $i.0 lineend]]
+ regexp {\d+$} $idx idx
+
+ # Adjust map of indexes
+ incr last_index $idx
+ incr last_index
+ set line($j) $last_index
+ }
+
+ # Create XHTML header
+ set html "<?xml version='1.0' encoding='utf-8' standalone='no'?>\n"
+ append html "<!DOCTYPE html PUBLIC\n"
+ append html "\t'-//W3C//DTD XHTML 1.1//EN'\n"
+ append html "\t'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'>\n"
+ append html "<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'>\n"
+ append html "<!--\n\tCreator: ${::APPNAME}\n\tDate: [clock format [clock seconds] -format {%D}]\n-->\n"
+ append html "\t<head>\n"
+ append html "\t\t<title>$filename</title>\n"
+ append html "\t\t<meta http-equiv=\"Content-Type\" content=\"application/xhtml+xml; charset=UTF-8\" />\n"
+ append html "\t\t<meta name=\"Generator\" content=\"${::APPNAME}\" />\n"
+ append html "\t\t<style type=\"text/css\">\n"
+ append html "\t\t\tbody {\n\t\t\t\tfont-family: $fontFamily;\n\t\t\t\tfont-size: ${fontSize}px;\n\t\t\t}\n"
+
+ ## Determinate highlighting tag ranges and define inline CSS
+ set ranges {}
+ # Iterate over predefined highlighting tags
+ foreach tag_def [concat \
+ ${ASMsyntaxHighlight::hightlight_tags} \
+ ${CsyntaxHighlight::hightlight_tags} \
+ ${LSTsyntaxHighlight::hightlight_tags} \
+ ] {
+
+ # Conditional abort
+ if {$getDataAsXHTML_abort} {
+ set getDataAsXHTML_abort 0
+ return {}
+ }
+
+ # Local variables
+ set tag [lindex $tag_def 0] ;# Tag name
+ set range [$editor tag ranges $tag] ;# List of tag ranges
+ set len [llength $range] ;# Number of ranges
+ set mirror_tag {} ;# Tag with exatly the same highlight
+
+ # Determinate mirror tag
+ switch -- $tag {
+ {tag_constant} {set mirror_tag tag_constant_def}
+ {tag_macro} {set mirror_tag tag_macro_def}
+ }
+ if {$mirror_tag != {}} {
+ set mirror_range [$editor tag ranges $mirror_tag]
+ } {
+ set mirror_range {}
+ }
+
+ # If the tag isn't present in the text -> skip
+ if {$len == 0 && ![llength $mirror_range]} {
+ continue
+ }
+ # Adjust tag name
+ set tag [string replace $tag 0 3]
+
+ # create CSS
+ append html "\t\t\t.$tag {\n"
+ append html "\t\t\t\tcolor: [lindex $tag_def 1];\n"
+ if {[lindex $tag_def 2]} {
+ append html "\t\t\t\ttext-decoration: line-through;\n"
+ }
+ if {[lindex $tag_def 3]} {
+ append html "\t\t\t\tfont-style: italic;\n"
+ }
+ if {[lindex $tag_def 4]} {
+ append html "\t\t\t\tfont-weight: bold;\n"
+ }
+ append html "\t\t\t}\n"
+
+ for {set i 0} {$i < $len} {incr i} {
+ lappend ranges [list [lindex $range $i] $tag 1]
+ incr i
+ lappend ranges [list [lindex $range $i] $tag 0]
+ }
+ if {$mirror_tag != {}} {
+ set len [llength $mirror_range]
+ for {set i 0} {$i < $len} {incr i} {
+ lappend ranges [list [lindex $mirror_range $i] $tag 1]
+ incr i
+ lappend ranges [list [lindex $mirror_range $i] $tag 0]
+ }
+ }
+ }
+ append html "\t\t</style>\n"
+ append html "\t</head>\n"
+
+ # Sort tag ranges (recursive)
+ set ranges [lsort -command "::FileList::editor__sort_tag_ranges" $ranges]
+
+ # Get plain text
+ set text [$editor get 1.0 end]
+ # Translate '<' and '>' to '\a' and '\b'
+ regsub -all {<} $text "\a" text
+ regsub -all {>} $text "\b" text
+
+ # Write XHTML tags to plain text
+ set i 0
+ foreach range $ranges {
+
+ # Conditional abort
+ if {$getDataAsXHTML_abort} {
+ set getDataAsXHTML_abort 0
+ return {}
+ }
+
+ # Update progress bar
+ if {![expr {$i % 50}]} {
+ incr ::X::compilation_progress
+ update
+ }
+
+ # Local variables
+ set idx [split [lindex $range 0] {.}] ;# Text index
+ set row [lindex $idx 0] ;# Line number
+ set col [lindex $idx 1] ;# Column number
+
+ # Determinate scalar text index
+ set idx [expr {$line($row) + $col}]
+ # Skip unused tags
+ if {$idx < 0} {set idx 0}
+
+ # Deterinate string to insert
+ if {[lindex $range 2]} {
+ set tag "span class='[lindex $range 1]'"
+ } {
+ set tag {/span}
+ }
+
+ # Insert XHTML tag into the text
+ set char [string index $text $idx]
+ set text [string replace $text $idx $idx "<$tag>$char"]
+
+ incr i
+ }
+
+ # Translate '&' -> &amp;
+ regsub -all "&" $text {\&amp;} text
+ # Traslate '\a', '\b' -> '&lt;', '&gt;'
+ regsub -all "\a" $text {\&lt;} text
+ regsub -all "\b" $text {\&gt;} text
+
+ # Create final XHTML document
+ append html "\t<body>\n\t\t<pre>\n"
+ append html "\t\t<!-- CODE BLOCK - begin -->\n"
+ append html $text
+ append html "\t\t<!-- CODE BLOCK - end -->\n"
+ append html "\t\t</pre>\n\t</body>\n</html>"
+
+ # Return result
+ return $html
+}