// Create color syntax highlighted html file from source code
// (c) 2002-2005, Pauli Lindgren 
// v0.1  03.08.2002
// v1.0  17.10.2005
//
// T-Reg Usage:
//   80 = name of syntax file
//   81 = keyword to be highlighted
//   82 = html tag to used for highlight
//   83 = html end tag
//   84 = line comment start string
//   85 = comment start string
//   86 = comment end string
//   87 = string delimiter
//   88 = tmp
//   90 = name of input file
//   91 = name of HTML output file
//   92 = path for HTML output file
//
// Numerig register usage:
//  #51 = current file buffer number
//  #52 = syntax file buffer number
//  #55 = keyword search option (Case sensitive)
//  #61 = flag: include CSS code
//  #62 = flag: full web page (include document level marking)


#61 = 1			// 1 = include CSS code, 0 = HTML only
#62 = 1			// 1 = full web page (head, body etc. tags)

Reg_Set(92, "f:\html\apu")	// Path for HTML file defined here, or...
//Reg_Set(92, PATH_ONLY)  	// Path for HTML file = same as source file

Reg_Set(80, HOME)
Reg_Set(80, "\", APPEND)
Reg_Set(80, SYN_NAME, APPEND)		// @80 = Name of syntax file
Reg_Set(90, FILENAME)			// @90 = Name of input file
Reg_Set(91, FILE_ONLY)
Reg_Set(91, "_", APPEND)
Reg_Set(91, EXT_ONLY, APPEND)
Reg_Set(91, ".htm", APPEND)		// @91 = Name of HTML output file

Reg_Copy_Block(88, 0, File_Size)	// create new file *.htm
Chdir(@92)
File_Open(@91)
Del_Block(0, File_Size)
Reg_Ins(88)

// Replace reserved HTML characters with entities in source file
Replace("&","&", BEGIN+ALL+NOERR)
Replace("<","&lt;", BEGIN+ALL+NOERR)
Replace(">","&gt;", BEGIN+ALL+NOERR)

#51 = Buf_Num			// #51 = current file edit buffer

#52 = File_Check(@(80)) 	// #52 = syntax file buffer, if already open
if (#52 == -1) {		// If syntax file not open...
    Buf_Switch(Buf_Free)	// Switch to free buffer
}
File_Open(@(80),BROWSE+NOEVENT) // Open or switch to syntax file
#52 = Buf_Num			// #52 = syntax file buffer

Statline_Message("Comments")

// Highlight comments:
BOF
if (Search("Comment|[|W]=|[|W]", ADVANCE+NOERR)) {
  #53 = CP
  Search(",")
  RCB(85,#53,CP)		// @85 = comment start string
  Char
  Match("|W", ADVANCE)
  #53 = CP
  Search("|{|W,|N}")
  RCB(86,#53,CP)		// @86 = comment end string
  Buf_Switch(#51)		// original buffer
  BOF
  Repeat(ALL) {
    Search("|@(85)",ERRBREAK)
    IT("<em>")
    Search("|@(86)",ADVANCE+ERRBREAK)
    IT("</em>")
  }
}


// Highlight line comments:
Buf_Switch(#52)			// syntax file buffer
BOF
if (Search("Linecmt|[|W]=|[|W]", ADVANCE+NOERR)) {
  Reg_Set(88,"|{|W,|N}")
  if (Cur_Char==34 || Cur_Char==39) {
    RCB(88,CP,CP+1)		// Quote character
    char  			// skip quote
  }
  #53 = CP
  Search(@(88))
  RCB(84,#53,CP)		// @84 = line comment start string
  Buf_Switch(#51)		// original buffer
  BOF
  Repeat(ALL) {
    Search("|{|@(84),<}",ERRBREAK)
    if (Cur_Char == '<') {	// skip comments inside comments
      Char
      RCB(88,CP,CP+1)
      if (Cur_Char != '/') {
	Search("</|@(88)", NOERR)   // find closing tag
      }
      Search(">", ADVANCE+ERRBREAK) // find end of </a> </i> tag
    } else {
      IT("<em>")		// highlight comment
      EOL
      IT("</em>")
    }
  }
}


// Highlight strings:
Statline_Message("Strings")
Buf_Switch(#52)			// syntax file buffer
BOF
if (Search("Strings|[|W]=|[|W]", ADVANCE+NOERR)) {
  char
  RCB(87,CP,CP+1)		// @87 = string delimiter
  Buf_Switch(#51)		// original buffer
  BOF
  Repeat(ALL) {
    Search("|{|@(87),<}",ERRBREAK)
    if (Cur_Char == '<') {	// skip text inside html tags
      Char
      RCB(88,CP,CP+1)
      if (Cur_Char != '/') {
	Search("</|@(88)", NOERR)   // find closing tag
      }
      Search(">", ADVANCE+ERRBREAK) // find end of </a> </i> tag
    } else {
      IT("<span class=string>")	// highlight string
      char
      Search("|@(87)", ADVANCE+ERRBREAK)
      IT("</span>")
    }
  }
}


// Highlight keywords:

Reg_Set(81,"1")
Reg_Set(82,"<b>")
Reg_Set(83,"</b>")
Call("kwords")

Reg_Set(81,"2")
Reg_Set(82,"<tt>")
Reg_Set(83,"</tt>")
Call("kwords")

Reg_Set(81,"3")
Reg_Set(82,'<span class=k3>')
Reg_Set(83,"</span>")
Call("kwords")

Reg_Set(81,"4")
Reg_Set(82,'<span class=k4>')
Reg_Set(83,"</span>")
Call("kwords")

Buf_Switch(#52)		// syntax file buffer
Buf_Quit(OK)		// close syntax file buffer (do not save changes)
Buf_Switch(#51)

// remove reduntant marking (in case two consecutive keywords)
BOF
Replace("</b> <b>"," ", ALL+NOERR)

// add HTML marking
BOF
IT("<PRE>")
IN
EOF
IN
IT("</PRE>")
IN

// add document level marking if enabled
BOF
if (#62) {
  IT("<HTML>") IN
  IT("<HEAD>") IN
  IT("  <TITLE>")
  IT("Listing of ") Reg_Ins(90)
  IT("</TITLE>") IN
  IN
}

// add CSS if enabled
if (#61) {
  IT('<style type="text/css">') IN
  IT("  BODY     { color: 0; background-color: #f8f8f8 }") IN
  IT("  PRE EM   { color: #009900 }				/* comments */") IN
  IT("  PRE B    { color: #0000ee; font-weight: bold } 	/* keywords 1 */") IN
  IT("  PRE TT   { color: #0055aa; font-weight: bold } 	/* keywords 2 */") IN
  IT("  PRE .k3  { color: #990099; font-weight: bold }	/* keywords 3 */") IN
  IT("  PRE .k4  { color: #aa0000; font-weight: bold }	/* keywords 4 */") IN
  IT("  PRE .string { color:#996600 }				/* strings */") IN
  IT("</style>") IN
  IN
}

if (#62) {
  IT("</HEAD>") IN
  IN
  EOF
  IT("</HTML>") IN
}

Statline_Message("Done")

return

// Search all keywords in keyword group @81,
// highlight each keyword with html tags <@82>...<@83>

:kwords:
Statline_Message("Keywords |@(81)")
Buf_Switch(#51)			// original buffer
BOF
Buf_Switch(#52)			// syntax file buffer
BOF

// check the casesense of the keyword group
#55 = 0
if (Search("Casesense|@(81)|[|W]=|[|W]", ADVANCE+NOERR)) {
  if (Cur_Char == 'y' || Cur_Char == 'Y') {
    #55 = CASE			// case sensitive keywords
  }
}

BOF
if (Search("Reserved|@(81)|[|W]=|[|W]", ADVANCE+NOERR)) {  // find keyword group
  Repeat(ALL) {
    #53 = CP
    Search("|{|,,|N}")		// find end of keyword
    RCB(81,#53,CP)		// t-reg 81 = keyword
    Buf_Switch(#51)		// original buffer
    BOF
    Repeat(ALL) {
      Search("|{|S|@(81)|S,<}", #55+ERRBREAK)
      if (Cur_Char == '<') {	// skip text inside html tags
	Char
	RCB(88,CP,CP+1)
	if (Cur_Char != '/') {
	  Search("</|@(88)", NOERR)   // find closing tag
	}
	Search(">", ADVANCE+ERRBREAK) // find end of tag
      } else {
	Char
	Reg_Ins(82)		// highlight keyword
	Char(Chars_Matched-2)
	Reg_Ins(83)
      }
    }
    Buf_Switch(#52)		// syntax file buffer
    if (cur_char != ',') {
      Line(1)  
      if (At_EOL) {Break}	// end of keyword list
    } else {
      char   
      Match("|[|W]|N", ADVANCE)	// in case comma at end of line
    }
    Match("|W", ADVANCE)	// find start of next keyword
    if (Match("//") == 0) {	// skip comment in syntax file
      Line(1)
      Search("|{|F,//}", ERRBREAK)
    }
  }
}

return