renee.rtf.xaa



renee is RTF parser/macro processor I wrote. I'm posting it to
comp.lang.tcl because it uses Tcl heavily--not so much because
the program is particularly targetted for Tcl.

{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
{\fonttbl\f0\froman\fcharset77 Palatino-Bold;\f1\froman\fcharset77 Palatino-Roman;\f2\fswiss\fcharset77 Helvetica-Bold;
\f3\fswiss\fcharset77 Helvetica;\f4\froman\fcharset77 Palatino-Italic;\f5\fnil\fcharset78 HiraKakuPro-W3;
\f6\fnil\fcharset77 AppleSymbols;\f7\fswiss\fcharset77 Helvetica-Oblique;\f8\fswiss\fcharset77 Optima-Bold;
\f9\fswiss\fcharset77 Optima-Regular;\f10\fswiss\fcharset77 Optima-Italic;\f11\froman\fcharset77 Palatino-BoldItalic;
\f12\fswiss\fcharset77 Optima-BoldItalic;\f13\fmodern\fcharset77 Courier;\f14\fmodern\fcharset77 Courier-Oblique;
\f15\fnil\fcharset77 GillSans-Bold;\f16\fnil\fcharset78 HiraKakuPro-W6;}
{\colortbl;\red255\green255\blue255;}
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\qr\pardirnatural

\f0\b\fs28 \cf0 1 Ren\'8ee \'d1 RTF Parser and Macro Processor.
\f1\b0\fs24 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f2\b \cf0 <
\f3\b0 copyrightnotice
\f2\b >\

\f3\b0 Copyright \'a9 2007 by S M Ryan.\
\
This specific program and its derivations cannot be resold for profit without permission of the authour. Permission is hereby granted to use or copy this program for all other purposes, provided this notice is retained on all copies. Permission to modify the code and to distribute original code with modifications is granted for only nonprofit use, provided the above notices are retained, and a notice that the code was modified is included with this copyright notice.\
\
The authour makes no claim to other programs by virtue of being translated with this code, inspected by it, linked with its output, live on the same disc, or happen to inhabit the same universe or any accessible alternate reality. The authour makes no claims to modifications which are expressed independently of this code.\
\
THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
\f2\b \

\f3\b0 \
You get what you pay for.\

\f2\b <>\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f4\i\b0\fs22 \cf0 1 Ren\'8ee \'d1 RTF Parser and Macro Processor.\
2 renee\
3 RTF Parsing\
3.1 Document Colours\
3.2 Encodings\
3.3 Document Fonts\
3.4 Document Groups\
3.5 Document Stream\
3.6 Character Stream\
3.7 Parser\
3.8 RTF Deconstruction\
3.9 RTF Reconstruction\
4 Macro Language\
4.1 Declarations\
4.2 State Table Syntax Extensions\
4.3 Macro Language Finite Transducer\
4.4 RTF Styling\
5 Tcl Interpretation\
6 Output Buffer\
6.1 Attributed Characters\
6.2 Append an Object to the Output Buffer\
6.3 Emit Strings to the Output Buffer\
7 Recognise and Expand Macros\
8 Write Output Buffer to Files\
8.1 Line Numbers\
8.2 Regions\
8.3 Errors\
8.4 Write function\
9 macro Command\
10 Miscellaneous\
A Syntax Macros\
B
\f5\i0 \'83\'8c\'83\'43\

\f4\i \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f2\i0\b\fs24 \cf0 <#
\f3\b0 macro embed off
\f2\b >\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f4\i\b0 \cf0 XCode bug \'d1 it can crash if files with line numbers are moved around or it does not like the #line directive.
\f2\i0\b \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f1\b0 \cf0 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f2\b \cf0 <
\f3\b0 \'b2 <=
\f2\b >
\f3\b0 \

\f2\b <
\f3\b0 \'b3 >=
\f2\b >
\f3\b0 \

\f2\b <
\f3\b0 \'ad !=
\f2\b >
\f3\b0 \

\f2\b <
\f3\b0 \'c2 !
\f2\b >
\f3\b0 \

\f2\b <
\f3\b0
\f6 \uc0\u8594
\f3 ->
\f2\b >
\f3\b0 \

\f2\b <
\f3\b0
\f6 \uc0\u8743
\f3 &&
\f2\b >
\f3\b0 \

\f2\b <
\f3\b0
\f6 \uc0\u8744
\f3 ||
\f2\b >
\f3\b0 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f1 \cf0 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f2\b \cf0 source[
\f3\b0 renee.c
\f2\b ]\

\f3\b0
\f2\b priv chars
\f3\b0
\f7\i renee
\f3\i0 =\
"Copyright \'a9 2007 by S M Ryan\\n"\
"All rights reserved; all lefts revered\\n";
\f2\b \
pub
\f3\b0 /*\
copyrightnotice\
*/
\f2\b \
priv
\f3\b0 /*\
copyrightnotice\
*/\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f1 \cf0 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f2\b \cf0 priv\
#include
\f3\b0 <ctype.h>\

\f2\b #define
\f3\b0 isletter(
\f7\i c
\f3\i0 ) (Tcl_UniCharIsAlpha(
\f7\i c
\f3\i0 )
\f6 \uc0\u8744
\f3 (
\f7\i c
\f3\i0 )=='_')\

\f2\b #define
\f3\b0 isname(
\f7\i c
\f3\i0 ) (Tcl_UniCharIsAlnum(
\f7\i c
\f3\i0 )
\f6 \uc0\u8744
\f3 (
\f7\i c
\f3\i0 )=='_')\

\f2\b #include
\f3\b0 <stdarg.h>\

\f2\b #include
\f3\b0 <stdbool.h>\

\f2\b #include
\f3\b0 <stddef.h>\

\f2\b #include
\f3\b0 <stdio.h>\

\f2\b #include
\f3\b0 <stdlib.h>\

\f2\b #include
\f3\b0 <string.h>\

\f2\b #include
\f3\b0 <sys/stat.h>\

\f2\b #include
\f3\b0 <tcl.h>\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f1 \cf0 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\qr\pardirnatural

\f0\b\fs28 \cf0 2 renee\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\qr\pardirnatural

\f8 \cf0 \
\pard\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural
\cf0 [[
\f9\b0\fs24 renee(1).rtf
\f8\b\fs28 ]]\
renee(1) Shell Command\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural
\cf0 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\fs26 \cf0 NAME\
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li1080\fi-360\ql\qnatural\pardirnatural

\f9\b0\fs24 \cf0 renee \'d1 RTF Parser and Macro Processor.\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f2\b \cf0 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f8\fs26 \cf0 SYNOPSIS\
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li1080\fi-360\ql\qnatural\pardirnatural

\fs24 \cf0 renee -p -q -r -s -h -c
\f10\i\b0 abbrevfontfamily
\f9\i0
\f8\b ... -d
\f10\i\b0 debugflags
\f8\i0\b ... -n
\f10\i\b0 maxexpansions
\f8\i0\b -u -o
\f10\i\b0 outputfolder
\f8\i0\b -D
\f10\i\b0 name
\f9\i0 [
\f8\b =
\f10\i\b0 value
\f9\i0 ]
\f10\i
\f8\i0\b ... -U
\f10\i\b0 name
\f9\i0 [
\f8\b --
\f9\b0 ]
\f10\i
\f8\i0\b ...
\f9\b0
\f10\i rtffile
\f9\i0
\f8\b ...
\fs26 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f3\b0\fs24 \cf0 \

\f2\b <
\f3\b0 helpMessage
\f2\b >\

\f3\b0 "%s -p -q -h -c abbrevfontfamily ... -d debugflags ... -n maxexpansions -u "\
"-o outputfolder -Dname[=value] ... -Uname [--] ... rtffile ..."\

\f2\b <>
\f3\b0 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f8\b\fs26 \cf0 \
DESCRIPTION\
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural

\fs24 \cf0 renee
\f9\b0 (1) concatenates one or more RTF files, extracting styled code segments, and translates these from a macro language into a Tcl script. It then (2) runs the script through a Tcl interpretter with an additional
\f8\b macro
\f9\b0 command (see below); this script recognises macros ultimately in the RTF source files and generates one or more output files.\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f2\b \cf0 \
pub func int
\f3\b0 main (
\f2\b int
\f3\b0
\f7\i N
\f3\i0 ,
\f2\b chars
\f3\b0 *
\f7\i P
\f3\i0 )
\f2\b is
\f3\b0 \{\

\f2\b
\f3\b0 flagForPartialReneeProcessing;\

\f2\b
\f3\b0 arrayOfCodeFontnames;\
arrayOfDocumentPaths;\
arrayOfIncludePaths;\
createThePrimaryTclInterpretterOfAProcess;\

\f2\b
\f7\i\b0 codefont
\f3\i0 =
\f7\i pcodefont
\f3\i0 ;\

\f2\b chars
\f7\i\b0 P0
\f3\i0 = (
\f2\b chars
\f3\b0 )*
\f7\i P
\f3\i0 ;\

\f2\b
\f3\b0 createMacroCommand;\
commandLineOptions;\

\f2\b Obj
\f3\b0
\f7\i script
\f3\i0 = 0;\

\f2\b if
\f3\b0 (
\f7\i process
\f3\i0 =='q') \{\

\f2\b
\f7\i\b0 script
\f3\i0 = incr(Tcl_NewObj());\

\f2\b
\f3\b0 Tcl_ReadChars(
\f7\i chstdin
\f3\i0 ,
\f7\i script
\f3\i0 , -1, 0);\

\f2\b \}else
\f3\b0
\f2\b if
\f3\b0 (
\f7\i process
\f3\i0 =='s') \{\

\f2\b
\f3\b0 RTFReconstructor;\

\f2\b
\f3\b0 \}
\f2\b else
\f3\b0 \{\

\f2\b
\f3\b0 defaultRTFsource;\

\f2\b
\f3\b0 defaultCodeFonts;\

\f2\b
\f3\b0 RTFParserVariables;\
macroParserVariables;\

\f2\b while
\f3\b0 (
\f7\i s
\f3\i0 \'adFINAL) \{\
ensureTheNextDocumentIsOpen;\

\f2\b
\f3\b0 incrementTheLineNumberIfThePreviousCharacterWasANewLine;\
checkIfBufferredCharacters;\

\f2\b
\f3\b0 RTFParser;\
translateCharacterIntoUnicode;\
saveCharacterToGroupDestinationIfAny;\

\f2\b if
\f3\b0 (
\f7\i process
\f3\i0 =='r') \{
\f7\i character
\f3\i0 = 0;
\f2\b continue
\f3\b0 ;\}\

\f2\b while
\f3\b0 (
\f7\i character
\f6\i0 \uc0\u8743
\f7\i s
\f3\i0 \'adFINAL) \{\

\f2\b
\f3\b0 flattenRTFStylesIntoTheTextStream;\

\f2\b
\f3\b0 macroParser;\

\f2\b
\f3\b0 \}\

\f2\b
\f3\b0 \}\

\f7\i script
\f3\i0 =
\f7\i X
\f3\i0 ;\

\f2\b
\f3\b0 \}\

\f2\b int
\f3\b0
\f7\i rc
\f3\i0 = TCL_OK;\

\f2\b if
\f3\b0 (
\f7\i process
\f3\i0 =='
\f7\i p
\f3\i0 ') \{\

\f2\b
\f3\b0 Tcl_WriteObj(
\f7\i chstdout
\f3\i0 ,
\f7\i script
\f3\i0 );\

\f2\b return
\f3\b0 0;\

\f2\b
\f3\b0 \}
\f2\b else if
\f3\b0 (
\f7\i process
\f3\i0 \'ad'r'
\f6 \uc0\u8743
\f3
\f7\i process
\f3\i0 \'ad's') \{\

\f2\b
\f7\i\b0 rc
\f3\i0 = Tcl_EvalObjEx(
\f7\i intr
\f3\i0 ,
\f7\i script
\f3\i0 , TCL_EVAL_DIRECT); decr(
\f7\i script
\f3\i0 );\

\f2\b if
\f3\b0 (
\f7\i rc
\f3\i0 ) error("tcl: %s", Tcl_GetStringResult(
\f7\i intr
\f3\i0 ));\

\f2\b else
\f3\b0 cprintf(
\f7\i chstdout
\f3\i0 , "%s\\n", Tcl_GetStringResult(
\f7\i intr
\f3\i0 ));\

\f2\b
\f3\b0 Tcl_Eval(
\f7\i intr
\f3\i0 , "macro flush");\

\f2\b
\f3\b0 \}\

\f2\b
\f3\b0 Tcl_DeleteInterp(
\f7\i intr
\f3\i0 );\

\f2\b return
\f3\b0
\f7\i rc
\f3\i0 ;\

\f2\b
\f3\b0 \}\
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural

\f9 \cf0 \
All parameters are optional and may be presented in any order, except
\f8\b --
\f9\b0 . All parameters after -- are RTF file paths whether they begin a dash (-) or not; RTF file paths before a
\f8\b --
\f9\b0 must not begin with a dash. Parameters followed by a value can written as one word (such as
\f8\b -n100
\f9\b0 ) or two words (
\f8\b -n 100
\f9\b0 ). If no parameters are present,
\f8\b renee
\f9\b0 expects an RTF file read from stdin.\
\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f3 \cf0
\f2\b <
\f3\b0 commandLineOptions
\f2\b >\

\f3\b0
\f2\b while
\f3\b0 (++
\f7\i P
\f3\i0 , --
\f7\i N
\f3\i0 >0) \{\

\f2\b switch
\f3\b0 (
\f7\i P
\f3\i0 [0][0]=='-' ?
\f7\i P
\f3\i0 [0][1] : 0) \{\

\f2\b case
\f3\b0 '-': doubledashOptionOfTheCommandLine;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 0: rtffileOptionOfTheCommandLine;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 'p': pOptionOfTheCommandLine;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 'q': qOptionOfTheCommandLine;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 'r': rOptionOfTheCommandLine;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 's': sOptionOfTheCommandLine;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 'c': cOptionOfTheCommandLine;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 'n': nOptionOfTheCommandLine;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 'u': uOptionOfTheCommandLine;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 'd': dOptionOfTheCommandLine;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 'o': oOptionOfTheCommandLine ;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 'D': DOptionOfTheCommandLine;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 'U': UOptionOfTheCommandLine;
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 'h': hOptionOfTheCommandLine;
\f2\b return
\f3\b0 0;\

\f2\b default
\f3\b0 : cprintf(
\f7\i chstderr
\f3\i0 , "unknown option: %s\\n",
\f7\i P
\f3\i0 [0]);
\f2\b return
\f3\b0 1;\
\}\
\}\

\f2\b <>
\f3\b0 \
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural

\f9 \cf0 \
The following options are available:\
\pard\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li2160\fi-1440\ql\qnatural\pardirnatural

\f8\b \cf0 \
-p
\f9\b0 Only run part (1) of
\f8\b renee
\f9\b0 , parsing RTF and macros into a Tcl script. The Tcl script is written to stdout. The script will include references to
\f8\b macro
\f9\b0 command, which is not included in
\f8\b tclsh
\f9\b0 .\

\f2\b <
\f3\b0 pOptionOfTheCommandLine
\f2\b >
\f7\i\b0 process
\f3\i0 = 'p'
\f2\b <>
\f9\b0 \

\f8\b \
-q
\f9\b0 Only run part (2) of
\f8\b renee
\f9\b0 , reading a Tcl script from stdin and interpretting it in Tcl interpretter with the
\f8\b macro
\f9\b0 command defined. The output content and files are determined by the Tcl script.\

\f2\b <
\f3\b0 qOptionOfTheCommandLine
\f2\b >
\f7\i\b0 process
\f3\i0 = 'q'
\f2\b <>\
<
\f3\b0 flagForPartialReneeProcessing
\f2\b > int
\f3\b0
\f7\i process
\f3\i0 = 0
\f2\b <>
\f9\b0 \

\f8\b \
-r
\f9\b0 Parse the RTF only, outputting to stdout.\

\f2\b <
\f3\b0 rOptionOfTheCommandLine
\f2\b >
\f7\i\b0 process
\f3\i0 = 'r'
\f2\b <>
\f9\b0 \

\f8\b \
-s
\f9\b0 Construct RTF on stdout, reading an
\f8\b renee -r
\f9\b0 parse (possibly editted) from stdin.\

\f2\b <
\f3\b0 sOptionOfTheCommandLine
\f2\b >
\f7\i\b0 process
\f3\i0 = 's'
\f2\b <>
\f9\b0 \

\f8\b \
-h
\f9\b0 Print the command parameters briefly.\

\f2\b <
\f3\b0 hOptionOfTheCommandLine
\f2\b >
\f3\b0 cprintf(
\f7\i chstderr
\f3\i0 , helpMessage,
\f7\i P0
\f3\i0 )
\f2\b <>
\f9\b0 \

\f8\b \
-c
\f9\b0
\f10\i fontfamily
\f9\i0 Add
\f10\i fontfamily
\f9\i0 to the list of code fonts. See below for RTF parsing. The fontname is abbreviated:\
\pard\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li2520\fi-360\ql\qnatural\pardirnatural
\cf0 (1) Remove all characters except letters and digits:
\f10\i Gilligan Antics-Italic
\f9\i0 becomes
\f10\i GilliganAnticsItalic
\f9\i0 .\
(2) Remove the phrases
\f10\i Bold
\f9\i0 ,
\f10\i Oblique
\f9\i0 ,
\f10\i Italic, Regular
\f9\i0 , and
\f10\i Roman
\f9\i0 (unless the first phrase):
\f10\i GilliganAnticsItalic
\f9\i0 becomes
\f10\i GilliganAntics
\f9\i0 .\
(3) Divide the name into groups of an uppercase letter followed by or zero more lower case letters or digits. At most five characters are retained from the first group, and three characters from each subsequent group:
\f10\i GilliganAntics
\f9\i0 becomes
\f10\i GilliAnt
\f9\i0 .\
\pard\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li2160\ql\qnatural\pardirnatural
\cf0 If no code fonts are specified, the defaults are
\f8\b -c LucidGra -c GillSan -c AppleSym\

\f2 <
\f3\b0 cOptionOfTheCommandLine
\f2\b >\
\pard\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li2160\fi-1440\ql\qnatural\pardirnatural
\cf0
\f7\i\b0 pcodefont
\f3\i0 [
\f7\i npcodefont
\f3\i0 ++] =
\f7\i P
\f3\i0 [0][2] ?
\f7\i P
\f3\i0 [0]+2 :
\f7\i N
\f3\i0 >0 ? (--
\f7\i N
\f3\i0 , *++
\f7\i P
\f3\i0 ) : "GillSan";\

\f7\i helvecode
\f3\i0 =
\f7\i helvecode
\f3\i0
\f6 \uc0\u8744
\f3 strcmp(
\f7\i pcodefont
\f3\i0 [
\f7\i npcodefont
\f3\i0 -1], "Helve")==0\

\f2\b <>\
<
\f3\b0 defaultCodeFonts
\f2\b >\
if
\f3\b0 (
\f7\i npcodefont
\f3\i0 ==0) \{\

\f7\i pcodefont
\f3\i0 [
\f7\i npcodefont
\f3\i0 ++] = "LucidGra";\

\f7\i pcodefont
\f3\i0 [
\f7\i npcodefont
\f3\i0 ++] = "GillSan"; \

\f7\i pcodefont
\f3\i0 [
\f7\i npcodefont
\f3\i0 ++] = "AppleSym";\
\}\

\f7\i pcodefont
\f3\i0 [
\f7\i npcodefont
\f3\i0 ] = 0\

\f2\b <>\
<
\f3\b0 arrayOfCodeFontnames
\f2\b > int
\f3\b0
\f7\i npcodefont
\f3\i0 = 0;
\f2\b chars
\f7\i\b0 pcodefont
\f3\i0 [
\f7\i N
\f3\i0 +1]
\f2\b <>\
\pard\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li2160\ql\qnatural\pardirnatural

\f9\b0 \cf0 \
\pard\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li2160\fi-1440\ql\qnatural\pardirnatural

\f8\b \cf0 -d
\f9\b0
\f10\i debugflags
\f9\i0 Print to stderr debugging traces. These can be used to debug renee or debug macro definitions.\
\pard\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li2520\fi-360\ql\qnatural\pardirnatural

\f8\b \cf0 r
\f9\b0 Show the tokens from the RTF sources during RTF parsing.\

\f8\b m
\f9\b0 Show the macro language parse states during macro language parsing.\

\f8\b M
\f9\b0 Show the calls to the
\f8\b macro
\f9\b0 command.\

\f8\b E
\f9\b0 Show the strings emitted the macro output.\

\f8\b R
\f9\b0 Show the macro recognition/expansion.\

\f8\b Q
\f9\b0 Show the processing of embedded commands while flushing the macro expansions to output files.\

\f8\b *
\f9\b0 Set all debug flags.\

\f2\b <
\f3\b0 dOptionOfTheCommandLine
\f2\b >
\f3\b0 trace("=",
\f7\i P
\f3\i0 [0][2] ?
\f7\i P
\f3\i0 [0]+2 :
\f7\i N
\f3\i0 >0 ? (--
\f7\i N
\f3\i0 , *++
\f7\i P
\f3\i0 ) : "*")
\f2\b <>\
\pard\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li2520\fi-360\ql\qnatural\pardirnatural

\f9\b0 \cf0 \
\pard\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li2160\fi-1440\ql\qnatural\pardirnatural

\f8\b \cf0 -n
\f9\b0
\f10\i max
\f9\i0 Set the maximum number of macro expansions. Once the maximum is reached, subsequent macro calls are replaced with error messages.\

\f2\b <
\f3\b0 nOptionOfTheCommandLine
\f2\b >
\f3\b0 \{\

\f2\b Obj
\f3\b0
\f7\i L
\f3\i0 [] = \{\
Tcl_NewStringObj("macro", -1), \
Tcl_NewStringObj("limit", -1), \
Tcl_NewStringObj(
\f7\i P
\f3\i0 [0][2] ?
\f7\i P
\f3\i0 [0]+2 :
\f7\i N
\f3\i0 >0 ? (--
\f7\i N
\f3\i0 , *++
\f7\i P
\f3\i0 ) : "100", -1), \
0\
\};\

\f2\b Obj
\f3\b0
\f7\i p
\f3\i0 = incr(Tcl_NewListObj(3,
\f7\i L
\f3\i0 ));\
Tcl_EvalObjEx(
\f7\i intr
\f3\i0 ,
\f7\i p
\f3\i0 , TCL_EVAL_DIRECT); decr(
\f7\i p
\f3\i0 );\
\}
\f2\b <>\

\f9\b0 \
\pard\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li2160\fi-1440\ql\qnatural\pardirnatural

\f8\b\fs26 \cf0 -u
\f9\b0
\fs24 Set an unlimitted number of macro expansions. This is the default.\

\f2\b <
\f3\b0 uOptionOfTheCommandLine
\f2\b >
\f3\b0 \{\

\f2\b Obj
\f3\b0
\f7\i L
\f3\i0 [] = \{\
Tcl_NewStringObj("macro", -1), \
Tcl_NewStringObj("unlimitted", -1), \
0\
\};\

\f2\b Obj
\f3\b0
\f7\i p
\f3\i0 = incr(Tcl_NewListObj(2,
\f7\i L
\f3\i0 ));\
Tcl_EvalObjEx(
\f7\i intr
\f3\i0 ,
\f7\i p
\f3\i0 , TCL_EVAL_DIRECT); decr(
\f7\i p
\f3\i0 );\
\}
\f2\b <>\

\f9\b0 \
\pard\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li2160\fi-1440\ql\qnatural\pardirnatural

\f8\b \cf0 -o
\f9\b0
\f10\i folder
\f9\i0 Set the output folder. The default output folder is the working directory (
\f8\b .
\f9\b0 ).\

\f2\b <
\f3\b0 oOptionOfTheCommandLine
\f2\b >
\f3\b0 \{\

\f2\b Obj
\f3\b0
\f7\i L
\f3\i0 [] = \{\
Tcl_NewStringObj("macro", -1), \
Tcl_NewStringObj("output", -1),\
Tcl_NewStringObj(
\f7\i P
\f3\i0 [0][2] ?
\f7\i P
\f3\i0 [0]+2 :
\f7\i N
\f3\i0 >0 ? (--
\f7\i N
\f3\i0 , *++
\f7\i P
\f3\i0 ) : ".", -1), \
0\
\};\

\f2\b Obj
\f3\b0
\f7\i p
\f3\i0 = incr(Tcl_NewListObj(3,
\f7\i L
\f3\i0 ));\
Tcl_EvalObjEx(
\f7\i intr
\f3\i0 ,
\f7\i p
\f3\i0 , TCL_EVAL_DIRECT); decr(
\f7\i p
\f3\i0 );\
\}
\f2\b <>\

\f9\b0 \

\f8\b -D
\f10\i\b0 var
\f9\i0 [=
\f10\i val
\f9\i0 ]
\f10\i
\f9\i0 Define the global Tcl variable
\f10\i var
\f9\i0 before interpretting the Tcl script. If
\f10\i val
\f9\i0 is omitted, the variable is set to 1.\

\f2\b <
\f3\b0 DOptionOfTheCommandLine
\f2\b >
\f3\b0 \{\

\f2\b chars
\f7\i\b0 d
\f3\i0 =
\f7\i P
\f3\i0 [0][2] ?
\f7\i P
\f3\i0 [0]+2 :
\f7\i N
\f3\i0 >0 ? (--
\f7\i N
\f3\i0 , *++
\f7\i P
\f3\i0 ) : "";\

\f2\b char
\f3\b0
\f7\i D
\f3\i0 [strlen(
\f7\i d
\f3\i0 )+1]; strcpy(
\f7\i D
\f3\i0 ,
\f7\i d
\f3\i0 );\

\f2\b chars
\f7\i\b0 Q
\f3\i0 = strchr(
\f7\i D
\f3\i0 , '=');
\f2\b if
\f3\b0 (
\f7\i Q
\f3\i0 ) *
\f7\i Q
\f3\i0 ++ = 0;
\f2\b else
\f3\b0
\f7\i Q
\f3\i0 = "1";\

\f2\b if
\f3\b0 (\'c2Tcl_SetVar(
\f7\i intr
\f3\i0 ,
\f7\i D
\f3\i0 ,
\f7\i Q
\f3\i0 , TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG))\

\f2\b
\f3\b0 cprintf(
\f7\i chstderr
\f3\i0 , "-D%s: %s\\n",
\f7\i D
\f3\i0 , Tcl_GetStringResult(
\f7\i intr
\f3\i0 ));\
\}
\f2\b <>\

\f10\i\b0 \

\f8\i0\b -U
\f10\i\b0 var
\f9\i0 Unset the global variable
\f10\i var
\f9\i0 before interpretting the Tcl script.\

\f2\b <
\f3\b0 UOptionOfTheCommandLine
\f2\b >
\f3\b0 \{\

\f2\b chars
\f7\i\b0 d
\f3\i0 =
\f7\i P
\f3\i0 [0][2] ?
\f7\i P
\f3\i0 [0]+2 :
\f7\i N
\f3\i0 >0 ? (--
\f7\i N
\f3\i0 , *++
\f7\i P
\f3\i0 ) : "";\

\f2\b char
\f3\b0
\f7\i D
\f3\i0 [strlen(
\f7\i d
\f3\i0 )+1]; strcpy(
\f7\i D
\f3\i0 ,
\f7\i d
\f3\i0 );\

\f2\b chars
\f7\i\b0 Q
\f3\i0 = strchr(
\f7\i D
\f3\i0 , '=');
\f2\b if
\f3\b0 (
\f7\i Q
\f3\i0 ) *
\f7\i Q
\f3\i0 ++ = 0;\

\f2\b if
\f3\b0 (\'c2Tcl_UnsetVar(
\f7\i intr
\f3\i0 ,
\f7\i D
\f3\i0 , TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG))\

\f2\b
\f3\b0 cprintf(
\f7\i chstderr
\f3\i0 , "-D%s: %s\\n",
\f7\i D
\f3\i0 , Tcl_GetStringResult(
\f7\i intr
\f3\i0 ));\
\}
\f2\b <>\

\f10\i\b0 \

\f8\i0\b --
\f9\b0 Subsequent parameters are only files even if the parameter looks like any of the above.\

\f2\b <
\f3\b0 doubledashOptionOfTheCommandLine
\f2\b >\
while
\f3\b0 (--
\f7\i N
\f3\i0 >0)
\f7\i document
\f3\i0 [
\f7\i ndocument
\f3\i0 ++] = *++
\f7\i P
\f3\i0 ;\

\f2\b <>\

\f9\b0 \

\f10\i rtffile
\f9\i0 RTF source file. Any number of RTF files can be presented. Each is separately parsed and then concatenating into a single stream which is parsed int the macro language. A dash (-) by itself means the RTF file is stdin. If no files are given, stdin is read for the RTF source.\

\f2\b <
\f3\b0 rtffileOptionOfTheCommandLine
\f2\b >\

\f7\i\b0 document
\f3\i0 [
\f7\i ndocument
\f3\i0 ++] = *
\f7\i P
\f3\i0 ;\

\f2\b <>\
<
\f3\b0 arrayOfDocumentPaths
\f2\b >\
int
\f3\b0
\f7\i ndocument
\f3\i0 = 0,
\f7\i xdocument
\f3\i0 = 0;
\f2\b chars
\f7\i\b0 document
\f3\i0 [
\f7\i N
\f3\i0 +1];\

\f2\b <>\
priv var
\f3\b0
\f2\b Obj
\f3\b0 *
\f7\i included
\f3\i0
\f2\b is
\f3\b0 0;\

\f2\b <
\f3\b0 arrayOfIncludePaths
\f2\b >\
Obj
\f7\i\b0 aincluded
\f3\i0 [
\f7\i N
\f3\i0 +1];
\f7\i included
\f3\i0 =
\f7\i aincluded
\f3\i0 ;\

\f2\b <>
\f3\b0 \

\f2\b <
\f3\b0 defaultRTFsource
\f2\b >\
if
\f3\b0 (
\f7\i ndocument
\f3\i0 ==0)
\f7\i document
\f3\i0 [
\f7\i ndocument
\f3\i0 ++] = "-";\

\f7\i document
\f3\i0 [
\f7\i ndocument
\f3\i0 ] = 0
\f2\b \
<>
\f9\b0 \
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural
\cf0 \

\f8\b renee
\f9\b0 generates output through a number of phases.\
\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\qr\pardirnatural

\f0\b\fs28 \cf0 3 RTF Parsing\
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural

\f8\fs24 \cf0 \
RTF parsing.\
renee
\f9\b0 is only concerned with whether the font of text is one of the declared code fonts, whether a small number of style options, bold, italic, underline, or outlined, and whether subscripted, superscripted, or at the baseline. Only the main body text is read, ignoring footnotes, captions, and other RTF groups. Text not in one of the code fonts (as a Times Roman with the default code fonts) is ignored. Other text styling is ignored. The output of this phase is a Unicode stream with styles attached and baseline markers concatenated from the source RTF files\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\qr\pardirnatural

\f0\b\fs26 \cf0 \
3.1 Document Colours\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f2\fs24 \cf0 \
priv structure
\f3\b0 *
\f2\b Colour
\f3\b0
\f2\b is
\f3\b0 \{\

\f2\b int
\f3\b0
\f7\i red
\f3\i0 ,
\f7\i green
\f3\i0 ,
\f7\i blue
\f3\i0 ,
\f7\i index
\f3\i0 ;
\f2\b Colour
\f3\b0
\f7\i next
\f3\i0 ;\

\f2\b
\f3\b0 \};\

\f2\b var Colour
\f3\b0
\f7\i colours
\f3\i0
\f2\b is
\f3\b0 0;
\f2\b var int
\f3\b0
\f7\i colourIndex
\f3\i0
\f2\b is
\f3\b0 0;\

\f2\b <
\f3\b0 endDocument+
\f2\b >\
while
\f3\b0 (
\f7\i colours
\f3\i0 ) \{\

\f2\b Colour
\f3\b0
\f7\i c
\f3\i0 =
\f7\i colours
\f3\i0 ;
\f7\i colours
\f3\i0 =
\f7\i colours
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 ;\
dispose(
\f7\i c
\f3\i0 );\
\}\

\f7\i colourIndex
\f3\i0 = 0;\

\f2\b <>
\f3\b0 \

\f2\b func Colour
\f3\b0 colour(
\f2\b int
\f3\b0
\f7\i param
\f3\i0 )
\f2\b is
\f3\b0 \{\

\f2\b static struct Colour
\f3\b0
\f7\i black
\f3\i0 = \{0, 0, 0, 0\};\

\f2\b Colour
\f3\b0
\f7\i p
\f3\i0 ,
\f7\i c
\f3\i0 ;
\f2\b for
\f3\b0 (
\f7\i p
\f3\i0 =0,
\f7\i c
\f3\i0 =
\f7\i colours
\f3\i0 ;
\f7\i c
\f3\i0 ;
\f7\i p
\f3\i0 =
\f7\i c
\f3\i0 ,
\f7\i c
\f3\i0 =
\f7\i c
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 ) \{\

\f2\b if
\f3\b0 (
\f7\i c
\f6\i0 \uc0\u8594
\f7\i index
\f3\i0 ==
\f7\i param
\f3\i0 ) \{\

\f2\b if
\f3\b0 (
\f7\i p
\f3\i0 ) \{
\f7\i p
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 =
\f7\i c
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 ;
\f7\i c
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 =
\f7\i colours
\f3\i0 ;
\f7\i colours
\f3\i0 =
\f7\i c
\f3\i0 ;\}\

\f2\b return
\f3\b0
\f7\i c
\f3\i0 ;\
\}\
\}\

\f2\b return
\f3\b0 &
\f7\i black
\f3\i0 ;\
\}\

\f2\b func
\f3\b0
\f2\b void
\f3\b0 colourCreate(
\f2\b void
\f3\b0 )
\f2\b is
\f3\b0 \{\

\f2\b Colour
\f3\b0
\f7\i c
\f3\i0 = heap(
\f2\b struct
\f3\b0
\f2\b Colour
\f3\b0 ); memset(
\f7\i c
\f3\i0 , 0,
\f2\b sizeof
\f3\b0 *
\f7\i c
\f3\i0 );\

\f7\i c
\f6\i0 \uc0\u8594
\f7\i red
\f3\i0 = get("red");
\f7\i c
\f6\i0 \uc0\u8594
\f7\i green
\f3\i0 = get("green");
\f7\i c
\f6\i0 \uc0\u8594
\f7\i blue
\f3\i0 = get("blue");\

\f7\i c
\f6\i0 \uc0\u8594
\f7\i index
\f3\i0 =
\f7\i colourIndex
\f3\i0 ;
\f7\i colourIndex
\f3\i0 += 1;\

\f2\b
\f7\i\b0 c
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 =
\f7\i colours
\f3\i0 ;
\f7\i colours
\f3\i0 =
\f7\i c
\f3\i0 ;\
put("red", 0); put("green", 0); put("blue", 0); \

\f2\b
\f3\b0 \}\

\f2\b \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\qr\pardirnatural

\f0\fs26 \cf0 3.2 Encodings
\f2\fs24 \
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural

\f0 \cf0 \

\f1\b0 Because the encoding identifiers (code page numbers) are the same in each document, encodings are shared amongst documents and not reset with each document.\
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural

\f2\b \cf0 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural
\cf0 priv structure
\f3\b0 *
\f2\b Encoding
\f3\b0
\f2\b is
\f3\b0 \{\

\f2\b chars
\f7\i\b0 name
\f3\i0 ;\

\f2\b Tcl_Encoding
\f3\b0
\f7\i encoding
\f3\i0 ;\

\f2\b Encoding
\f3\b0
\f7\i next
\f3\i0 ;\

\f2\b
\f3\b0 \};\

\f2\b var Encoding
\f3\b0
\f7\i encodings
\f3\i0
\f2\b is
\f3\b0 0;\

\f2\b func
\f3\b0
\f2\b Tcl_Encoding
\f3\b0 codepage(
\f2\b int
\f3\b0
\f7\i cpg
\f3\i0 )
\f2\b is
\f3\b0 \{\

\f2\b char
\f3\b0
\f7\i x
\f3\i0 [50];\

\f2\b switch
\f3\b0 (
\f7\i cpg
\f3\i0 ) \{\

\f2\b case
\f3\b0 37: strcpy(
\f7\i x
\f3\i0 , "ebcdic");
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 819: strcpy(
\f7\i x
\f3\i0 , "iso8859-1");
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 10000: strcpy(
\f7\i x
\f3\i0 , "macRoman");
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 10006: strcpy(
\f7\i x
\f3\i0 , "macGreek");
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 10007: strcpy(
\f7\i x
\f3\i0 , "macCyrillic");
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 10029: strcpy(
\f7\i x
\f3\i0 , "macLatin2");
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 10079: strcpy(
\f7\i x
\f3\i0 , "macIcelandic");
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 10081: strcpy(
\f7\i x
\f3\i0 , "macTurkish");
\f2\b break
\f3\b0 ;\

\f2\b default
\f3\b0 : sprintf(
\f7\i x
\f3\i0 , "cp%d",
\f7\i cpg
\f3\i0 );
\f2\b break
\f3\b0 ;\

\f2\b
\f3\b0 \}\

\f2\b Encoding
\f3\b0
\f7\i p
\f3\i0 ,
\f7\i c
\f3\i0 ;
\f2\b for
\f3\b0 (
\f7\i p
\f3\i0 =0,
\f7\i c
\f3\i0 =
\f7\i encodings
\f3\i0 ;
\f7\i c
\f3\i0 ;
\f7\i p
\f3\i0 =
\f7\i c
\f3\i0 ,
\f7\i c
\f3\i0 =
\f7\i c
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 ) \{\

\f2\b if
\f3\b0 (strcmp(
\f7\i c
\f6\i0 \uc0\u8594
\f7\i name
\f3\i0 ,
\f7\i x
\f3\i0 )==0) \{\

\f2\b if
\f3\b0 (
\f7\i p
\f3\i0 ) \{
\f7\i p
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 =
\f7\i c
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 ;
\f7\i c
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 =
\f7\i encodings
\f3\i0 ;
\f7\i encodings
\f3\i0 =
\f7\i c
\f3\i0 ;\}\

\f2\b return
\f3\b0
\f7\i c
\f6\i0 \uc0\u8594
\f7\i encoding
\f3\i0 ;\

\f2\b
\f3\b0 \}\

\f2\b
\f3\b0 \}\

\f2\b Encoding
\f3\b0
\f7\i e
\f3\i0 = heap(
\f2\b struct
\f3\b0
\f2\b Encoding
\f3\b0 );\

\f2\b
\f7\i\b0 e
\f6\i0 \uc0\u8594
\f7\i name
\f3\i0 = strcpy(alloc(strlen(
\f7\i x
\f3\i0 )+1),
\f7\i x
\f3\i0 );\

\f2\b
\f7\i\b0 e
\f6\i0 \uc0\u8594
\f7\i encoding
\f3\i0 = Tcl_GetEncoding(0,
\f7\i x
\f3\i0 );\

\f2\b if
\f3\b0 (\'c2
\f7\i e
\f6\i0 \uc0\u8594
\f7\i encoding
\f3\i0 )\
error("codepage %d (%s): could not load the encoding",
\f7\i cpg
\f3\i0 ,
\f7\i x
\f3\i0 );\

\f2\b
\f7\i\b0 e
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 =
\f7\i encodings
\f3\i0 ;
\f7\i encodings
\f3\i0 =
\f7\i e
\f3\i0 ;\

\f2\b return
\f3\b0
\f7\i e
\f6\i0 \uc0\u8594
\f7\i encoding
\f3\i0 ;\

\f2\b
\f3\b0 \}\

\f2\b \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\qr\pardirnatural

\f0\fs26 \cf0 3.3 Document Fonts\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f1\b0\fs24 \cf0 \
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural

\f0\b \cf0 renee
\f1\b0 uses abbreviated font names similar to PostScript to avoid nonsense such as whether the font name has spaces or dashes. There is also confusion whether text styles bold and italic should be encoded as the plain font name (such as Helvetica) with control words \\b and \\i, or whether to encode the style in the font name (such as Helvetica Oblique).
\f0\b renee
\f1\b0 recognises common font variation names and treats these as if the corresponding control words were also given.\
\
The codefont names are against family names rather than specific font names. This saves listing all possible font variants on the command line.\
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural

\f2\b \cf0 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural
\cf0 priv structure
\f3\b0 *
\f2\b Font
\f3\b0
\f2\b is
\f3\b0 \{\

\f2\b int
\f3\b0
\f7\i fontindex
\f3\i0 ,
\f7\i bold
\f3\i0 ,
\f7\i italic
\f3\i0 ,
\f7\i uc
\f3\i0 ,
\f7\i cpg
\f3\i0 ,
\f7\i codefont
\f3\i0 ;\

\f2\b chars
\f7\i\b0 longname
\f3\i0 ,
\f7\i familyname
\f3\i0 ,
\f7\i fontname
\f3\i0 ;
\f2\b Font
\f3\b0
\f7\i next
\f3\i0 ;\

\f2\b
\f3\b0 \};\

\f2\b var Font
\f3\b0
\f7\i fonts
\f3\i0
\f2\b is
\f3\b0 0;
\f2\b var int
\f3\b0
\f7\i deff
\f3\i0
\f2\b is
\f3\b0 0;\

\f2\b var chars
\f3\b0 *
\f7\i codefont
\f2\i0\b is
\f3\b0 0;
\f2\b var bool
\f3\b0
\f7\i helvecode
\f2\i0\b is
\f3\b0
\f2\b false
\f3\b0 ;\

\f2\b <
\f3\b0 endDocument+
\f2\b >\
while
\f3\b0 (
\f7\i fonts
\f3\i0 ) \{\

\f2\b Font
\f3\b0
\f7\i f
\f3\i0 =
\f7\i fonts
\f3\i0 ;
\f7\i fonts
\f3\i0 =
\f7\i fonts
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 ;\
dispose(
\f7\i f
\f6\i0 \uc0\u8594
\f7\i longname
\f3\i0 ); dispose(
\f7\i f
\f6\i0 \uc0\u8594
\f7\i familyname
\f3\i0 ); dispose(
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 ); \
dispose(
\f7\i f
\f3\i0 );\
\}\

\f7\i deff
\f3\i0 = 0;\

\f2\b <>
\f3\b0 \

\f2\b func Font
\f3\b0 font(
\f2\b int
\f3\b0
\f7\i param
\f3\i0 )
\f2\b is
\f3\b0 \{\

\f4\i On MacOSX, the default font in TextEdit is Helvetica 12.\
This despite the fact that no font is uglier except Times Roman.\
Perhaps this is why Helvetica and Times Roman are the most\
widely available fonts.\
Yes, this document uses Helvetica, but for transportablility, not\
some perversion of typographic aethestics. There is a reason why\
the default code fonts are what they are.
\f3\i0 \

\f2\b static struct Font
\f3\b0
\f7\i helvetica
\f3\i0 = \{-1, 0, 0, 0, 0, 0,\
"Helvetica", "Helve", "Helve",\
0\};\

\f2\b Font
\f3\b0
\f7\i p
\f3\i0 ,
\f7\i c
\f3\i0 ;
\f2\b for
\f3\b0 (
\f7\i p
\f3\i0 =0,
\f7\i c
\f3\i0 =
\f7\i fonts
\f3\i0 ;
\f7\i c
\f3\i0 ;
\f7\i p
\f3\i0 =
\f7\i c
\f3\i0 ,
\f7\i c
\f3\i0 =
\f7\i c
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 ) \{\

\f2\b if
\f3\b0 (
\f7\i c
\f6\i0 \uc0\u8594
\f7\i fontindex
\f3\i0 ==
\f7\i param
\f3\i0 ) \{\

\f2\b if
\f3\b0 (
\f7\i p
\f3\i0 ) \{
\f7\i p
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 =
\f7\i c
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 ;
\f7\i c
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 =
\f7\i fonts
\f3\i0 ;
\f7\i fonts
\f3\i0 =
\f7\i c
\f3\i0 ;\}\

\f2\b return
\f3\b0
\f7\i c
\f3\i0 ;\
\}\
\}\

\f7\i helvetica
\f3\i0 .
\f7\i codefont
\f3\i0 =
\f7\i helvecode
\f3\i0 ;\

\f2\b return
\f3\b0 &
\f7\i helvetica
\f3\i0 ;\
\}\

\f2\b func
\f3\b0
\f2\b void
\f3\b0 fontCreate(
\f2\b void
\f3\b0 )
\f2\b is
\f3\b0 \{\

\f2\b if
\f3\b0 (get("f")\'b30) \{\

\f2\b Font
\f3\b0
\f7\i f
\f3\i0 = heap(
\f2\b struct
\f3\b0
\f2\b Font
\f3\b0 ); memset(
\f7\i f
\f3\i0 , 0,
\f2\b sizeof
\f3\b0 *
\f7\i f
\f3\i0 );\

\f2\b
\f7\i\b0 f
\f6\i0 \uc0\u8594
\f7\i fontindex
\f3\i0 = get("f");\

\f2\b
\f7\i\b0 f
\f6\i0 \uc0\u8594
\f7\i bold
\f3\i0 = get("b");
\f7\i f
\f6\i0 \uc0\u8594
\f7\i italic
\f3\i0 = get("i");\

\f2\b
\f7\i\b0 f
\f6\i0 \uc0\u8594
\f7\i uc
\f3\i0 = get("uc");
\f7\i f
\f6\i0 \uc0\u8594
\f7\i cpg
\f3\i0 = get("cpg");\

\f2\b
\f7\i\b0 f
\f6\i0 \uc0\u8594
\f7\i next
\f3\i0 =
\f7\i fonts
\f3\i0 ;
\f7\i fonts
\f3\i0 =
\f7\i f
\f3\i0 ;\

\f2\b int
\f3\b0
\f7\i n
\f3\i0 ;
\f2\b chars
\f7\i\b0 s
\f3\i0 = Tcl_GetStringFromObj(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 , &
\f7\i n
\f3\i0 );\

\f2\b
\f7\i\b0 f
\f6\i0 \uc0\u8594
\f7\i longname
\f3\i0 = alloc(
\f7\i n
\f3\i0 +1); strcpy(
\f7\i f
\f6\i0 \uc0\u8594
\f7\i longname
\f3\i0 ,
\f7\i s
\f3\i0 );\

\f2\b
\f7\i\b0 f
\f6\i0 \uc0\u8594
\f7\i familyname
\f3\i0 = alloc(
\f7\i n
\f3\i0 +1);\

\f2\b
\f7\i\b0 f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 = alloc(
\f7\i n
\f3\i0 +1);\

\f2\b int
\f3\b0
\f7\i h, i
\f3\i0 ,
\f7\i j
\f3\i0 ,
\f7\i k
\f3\i0 ,
\f7\i l
\f3\i0 =5;\

\f2\b for
\f3\b0 (
\f7\i h
\f3\i0 =
\f7\i i
\f3\i0 =
\f7\i j
\f3\i0 =0;
\f7\i i
\f3\i0 <
\f7\i n
\f3\i0 ;
\f7\i i
\f3\i0 ++) \{\

\f2\b if
\f3\b0 (strncmp(
\f7\i s
\f3\i0 +
\f7\i i
\f3\i0 , "Bold", 4)==0
\f6 \uc0\u8743
\f3 \'c2islower(
\f7\i s
\f3\i0 [
\f7\i i
\f3\i0 +4])
\f6 \uc0\u8743
\f3
\f7\i l
\f3\i0 ==3) \{\

\f2\b
\f7\i\b0 i
\f3\i0 +=4;
\f7\i f
\f6\i0 \uc0\u8594
\f7\i bold
\f3\i0 =
\f2\b true
\f3\b0 ;\

\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'B';
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'o';
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'l';\

\f2\b
\f3\b0 \}
\f2\b else
\f3\b0
\f2\b if
\f3\b0 (strncmp(
\f7\i s
\f3\i0 +
\f7\i i
\f3\i0 , "Oblique", 7)==0
\f6 \uc0\u8743
\f3 \'c2islower(
\f7\i s
\f3\i0 [
\f7\i i
\f3\i0 +7])
\f6 \uc0\u8743
\f3
\f7\i l
\f3\i0 ==3) \{\

\f2\b
\f7\i\b0 i
\f3\i0 +=7;
\f7\i f
\f6\i0 \uc0\u8594
\f7\i italic
\f3\i0 =
\f2\b true
\f3\b0 ;\

\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'O';
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'b';
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'l';\

\f2\b
\f3\b0 \}
\f2\b else
\f3\b0
\f2\b if
\f3\b0 (strncmp(
\f7\i s
\f3\i0 +
\f7\i i
\f3\i0 , "Italic", 6)==0
\f6 \uc0\u8743
\f3 \'c2islower(
\f7\i s
\f3\i0 [
\f7\i i
\f3\i0 +6])
\f6 \uc0\u8743
\f3
\f7\i l
\f3\i0 ==3) \{\

\f2\b
\f7\i\b0 i
\f3\i0 +=6;
\f7\i f
\f6\i0 \uc0\u8594
\f7\i italic
\f3\i0 =
\f2\b true
\f3\b0 ;\

\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'I';
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 't';
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'a';\

\f2\b
\f3\b0 \}
\f2\b else
\f3\b0
\f2\b if
\f3\b0 (strncmp(
\f7\i s
\f3\i0 +
\f7\i i
\f3\i0 , "Roman", 5)==0
\f6 \uc0\u8743
\f3 \'c2islower(
\f7\i s
\f3\i0 [
\f7\i i
\f3\i0 +5])
\f6 \uc0\u8743
\f3
\f7\i l
\f3\i0 ==3) \{\

\f2\b
\f7\i\b0 i
\f3\i0 +=5;
\f7\i f
\f6\i0 \uc0\u8594
\f7\i bold
\f3\i0 =
\f2\b false
\f3\b0 ;
\f7\i f
\f6\i0 \uc0\u8594
\f7\i italic
\f3\i0 =
\f2\b false
\f3\b0 ;\

\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'R';
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'o';
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'm';\

\f2\b
\f3\b0 \}
\f2\b else
\f3\b0
\f2\b if
\f3\b0 (strncmp(
\f7\i s
\f3\i0 +
\f7\i i
\f3\i0 , "Regular", 7)==0
\f6 \uc0\u8743
\f3 \'c2islower(
\f7\i s
\f3\i0 [
\f7\i i
\f3\i0 +7])
\f6 \uc0\u8743
\f3
\f7\i l
\f3\i0 ==3) \{\

\f2\b
\f7\i\b0 i
\f3\i0 +=7;
\f7\i f
\f6\i0 \uc0\u8594
\f7\i bold
\f3\i0 =
\f2\b false
\f3\b0 ;
\f7\i f
\f6\i0 \uc0\u8594
\f7\i italic
\f3\i0 =
\f2\b false
\f3\b0 ;\

\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'R';
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'e';
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 'g';\

\f2\b
\f3\b0 \}
\f2\b else if
\f3\b0 (isupper(
\f7\i s
\f3\i0 [
\f7\i i
\f3\i0 ])) \{\

\f7\i f
\f6\i0 \uc0\u8594
\f7\i familyname
\f3\i0 [
\f7\i h
\f3\i0 ++] =
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] =
\f7\i s
\f3\i0 [
\f7\i i
\f3\i0 ];
\f7\i k
\f3\i0 =
\f7\i l
\f3\i0 ;
\f7\i l
\f3\i0 = 3;\
\}
\f2\b else
\f3\b0
\f2\b if
\f3\b0 ((islower(
\f7\i s
\f3\i0 [
\f7\i i
\f3\i0 ])
\f6 \uc0\u8744
\f3 isdigit(
\f7\i s
\f3\i0 [
\f7\i i
\f3\i0 ]))
\f6 \uc0\u8743
\f3 --
\f7\i k
\f3\i0 >0) \{\

\f7\i f
\f6\i0 \uc0\u8594
\f7\i familyname
\f3\i0 [
\f7\i h
\f3\i0 ++] =
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] =
\f7\i s
\f3\i0 [
\f7\i i
\f3\i0 ];\
\}\

\f2\b
\f3\b0 \}\

\f2\b
\f7\i\b0 f
\f6\i0 \uc0\u8594
\f7\i familyname
\f3\i0 [
\f7\i h
\f3\i0 ++] = 0;
\f7\i f
\f6\i0 \uc0\u8594
\f7\i familyname
\f3\i0 = Tcl_Realloc(
\f7\i f
\f6\i0 \uc0\u8594
\f7\i familyname
\f3\i0 ,
\f7\i h
\f3\i0 );\

\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 [
\f7\i j
\f3\i0 ++] = 0;
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 = Tcl_Realloc(
\f7\i f
\f6\i0 \uc0\u8594
\f7\i fontname
\f3\i0 ,
\f7\i j
\f3\i0 );\

\f2\b
\f7\i\b0 f
\f6\i0 \uc0\u8594
\f7\i codefont
\f3\i0 =
\f2\b false
\f3\b0 ;\

\f2\b for
\f3\b0 (
\f7\i i
\f3\i0 =0; \'c2
\f7\i f
\f6\i0 \uc0\u8594
\f7\i codefont
\f3\i0
\f6 \uc0\u8743
\f3
\f7\i codefont
\f3\i0 [
\f7\i i
\f3\i0 ];
\f7\i i
\f3\i0 ++) \{\

\f2\b
\f7\i\b0 f
\f6\i0 \uc0\u8594
\f7\i codefont
\f3\i0 = strcmp(
\f7\i f
\f6\i0 \uc0\u8594
\f7\i familyname
\f3\i0 ,
\f7\i codefont
\f3\i0 [
\f7\i i
\f3\i0 ])==0;\

\f2\b
\f3\b0 \}\

\f2\b
\f3\b0 Tcl_SetObjLength(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 , 0);\

\f2\b
\f3\b0 \}\

\f2\b
\f3\b0 put("f", -1);\

\f2\b
\f3\b0 \}\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f1 \cf0 \
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural
\cf0 When a font is applied to a group, some properties of the font are also applied until overridden or a different font is chosen. The easiest thing to do is push a kind of group until the font changes. But subsequent control words would apply to group under the font, but still override the font\'d1this is too complicated for the group data structure. Instead the relevant controls \\
\f4\i x
\f1\i0 are stored in the group as \\
\f4\i x
\f1\i0 and \\#
\f4\i x
\f1\i0 . Applying a font changes the \\
\f4\i x
\f1\i0 only; when the font is changed, the \\#
\f4\i x
\f1\i0 values are used to restore \\
\f4\i x
\f1\i0 . (If the \\
\f4\i x
\f1\i0 controls have been changed since the font, the \\#
\f4\i x
\f1\i0 will have also been updated.)\
\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f3 \cf0
\f2\b <
\f3\b0 mergeGroupAndFontProperties
\f2\b >\

\f3\b0 put("b", get("#b"));\
put("i", get("#i"));\
put("uc", get("#uc"));\
put("cpg", get("#cpg"));\

\f2\b if
\f3\b0 (
\f7\i f
\f6\i0 \uc0\u8594
\f7\i bold
\f3\i0 ) put("b",
\f2\b true
\f3\b0 );\

\f2\b if
\f3\b0 (
\f7\i f
\f6\i0 \uc0\u8594
\f7\i italic
\f3\i0 ) put("i",
\f2\b true
\f3\b0 );\

\f2\b if
\f3\b0 (
\f7\i f
\f6\i0 \uc0\u8594
\f7\i uc
\f3\i0 ) put("uc",
\f7\i f
\f6\i0 \uc0\u8594
\f7\i uc
\f3\i0 );\

\f2\b if
\f3\b0 (
\f7\i f
\f6\i0 \uc0\u8594
\f7\i cpg
\f3\i0 ) put("cpg",
\f7\i f
\f6\i0 \uc0\u8594
\f7\i cpg
\f3\i0 );\

\f2\b <>
\f3\b0 \

\f2\b \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\qr\pardirnatural

\f0\fs26 \cf0 3.4 Document Groups
\f2\fs24 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f1\b0 \cf0 \
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural
\cf0 Most of the things stored in groups are control word values as integers. These are stored in a hash table mapping control words into current integer values, the value as the hash entry
\f0\b ClientData
\f1\b0 . Two string values are font names, accessed through the current font index "f" control word, and the group destination. The destination is special cased as a small string in the group
\f0\b struct
\f1\b0 .\
\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f2\b \cf0 priv structure
\f3\b0 *
\f2\b Group
\f3\b0
\f2\b is
\f3\b0 \{\
controlValueDictionaryField;\

\f2\b
\f3\b0 groupDestinationField;\

\f2\b Group
\f3\b0
\f7\i link
\f3\i0 ;\

\f2\b
\f3\b0 \};\

\f2\b var Group
\f3\b0
\f7\i group
\f3\i0
\f2\b is
\f3\b0 0;\

\f2\b <
\f3\b0 endDocument+
\f2\b >\
while
\f3\b0 (
\f7\i group
\f3\i0 ) \{\

\f2\b Group
\f3\b0
\f7\i inner
\f3\i0 =
\f7\i group
\f3\i0 ;
\f7\i group
\f3\i0 =
\f7\i group
\f6\i0 \uc0\u8594
\f7\i link
\f3\i0 ;\
discardControlValueDictionary;\
discardGroupDestination;\
dispose(
\f7\i inner
\f3\i0 );\
\}\

\f2\b <>
\f3\b0 \

\f2\b <
\f3\b0 beginGroup
\f2\b >
\f3\b0 \{\

\f2\b Group
\f3\b0
\f7\i inner
\f3\i0 = heap(
\f2\b struct
\f3\b0
\f2\b Group
\f3\b0 );\
createControlValueDictionary;\
inheritControlValueDictionaryFromEnclosingGroup;\
initialiseGroupDestination;
\f2\b \

\f3\b0
\f7\i inner
\f6\i0 \uc0\u8594
\f7\i link
\f3\i0 =
\f7\i group
\f3\i0 ;
\f7\i group
\f3\i0 =
\f7\i inner
\f3\i0 ;\
\}
\f2\b <>
\f3\b0 \

\f2\b <
\f3\b0 endGroup
\f2\b >
\f3\b0 \{\

\f2\b Group
\f3\b0
\f7\i inner
\f3\i0 =
\f7\i group
\f3\i0 ;
\f7\i group
\f3\i0 =
\f7\i group
\f6\i0 \uc0\u8594
\f7\i link
\f3\i0 ;\
propagateGroupContentsToOuterGroup;\
discardControlValueDictionary;\
discardGroupDestination;\
dispose(
\f7\i inner
\f3\i0 );\
\}
\f2\b <>
\f3\b0 \
\
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural

\f1 \cf0 The control word values for a group are stored in dictionary (hash table) that maps control name to control value which is an integer. A group inherits control values from the containing group: this is done by copying the containing dictionary to the inner one.\
\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f3 \cf0
\f2\b <
\f3\b0 controlValueDictionaryField
\f2\b >Tcl_HashTable
\f3\b0
\f7\i dict
\f2\i0\b <>
\f3\b0 \

\f2\b <
\f3\b0 createControlValueDictionary
\f2\b >\

\f3\b0 Tcl_InitHashTable(&
\f7\i inner
\f6\i0 \uc0\u8594
\f7\i dict
\f3\i0 , TCL_STRING_KEYS)\

\f2\b <>
\f3\b0 \

\f2\b <
\f3\b0 inheritControlValueDictionaryFromEnclosingGroup
\f2\b >\
if
\f3\b0 (
\f7\i group
\f3\i0 ) \{\

\f2\b Tcl_HashSearch
\f3\b0
\f7\i S
\f3\i0 ;
\f2\b Tcl_HashEntry
\f3\b0 *
\f7\i e
\f3\i0 ;
\f2\b int
\f3\b0
\f7\i n
\f3\i0 ;\

\f2\b for
\f3\b0 (
\f7\i e
\f3\i0 =Tcl_FirstHashEntry(&
\f7\i group
\f6\i0 \uc0\u8594
\f7\i dict
\f3\i0 , &
\f7\i S
\f3\i0 );
\f7\i e
\f3\i0 ;
\f7\i e
\f3\i0 =Tcl_NextHashEntry(&
\f7\i S
\f3\i0 )) \{\

\f2\b Tcl_HashEntry
\f3\b0 *
\f7\i E
\f3\i0 = Tcl_CreateHashEntry(\
&
\f7\i inner
\f6\i0 \uc0\u8594
\f7\i dict
\f3\i0 ,\
Tcl_GetHashKey(&
\f7\i group
\f6\i0 \uc0\u8594
\f7\i dict
\f3\i0 ,
\f7\i e
\f3\i0 ),\
&
\f7\i n
\f3\i0 );\
Tcl_SetHashValue(\

\f7\i E
\f3\i0 ,\
Tcl_GetHashValue(
\f7\i e
\f3\i0 ));\
\}\
\}\

\f2\b <>
\f3\b0 \

\f2\b <
\f3\b0 discardControlValueDictionary
\f2\b >\

\f3\b0 Tcl_DeleteHashTable(&
\f7\i inner
\f6\i0 \uc0\u8594
\f7\i dict
\f3\i0 )
\f2\b \

\f3\b0
\f2\b <>
\f3\b0 \

\f2\b func long
\f3\b0 get(
\f2\b chars
\f3\b0
\f7\i name
\f3\i0 )
\f2\b is
\f3\b0 \{\

\f2\b Tcl_HashEntry
\f3\b0 *
\f7\i e
\f3\i0 =
\f7\i group
\f3\i0 ? Tcl_FindHashEntry(&
\f7\i group
\f6\i0 \uc0\u8594
\f7\i dict
\f3\i0 ,
\f7\i name
\f3\i0 ) : 0;\

\f2\b return
\f3\b0
\f7\i e
\f3\i0 ? (
\f2\b long
\f3\b0 )Tcl_GetHashValue(
\f7\i e
\f3\i0 ) : 0L;\
\}\

\f2\b func void
\f3\b0 put(
\f2\b chars
\f3\b0
\f7\i name
\f3\i0 ,
\f2\b long
\f3\b0
\f7\i value
\f3\i0 )
\f2\b is
\f3\b0 \{\

\f2\b if
\f3\b0 (
\f7\i group
\f3\i0 ) \{\

\f2\b int
\f3\b0
\f7\i n
\f3\i0 ;
\f2\b Tcl_HashEntry
\f3\b0 *
\f7\i e
\f3\i0 = Tcl_CreateHashEntry(&
\f7\i group
\f6\i0 \uc0\u8594
\f7\i dict
\f3\i0 ,
\f7\i name
\f3\i0 , &
\f7\i n
\f3\i0 );\
Tcl_SetHashValue(
\f7\i e
\f3\i0 ,(
\f2\b ClientData
\f3\b0 )
\f7\i value
\f3\i0 );\
\}\
\}\
\
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural

\f1 \cf0 Default is that text in a group has no explicit destination (destination is "") and so it is sent on to the macro parser. A group inherits its containing group destination, unless overridden. At the end of the group, the buffer is added to the containing group if it is the same destination, otherwise, in general, it is discarded: in fact with few exceptions all alternate destinations are discarded. The exceptions are \\upr (unicode pair), \\fonttbl (font table), and \\colortbl (colour table). Unicode destinations are eventually sent on to the macro parser; font and color tables are saved for later reference in the document.\
\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f3 \cf0
\f2\b <
\f3\b0 groupDestinationField
\f2\b >Obj
\f3\b0
\f7\i buffer
\f3\i0 ;
\f2\b char
\f3\b0
\f7\i dest
\f3\i0 [40]
\f2\b <>
\f3\b0 \

\f2\b <
\f7\i\b0 groupdest
\f2\i0\b >
\f3\b0 (
\f7\i group
\f3\i0 ?
\f7\i group
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0 : "")
\f2\b <>
\f3\b0 \

\f2\b <
\f3\b0 initialiseGroupDestination
\f2\b >\

\f7\i\b0 inner
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 = incr(Tcl_NewObj());\

\f2\b if
\f3\b0 (
\f7\i group
\f3\i0 ) \{\
strcpy(
\f7\i inner
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0 ,
\f7\i group
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0 );\

\f2\b
\f3\b0 \}
\f2\b else
\f3\b0 \{\

\f7\i inner
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0 [0] = 0;\
\}
\f2\b \

\f3\b0
\f2\b <>
\f3\b0 \

\f2\b <
\f3\b0 discardGroupDestination
\f2\b >
\f3\b0 \

\f2\b
\f3\b0 decr(
\f7\i inner
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 )
\f2\b \

\f3\b0
\f2\b <>
\f3\b0 \

\f2\b <
\f3\b0 propagateGroupContentsToOuterGroup
\f2\b >\

\f3\b0
\f2\b if
\f3\b0 (\'c2
\f7\i group
\f3\i0
\f6 \uc0\u8744
\f3 strcmp(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0 ,
\f7\i inner
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0 )\'ad0) \{\

\f2\b if
\f3\b0 (strcmp(
\f7\i groupdest
\f3\i0 , "upr")==0) \{\

\f2\b if
\f3\b0 (
\f7\i group
\f3\i0 ) Tcl_AppendObjToObj(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 ,
\f7\i inner
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 );\
\}
\f2\b else if
\f3\b0 (strcmp(
\f7\i groupdest
\f3\i0 , "fonttbl")==0) \{\
fontCreate();\
\}
\f2\b else if
\f3\b0 (strcmp(
\f7\i groupdest
\f3\i0 , "colortbl")==0) \{\
colourCreate();\
\}\
\}\

\f2\b if
\f3\b0 (*
\f7\i inner
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0
\f6 \uc0\u8743
\f3 strcmp(
\f7\i groupdest
\f3\i0 ,
\f7\i inner
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0 )==0) \{\
Tcl_AppendObjToObj(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 ,
\f7\i inner
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 );\
\}\

\f2\b <>
\f3\b0 \

\f2\b <
\f3\b0 destinationControlWord
\f2\b >\

\f3\b0 strcpy(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0 ,
\f7\i tag
\f3\i0 +1)\

\f2\b <>
\f3\b0 \

\f2\b <
\f3\b0 groupDestinationAfterAsterisk
\f2\b >\

\f3\b0
\f4\i A \\* is expected to be followed by a destination, whether
\f11\b renee
\f4\b0 understands\
the destination or not. On the \\*, mark the group dest that a destination\
is expected, and then on the next control word, if it is otherwise unrecognized,\
use that as the destination. Such destinations are the control word prefixed \
with "*".\

\f2\i0\b if
\f3\b0 (strcmp(
\f7\i tag
\f3\i0 , "/*")==0) \{\
strcpy(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0 ,
\f7\i "*"
\f3\i0 );\

\f2\b
\f3\b0 \}
\f2\b else
\f3\b0
\f2\b if
\f3\b0 (strcmp(
\f7\i groupdest
\f3\i0 , "*")==0) \{\

\f7\i group
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0 [0] = '*'; strcpy(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0 +1,
\f7\i tag
\f3\i0 +1);\

\f2\b
\f3\b0 \}\

\f2\b <>
\f3\b0 \

\f2\b <
\f3\b0 ignoreMisplacedAsteriskDestination
\f2\b >\

\f3\b0
\f4\i The previous symbol was a \\* followed by something other than a destination.\
This is an error and resolved by ignoring the group.\

\f3\i0
\f2\b if
\f3\b0 (strcmp(
\f7\i groupdest
\f3\i0 , "*")==0
\f6 \uc0\u8743
\f3 strcmp(
\f7\i tag
\f3\i0 , "/*")\'ad0) \{\
strcpy(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i dest
\f3\i0 , "(ignored)");\
\}\

\f2\b <>
\f3\b0 \

\f2\b <
\f3\b0 saveCharacterToGroupDestinationIfAny
\f2\b >\

\f3\b0
\f4\i The next character was extracted from the document\

\f3\i0
\f4\i If the current group has a destination, save to the group buffer.\
Otherwise fall through to the macro language parser.\

\f2\i0\b if
\f3\b0 (*
\f7\i groupdest
\f3\i0 ) \{\

\f2\b Tcl_UniChar
\f3\b0
\f7\i U
\f3\i0 [1] = \{
\f7\i character
\f3\i0 \};
\f7\i character
\f3\i0 = 0;\

\f2\b
\f3\b0 Tcl_AppendUnicodeToObj(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 ,
\f7\i U
\f3\i0 , 1);\

\f2\b
\f3\b0 \}\

\f2\b <>
\f3\b0 \
\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\qr\pardirnatural

\f0\b\fs26 \cf0 3.5 Document Stream\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f1\b0\fs24 \cf0 \
\pard\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\li720\ql\qnatural\pardirnatural
\cf0 Run through the list of files on the command line, extracting one byte at a time. It is assumed the actual file encoding has one byte per character in an encoding that can be changed at any time; this excludes UTF-8, but given RTF is Microsoft invention and they did not invent UTF-8, this is safe assumption.\
\
Files are openned with binary encoding to extract single bytes. The
\f4\i rtfInputBuffer
\f1\i0 is used to satisfy Tcl interfaces.
\f0\b renee
\f1\b0 immediately extracts the input byte and then ignores the buffer. Within renee it is
\f4\i inputByteBuffer
\f1\i0 , the curent input byte, which is signficant.\
\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f2\b \cf0 <
\f3\b0 RTFParserVariables+
\f2\b >
\f3\b0 \

\f2\b Tcl_Channel
\f3\b0
\f7\i inputChannel
\f3\i0 = 0;\

\f2\b Obj
\f3\b0
\f7\i rtfInputBuffer
\f3\i0 = incr(Tcl_NewObj());\

\f2\b int
\f3\b0
\f7\i inputByteBuffer
\f3\i0 = 0;\

\f2\b <>\

\f3\b0
\f2\b priv var chars
\f3\b0
\f7\i currdoc
\f3\i0
\f2\b is
\f3\b0 "-";\

\f2\b priv var int
\f3\b0
\f7\i currxdoc
\f3\i0
\f2\b is
\f3\b0 0;\

\f2\b priv var int
\f3\b0
\f7\i lp
\f3\i0
\f2\b is
\f3\b0 0;\

\f2\b <
\f3\b0 ensureTheNextDocumentIsOpen
\f2\b >\
for
\f3\b0 (; \'c2
\f7\i inputChannel
\f3\i0
\f6 \uc0\u8743
\f3
\f7\i document
\f3\i0 [
\f7\i xdocument
\f3\i0 ];
\f7\i xdocument
\f3\i0 ++) \{\

\f7\i currxdoc
\f3\i0 =
\f7\i xdocument; currdoc
\f3\i0 =
\f7\i document
\f3\i0 [
\f7\i xdocument
\f3\i0 ];\

\f7\i lp
\f3\i0 = 1;
\f7\i inputByteBuffer
\f3\i0 = 0;\

\f2\b if
\f3\b0 (strcmp(
\f7\i document
\f3\i0 [
\f7\i xdocument
\f3\i0 ], "-")==0) \{\

\f2\b
\f7\i\b0 included
\f3\i0 [
\f7\i xdocument
\f3\i0 ] = incr(Tcl_NewStringObj("(stdin)", -1));\

\f7\i inputChannel
\f3\i0 =
\f7\i chstdin
\f3\i0 ;\

\f2\b
\f3\b0 \}
\f2\b else
\f3\b0 \{\

\f4\i On MacOSX, RTF files with images are bundles with the image files\
and the actual RTF document as a member named TXT.rtf.
\f3\i0 \

\f2\b Obj
\f3\b0
\f7\i pathobj
\f3\i0 = incr(Tcl_NewStringObj(
\f7\i document
\f3\i0 [
\f7\i xdocument
\f3\i0 ], -1));\

\f2\b Tcl_StatBuf
\f3\b0 *
\f7\i st
\f3\i0 = Tcl_AllocStatBuf();\

\f2\b if
\f3\b0 (Tcl_FSStat(
\f7\i pathobj
\f3\i0 ,
\f7\i st
\f3\i0 )==0
\f6 \uc0\u8743
\f3 (
\f7\i st
\f6\i0 \uc0\u8594
\f7\i st_mode
\f3\i0 &S_IFMT)==S_IFDIR) \{\

\f2\b if
\f3\b0 (Tcl_IsShared(
\f7\i pathobj
\f3\i0 )) \{\

\f2\b Obj
\f3\b0
\f7\i t
\f3\i0 = incr(Tcl_DuplicateObj(
\f7\i pathobj
\f3\i0 ));\
decr(
\f7\i pathobj
\f3\i0 );
\f7\i pathobj
\f3\i0 =
\f7\i t
\f3\i0 ;\
\}\

\f2\b
\f3\b0 Tcl_AppendToObj(
\f7\i pathobj
\f3\i0 , "/TXT.rtf", -1);\
\}\

\f2\b
\f3\b0 dispose(
\f7\i st
\f3\i0 );\

\f2\b
\f7\i\b0 inputChannel
\f3\i0 = Tcl_FSOpenFileChannel(
\f7\i intr
\f3\i0 ,
\f7\i pathobj
\f3\i0 , "r", 0);\

\f2\b if
\f3\b0 (
\f7\i inputChannel
\f3\i0 ) \{\

\f2\b
\f3\b0 Tcl_SetChannelOption(0,
\f7\i inputChannel
\f3\i0 , "-encoding", "binary");\

\f2\b
\f3\b0 Tcl_RegisterChannel(
\f7\i intr
\f3\i0 ,
\f7\i inputChannel
\f3\i0 );\

\f7\i included
\f3\i0 [
\f7\i xdocument
\f3\i0 ] = incr(Tcl_FSGetNormalizedPath(
\f7\i intr
\f3\i0 ,
\f7\i pathobj
\f3\i0 ));\

\f2\b if
\f3\b0 (\'c2
\f7\i included
\f3\i0 [
\f7\i xdocument
\f3\i0 ])
\f7\i included
\f3\i0 [
\f7\i xdocument
\f3\i0 ] = incr(
\f7\i pathobj
\f3\i0 );\

\f2\b
\f3\b0 \}
\f2\b else
\f3\b0 \{\

\f2\b
\f3\b0 error("cannot open: %s: %s", Tcl_GetStringResult(
\f7\i intr
\f3\i0 ), *
\f7\i document
\f3\i0 );\
\}\

\f2\b
\f3\b0 decr(
\f7\i pathobj
\f3\i0 );\

\f2\b
\f3\b0 \}\
\}\

\f2\b <>\

\f3\b0
\f2\b <
\f3\b0 endDocument+
\f2\b >\
if
\f3\b0 (
\f7\i inputChannel
\f6\i0 \uc0\u8743
\f7\i inputChannel
\f3\i0 \'ad
\f7\i chstdin
\f3\i0 ) Tcl_UnregisterChannel(
\f7\i intr
\f3\i0 ,
\f7\i inputChannel
\f3\i0 );\

\f2\b
\f7\i\b0 inputChannel
\f3\i0 = 0;\

\f2\b <>
\f3\b0 \

\f2\b \
<
\f7\i\b0 inputByte
\f2\i0\b > (
\f7\i\b0 inputByteBuffer
\f3\i0 ==0\
?
\f7\i inputByteBuffer
\f3\i0 = readInputBuffer(
\f7\i inputChannel
\f3\i0 ,
\f7\i rtfInputBuffer
\f3\i0 )\
:
\f7\i inputByteBuffer\

\f3\i0 )
\f2\b <>\
<
\f3\b0 shiftInputByte
\f2\b >
\f3\b0 (
\f7\i inputByteBuffer
\f3\i0 =0)
\f2\b <>
\f3\b0 \

\f2\b func int
\f3\b0 readInputBuffer(
\f2\b Tcl_Channel
\f3\b0
\f7\i inputChannel
\f3\i0 ,
\f2\b Obj
\f3\b0
\f7\i rtfInputBuffer
\f3\i0 )
\f2\b is
\f3\b0 \{\

\f2\b return
\f3\b0 \'c2
\f7\i inputChannel
\f3\i0 ? EOI\
: Tcl_ReadChars(
\f7\i inputChannel
\f3\i0 ,
\f7\i rtfInputBuffer
\f3\i0 , 1, 0)<1 ? EOS\
: Tcl_GetByteArrayFromObj(
\f7\i rtfInputBuffer
\f3\i0 , 0)[0];\
\}\
\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\qr\pardirnatural

\f0\b\fs26 \cf0 3.6 Character Stream\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f1\b0\fs24 \cf0 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f2\b \cf0 <
\f3\b0 RTFParserVariables+
\f2\b >
\f3\b0 \

\f2\b int
\f3\b0
\f7\i character
\f3\i0 = 0;
\f2\b bool
\f3\b0
\f7\i unicode
\f3\i0 =
\f2\b true
\f3\b0 ;
\f2\b int
\f3\b0
\f7\i lpincr
\f3\i0 = 0;\

\f2\b int
\f3\b0
\f7\i baseline
\f3\i0 = 0\

\f2\b <>\
<
\f3\b0 incrementTheLineNumberIfThePreviousCharacterWasANewLine
\f2\b >
\f3\b0 \

\f2\b
\f7\i\b0 lp
\f3\i0 +=
\f7\i lpincr
\f3\i0 ;
\f7\i lpincr
\f3\i0 = 0\

\f2\b <>\

\f3\b0
\f2\b <
\f3\b0 translateCharacterIntoUnicode
\f2\b >
\f3\b0 \

\f2\b if
\f3\b0 (
\f7\i character
\f3\i0 ==EOS
\f6 \uc0\u8744
\f3
\f7\i character
\f3\i0 ==EOI)
\f7\i unicode
\f3\i0 =
\f2\b true
\f3\b0 ;\

\f2\b if
\f3\b0 (\'c2
\f7\i unicode
\f3\i0 ) \{\

\f2\b Tcl_Encoding
\f3\b0
\f7\i encoding
\f3\i0 = codepage(get("cpg"));\

\f2\b char
\f3\b0
\f7\i src
\f3\i0 [2] = \{
\f7\i character
\f3\i0 , 0\};
\f2\b Tcl_DString
\f3\b0
\f7\i ds
\f3\i0 ; Tcl_DStringInit(&
\f7\i ds
\f3\i0 );\

\f2\b chars
\f7\i\b0 cnv
\f3\i0 = Tcl_ExternalToUtfDString(
\f7\i encoding
\f3\i0 ,
\f7\i src
\f3\i0 , 1, &
\f7\i ds
\f3\i0 );\

\f2\b Tcl_UniChar
\f3\b0
\f7\i t
\f3\i0 ; Tcl_UtfToUniChar(
\f7\i cnv
\f3\i0 , &
\f7\i t
\f3\i0 );\

\f2\b
\f7\i\b0 character
\f3\i0 =
\f7\i t
\f3\i0 ;
\f7\i unicode
\f3\i0 =
\f2\b true
\f3\b0 ;\

\f2\b
\f3\b0 Tcl_DStringFree(&
\f7\i ds
\f3\i0 );\

\f2\b
\f3\b0 \}\

\f2\b <>\

\f3\b0
\f2\b <
\f3\b0 checkIfBufferredCharacters
\f2\b >\

\f4\i\b0 This should only happen after ending a \\upr group.
\f3\i0 \

\f2\b
\f3\b0
\f2\b if
\f3\b0 (
\f7\i character
\f3\i0 ==0
\f6 \uc0\u8743
\f3
\f7\i group
\f3\i0
\f6 \uc0\u8743
\f3 \'c2*
\f7\i groupdest
\f3\i0
\f6 \uc0\u8743
\f3 Tcl_GetCharLength(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 )>0) \{\

\f7\i character
\f3\i0 = Tcl_GetUniChar(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 , 0);\

\f2\b Obj
\f3\b0
\f7\i rest
\f3\i0 = incr(Tcl_GetRange(\

\f7\i group
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 ,\
1,\
Tcl_GetCharLength(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 )-1));\
decr(
\f7\i group
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 );
\f7\i group
\f6\i0 \uc0\u8594
\f7\i buffer
\f3\i0 =
\f7\i rest
\f3\i0 ;\
\}\

\f2\b <>\
\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\qr\pardirnatural

\f0\fs26 \cf0 3.7 Parser\
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f1\b0\fs24 \cf0 \
\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640\ql\qnatural\pardirnatural

\f2\b \cf0 <
\f3\b0 RTFParser
\f2\b >\
while
\f3\b0 (
\f7\i character
\f3\i0 ==0) \{\
RTFParseTraceVariables;\

\f2\b switch
\f3\b0 (
\f7\i inputByte
\f3\i0 ) \{\

\f2\b case
\f3\b0 EOS:
\f2\b case
\f3\b0 EOI:\

\f2\b if
\f3\b0 (
\f7\i group
\f3\i0 ) \{\
strcpy(tag, "END");\

\f2\b
\f3\b0 error("group not closed at end of file.");\

\f2\b
\f7\i\b0 inputByteBuffer
\f3\i0 = 125;\

\f2\b
\f3\b0 \}
\f2\b else
\f3\b0 \{\
strcpy(tag, "EOS");\

\f2\b
\f7\i\b0 character
\f3\i0 =
\f7\i inputByte
\f3\i0 ;\

\f2\b if
\f3\b0 (
\f7\i inputByte
\f3\i0 ==EOS) shiftInputByte;\

\f2\b
\f3\b0 \}\

\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 123:\
strcpy(tag, "BEGIN"); beginGroup; shiftInputByte;\

\f2\b
\f3\b0
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 125:\
strcpy(tag, "END"); endGroup; shiftInputByte;\

\f2\b
\f3\b0
\f2\b break
\f3\b0 ;\

\f2\b case
\f3\b0 '\\\\': \{\

\f2\b char
\f3\b0
\f7\i parameter
\f3\i0 [50];
\f2\b int
\f7\i\b0 i
\f3\i0 ;\

\f2\b
\f3\b0 shiftInputByte;\

\f2\b if
\f3\b0 (
\f7\i inputByte
\f3\i0 ==EOS
\f6 \uc0\u8744
\f3
\f7\i inputByte
\f3\i0 ==EOI) \{\
strcpy(tag, "EOS");\

\f2\b
\f3\b0 error("end of file in rtf keyword.");\

\f2\b
\f7\i\b0 character
\f3\i0 =
\f7\i inputByte
\f3\i0 ;
\f2\b continue
\f3\b0 ;\

\f2\b
\f3\b0 \}
\f2\b else
\f3\b0
\f2\b if
\f3\b0 (isalpha(
\f7\i inputByte
\f3\i0 )) \{\
*tag = '/';\

\f2\b for
\f3\b0 (
\f7\i i
\f3\i0 =1; isalpha(
\f7\i inputByte
\f3\i0 ); shiftInputByte)\

\f2\b if
\f3\b0 (
\f7\i i
\f3\i0 <(
\f2\b sizeof
\f3\b0
\f7\i tag
\f3\i0 )-1)
\f7\i tag
\f3\i0 [
\f7\i i
\f3\i0 ++] =
\f7\i inputByte
\f3\i0 ;\

\f7\i tag
\f3\i0 [
\f7\i i
\f3\i0 ] = 0;
\f7\i i
\f3\i0 = 0;\

\f2\b if
\f3\b0 (
\f7\i inputByte
\f3\i0 =='-') \{\

\f2\b
\f7\i\b0 parameter
\f3\i0 [
\f7\i i
\f3\i0 ++] =
\f7\i inputByte
\f3\i0 ; shiftInputByte;\

\f2\b if
\f3\b0 (
\f7\i inputByte
\f3\i0 ==EOS
\f6 \uc0\u8744
\f3
\f7\i inputByte
\f3\i0 ==EOI)\

\f2\b
\f3\b0 error("end of file in rtf keyword parameter: %s",
\f7\i tag
\f3\i0 );\

\f2\b
\f3\b0 \}\

\f2\b if
\f3\b0 (isdigit(
\f7\i inputByte
\f3\i0 )) \{\

\f2\b
\f7\i\b0 hasparam
\f3\i0 =
\f2\b true
\f3\b0 ;\

\f2\b for
\f3\b0 (; isdigit(
\f7\i inputByte
\f3\i0 ); shiftInputByte)\

\f2\b if
\f3\b0 (
\f7\i i
\f3\i0 <(
\f2\b sizeof
\f3\b0
\f7\i parameter
\f3\i0 )-1)
\f7\i parameter
\f3\i0 [
\f7\i i
\f3\i0 ++] =
\f7\i inputByte
\f3\i0 ;\

\f2\b
\f7\i\b0 parameter
\f3\i0 [
\f7\i i
\f3\i0 ] = 0;
\f7\i param
\f3\i0 = strtol(
.



Relevant Pages

  • Re: input & output in assembly
    ... [As you've not specified OS or assembler, ... using individual character I/O and handling the rest yourself in your ... it finds in that string, ... ENTER key is pressed (maximum buffer size: ...
    (comp.lang.asm.x86)
  • Re: input & output in assembly
    ... [As you've not specified OS or assembler, ... using individual character I/O and handling the rest yourself in your ... it finds in that string, ... ENTER key is pressed (maximum buffer size: ...
    (alt.lang.asm)
  • Re: Word 2004 and random Hidden characters
    ... (that content takes on a 'hidden' character attribute when edited with Word ... that will address this RTF import issue. ... 'clear formatting' doesn't remove the hidden attribute). ... also have white space characters show up as '??' ...
    (microsoft.public.mac.office.word)
  • Re: Word 2004 and random Hidden characters
    ... created RTF with Word 2004, because while Word 2004 supports Unicode, it ... are apparently some passages of text which have the hidden character ... 'clear formatting' doesn't remove the hidden attribute). ... have white space characters show up as '??' ...
    (microsoft.public.mac.office.word)
  • Re: Word 2004 and random Hidden characters
    ... created RTF with Word 2004, because while Word 2004 supports Unicode, it ... are apparently some passages of text which have the hidden character ... 'clear formatting' doesn't remove the hidden attribute). ... Mac, open in Word 2004 and the file appears empty (except the status bar at ...
    (microsoft.public.mac.office.word)