' Program to convert HZ to Big 5, keeping horizontal positions in a line
' Usage: Run this program in QBasic.
' Requirements: Must define the constants (see below) HC.TAB to the file
' "hc.tab", and HC.SUPP.TAB to the file "hc_supp.tab"
' (can be obtained from ifcss.org).
' Restrictions: Longest line of HZ text is 255 bytes.
CONST HC.TAB = "d:\zwdos\prog\hc.tab" ' "c:\hz\wuda\hc.tab", etc.
CONST HC.SUPP.TAB = "d:\zwdos\prog\hc_supp.tab"' "c:\hz\wuda\hc_supp.tab", etc.
' Do not change anything below
DECLARE SUB InitReadTable (f$)
DECLARE SUB FileFin ()
DECLARE FUNCTION FileInit% ()
DECLARE SUB AscLineLink ()
DECLARE SUB AscLineEnd ()
DECLARE SUB ChinLineEnd ()
DECLARE SUB ChinChar ()
DECLARE SUB LineEnd ()
DECLARE SUB Fin ()
DECLARE SUB LineParse ()
DECLARE FUNCTION Init% ()
DECLARE SUB AscToChin ()
DECLARE SUB AscTilde ()
DECLARE SUB ChinToAsc ()
DECLARE FUNCTION CaseAsc% ()
DECLARE FUNCTION CaseChin% ()
DECLARE SUB AscChar ()
'/*----------------------------------------------------------------------
' Convert HZ to Big 5
' by Daniel Chung
' ----------------------------------------------------------------------*/
'/* State of machine while converting a line. */
'/* AM = ASCII, CH = Chinese */
CONST AM = 1
CONST CH = 2
'/* Font. */
CONST ZONESIZE = 94
CONST SYMBOL.BEGIN = 33 'ASC("!")
CONST SYMBOL.END = 42 'ASC(")")
CONST CHAR.BEGIN = 48 'ASC("0")
CONST CHAR.END = 96 + 23 'ASC("w")
CONST BYTE2.BEGIN = 33 'ASC("!")
CONST BYTE2.END = 126 'ASC("~")
'/*----------------------------------------------------------------------
' main: Main.
' ----------------------------------------------------------------------*/
DEFINT A-Z
DIM SHARED filename AS STRING * 80
DIM SHARED str AS STRING * 256 'current string of text
DIM SHARED strlen 'len of non-empty part of text
DIM SHARED x 'current position in string
DIM SHARED outfile AS STRING * 80
DIM SHARED keephoriz 'whether to keep horiz position
DIM SHARED printfreq 'whether use frequent char set
DIM SHARED table(96, 96) AS STRING * 2 'conversion table
'/* init */
IF Init = 0 THEN END
WHILE FileInit = 1
WHILE (NOT EOF(1))
LINE INPUT #1, str
LineParse
WEND
FileFin
WEND
'/* fin */
Fin
END
'/*----------------------------------------------------------------------
' asc_char: ASCII mode -- print character.
' ----------------------------------------------------------------------*/
SUB AscChar
c = ASC(MID$(str, x, 1))
'/* Ignore space and non-printable. */
IF (c <= ASC(" ")) OR (c > 126) THEN
PRINT #2, " ";
ELSE
PRINT #2, CHR$(c);
END IF
END SUB
SUB AscLineEnd
END SUB
SUB AscLineLink
END SUB
'/*----------------------------------------------------------------------
' asc_tilde: ASCII mode -- print "~".
' ----------------------------------------------------------------------*/
SUB AscTilde
IF keephoriz = 1 THEN
PRINT #2, " ~";
ELSE
PRINT #2, "~";
END IF
END SUB
'/*----------------------------------------------------------------------
' asc_to_chin: ASCII mode -- change to Chinese mode.
' ----------------------------------------------------------------------*/
SUB AscToChin
IF keephoriz = 1 THEN
PRINT #2, " ";
END IF
END SUB
'/*----------------------------------------------------------------------
' case_asc: Finite state machine -- ASCII mode.
'
' Return mode, or 0 for end-of-line.
' ----------------------------------------------------------------------*/
FUNCTION CaseAsc
IF MID$(str, x, 2) = "~{" THEN '/* AM -> CH */
AscToChin
x = x + 2
CaseAsc = CH
ELSEIF MID$(str, x, 2) = "~~" THEN '/* "~~" -> "~" */
AscTilde
x = x + 2
CaseAsc = AM
'/* link to next line */
ELSEIF MID$(str, x, 1) = "~" AND x = strlen THEN
AscLineLink
CaseAsc = 0
ELSEIF x >= strlen + 1 THEN '/* end of line */
AscLineEnd
CaseAsc = 0
ELSE '/* ASCII char */
AscChar
x = x + 1
CaseAsc = AM
END IF
END FUNCTION
'*----------------------------------------------------------------------
' case_chin: Finite state machine -- Chinese mode.
' ----------------------------------------------------------------------*/
FUNCTION CaseChin
'/* end of line */
IF MID$(str, x, 2) = "~}" AND x + 1 = strlen THEN
ChinLineEnd
CaseChin = 0
ELSEIF MID$(str, x, 2) = "~}" THEN '/* CH -> AM */
ChinToAsc
x = x + 2
CaseChin = AM
'/* end of line */
ELSEIF (x >= strlen) THEN
ChinLineEnd
CaseChin = 0
ELSE '/* CH char */
ChinChar
x = x + 2
CaseChin = CH
END IF
END FUNCTION
'/*----------------------------------------------------------------------
' chin_char: Chinese mode -- print character.
' ----------------------------------------------------------------------*/
SUB ChinChar
a = ASC(MID$(str, x))
b = ASC(MID$(str, x + 1))
'/* Check valid */
IF ((a < SYMBOL.BEGIN) OR (a > CHAR.END)) THEN
v = 0
ELSEIF (a > SYMBOL.END) AND (a < CHAR.BEGIN) THEN
v = 0
ELSEIF (b < BYTE2.BEGIN) OR (b > BYTE2.END) THEN
v = 0
ELSE
v = 1
END IF
'/* print */
IF v = 1 THEN 'Valid HZ
IF (ASC(table(a - 32, b - 32)) > 0) THEN
PRINT #2, table(a - 32, b - 32); 'Big-Five character
ELSE
PRINT #2, CHR$(&HA1); CHR$(&HBC); 'Square symbol
END IF
ELSE 'Invalid HZ
PRINT #2, CHR$(&HA1); CHR$(&HBC); 'Square symbol
END IF
END SUB
SUB ChinLineEnd
END SUB
'/*----------------------------------------------------------------------
' chin_to_asc: Chinese mode -- change to ASCII mode.
' ----------------------------------------------------------------------*/
SUB ChinToAsc
IF keephoriz = 1 THEN
PRINT #2, " ";
END IF
END SUB
SUB FileFin
CLOSE #1
CLOSE #2
END SUB
FUNCTION FileInit
'/* file */
INPUT "name of input file (. to end): ", filename
IF LEFT$(filename, 1) = "." THEN
FileInit = 0
GOTO FileInit.exit
END IF
OPEN filename FOR INPUT AS #1
'/* output */
INPUT "name of output file: ", outfile
OPEN outfile FOR OUTPUT AS #2
FileInit = 1
FileInit.exit:
END FUNCTION
SUB Fin
END SUB
'/*----------------------------------------------------------------------
' init: Initialise.
' ----------------------------------------------------------------------*/
FUNCTION Init
'/* parameters */
INPUT "keep horizontal positions (1 or 0): ", keephoriz
INPUT "prefer frequently-used character set (1 or 0): ", printfreq
'/* read table */
PRINT "reading conversion table ..."
InitReadTable (HC.TAB)
'/* read supplementary table */
PRINT "reading supplementary conversion table ..."
InitReadTable (HC.SUPP.TAB)
'/* corrections of symbols */
table(ASC("!") - 32, ASC("$") - 32) = CHR$(&HA1) + CHR$(&H45)
table(ASC("#") - 32, ASC(";") - 32) = CHR$(&HA1) + CHR$(&H46)
table(ASC("#") - 32, ASC("{") - 32) = CHR$(&HA1) + CHR$(&H61)
table(ASC("#") - 32, ASC("|") - 32) = CHR$(&HA1) + CHR$(&H55)
table(ASC("#") - 32, ASC("}") - 32) = CHR$(&HA1) + CHR$(&H62)
table(ASC("#") - 32, 34 - 32) = CHR$(&HA1) + CHR$(&HAA)
table(ASC("#") - 32, ASC("$") - 32) = CHR$(&HA2) + CHR$(&H44)
'/* corrections of characters */
table(ASC("H") - 32, ASC("~") - 32) = CHR$(&HB0) + CHR$(&HD1)
table(ASC("g") - 32, ASC("[") - 32) = CHR$(&HA4) + CHR$(&H5C)
table(ASC("C") - 32, ASC("4") - 32) = CHR$(&HBB) + CHR$(&HF2)
table(ASC("X") - 32, ASC(":") - 32) = CHR$(&HE2) + CHR$(&HE9)
table(ASC("l") - 32, ASC("r") - 32) = CHR$(&HE9) + CHR$(&HA5)
Init = 1
END FUNCTION
SUB InitReadTable (f$)
OPEN f$ FOR INPUT AS #3
WHILE NOT EOF(3)
LINE INPUT #3, s$
IF MID$(s$, 1, 1) <> "#" THEN
a = ASC(MID$(s$, 1, 1)) - 128 - 32
b = ASC(MID$(s$, 2, 1)) - 128 - 32
IF ASC(table(a, b)) = 0 THEN table(a, b) = MID$(s$, 3, 2)
'less-often character set?
IF printfreq = 1 AND ASC(table(a, b)) > 200 THEN
FOR i = 3 TO LEN(s$) - 1 STEP 2
IF ASC(MID$(s$, i, 1)) <= 200 THEN
table(a, b) = MID$(s$, i, 2)
GOTO InitReadTable.brk
END IF
NEXT i
END IF
InitReadTable.brk:
END IF
WEND
CLOSE #3
END SUB
SUB LineEnd
PRINT ".";
PRINT #2, ""
END SUB
'*----------------------------------------------------------------------
' line_print: Finite state machine for printing line.
' ----------------------------------------------------------------------*/
SUB LineParse
x = 1
s = AM 'local variable: "state"
'/* string length */
strlen = 0
FOR i = LEN(str) TO 1 STEP -1
IF MID$(str, i, 1) <> " " THEN
strlen = i
GOTO brk
END IF
NEXT i
brk:
'/* loop */
WHILE s <> 0
SELECT CASE s
CASE AM
s = CaseAsc
CASE CH
s = CaseChin
END SELECT
WEND
LineEnd
END SUB
' Program to convert Big 5 to HZ, keeping horizontal positions in a line
' Usage: Run this program in QBasic.
' Guidelines: In order to keep horizontal positions:
' A line must start in ASCII mode.
' A line starting in Chinese must start with 2 ASCII spaces.
' ASCII<->Chinese mode switch must leave 2 ASCII spaces.
' "~" must be preceded by an ASCII space in ASCII mode.
' Requirements: Must define the constants (see below) HC.TAB to the file
' "hc.tab", and HC.SUPP.TAB to the file "hc_supp.tab"
' (can be obtained from ifcss.org).
' Restrictions: Longest line of Big 5 text is 255 bytes.
CONST HC.TAB = "d:\zwdos\prog\hc.tab" ' "c:\hz\wuda\hc.tab", etc.
CONST HC.SUPP.TAB = "d:\zwdos\prog\hc_supp.tab" ' "c:\hz\wuda\hc_supp.tab", etc.
' Do not change anything below
DECLARE SUB InitReadTable (f$)
DECLARE SUB FileFin ()
DECLARE FUNCTION FileInit% ()
DECLARE SUB AscLineEnd ()
DECLARE SUB ChinLineEnd ()
DECLARE SUB ChinChar ()
DECLARE SUB LineEnd ()
DECLARE SUB Fin ()
DECLARE SUB LineParse ()
DECLARE FUNCTION Init% ()
DECLARE SUB AscToChin ()
DECLARE SUB AscTilde ()
DECLARE SUB ChinToAsc ()
DECLARE FUNCTION CaseAsc% ()
DECLARE FUNCTION CaseChin% ()
DECLARE SUB AscChar ()
'/*----------------------------------------------------------------------
' Convert Big 5 to HZ
' by Daniel Chung
' ----------------------------------------------------------------------*/
'/* State of machine while converting a line. */
'/* AM = ASCII, CH = Chinese */
CONST AM = 1
CONST CH = 2
'/* Font. */
CONST ZONESIZE = 94
CONST BYTE1.BEGIN = &HA1
CONST BYTE1.END = &HFE
CONST BYTE2A.BEGIN = &H40
CONST BYTE2A.END = &H7E
CONST BYTE2B.BEGIN = &HA1
CONST BYTE2B.END = &HFE
'/*----------------------------------------------------------------------
' main: Main.
' ----------------------------------------------------------------------*/
DEFINT A-Z
DIM SHARED filename AS STRING * 80
DIM SHARED str AS STRING * 256 'current string of text
DIM SHARED strlen 'len of non-empty part of text
DIM SHARED x 'current position in string
DIM SHARED link, printlink 'whether link to next line
DIM SHARED outfile AS STRING * 80
DIM SHARED keephoriz 'whether to keep horiz position
'conversion table
DIM SHARED tableA(96, 64) AS STRING * 2
DIM SHARED tableB(96, 96) AS STRING * 2
'/* init */
IF Init = 0 THEN END
WHILE FileInit = 1
WHILE (NOT EOF(1))
LINE INPUT #1, str
LineParse
WEND
FileFin
WEND
'/* fin */
Fin
END
'/*----------------------------------------------------------------------
' asc_char: ASCII mode -- print character.
' ----------------------------------------------------------------------*/
SUB AscChar
c = ASC(MID$(str, x, 1))
d = ASC(MID$(str, x + 1, 1))
'/* Ignore space and non-printable. */
IF (c <= ASC(" ")) OR (c > 126) THEN
PRINT #2, " ";
ELSE
PRINT #2, CHR$(c);
END IF
END SUB
SUB AscLineEnd
END SUB
'/*----------------------------------------------------------------------
' asc_tilde: ASCII mode -- print "~".
' ----------------------------------------------------------------------*/
SUB AscTilde
PRINT #2, "~~";
END SUB
'/*----------------------------------------------------------------------
' asc_to_chin: ASCII mode -- change to Chinese mode.
' ----------------------------------------------------------------------*/
SUB AscToChin
PRINT #2, "~{";
END SUB
'/*----------------------------------------------------------------------
' case_asc: Finite state machine -- ASCII mode.
'
' Return mode, or 0 for end-of-line.
' ----------------------------------------------------------------------*/
FUNCTION CaseAsc
'/* AM -> CH */
IF MID$(str, x, 2) = " " AND ASC(MID$(str, x + 2, 1)) >= 128 THEN
IF keephoriz THEN
AscToChin
x = x + 2
CaseAsc = CH
ELSE
AscChar
x = x + 1
CaseAsc = AM
END IF
ELSEIF ASC(MID$(str, x, 1)) >= 128 THEN '/* AM -> CH */
AscToChin
CaseAsc = CH
ELSEIF MID$(str, x, 2) = " ~" THEN '/* " ~" -> "~~" */
IF keephoriz THEN
AscTilde
x = x + 2
ELSE
AscChar
x = x + 1
END IF
CaseAsc = AM
ELSEIF MID$(str, x, 1) = "~" THEN '/* "~" -> "~~" */
AscTilde
x = x + 1
CaseAsc = AM
ELSEIF x >= strlen + 1 THEN '/* end of line */
AscLineEnd
CaseAsc = 0
ELSE '/* ASCII char */
AscChar
x = x + 1
CaseAsc = AM
END IF
END FUNCTION
'*----------------------------------------------------------------------
' case_chin: Finite state machine -- Chinese mode.
' ----------------------------------------------------------------------*/
FUNCTION CaseChin
'/* CH -> AM */
IF MID$(str, x, 2) = " " THEN
ChinToAsc
IF keephoriz THEN x = x + 2
CaseChin = AM
ELSEIF ASC(MID$(str, x, 1)) < 128 THEN
ChinToAsc
CaseChin = AM
'/* end of line */
ELSEIF (x >= strlen) THEN
ChinLineEnd
CaseChin = 0
ELSE '/* CH char */
ChinChar
x = x + 2
CaseChin = CH
END IF
END FUNCTION
'/*----------------------------------------------------------------------
' chin_char: Chinese mode -- print character.
' ----------------------------------------------------------------------*/
SUB ChinChar
A = ASC(MID$(str, x))
b = ASC(MID$(str, x + 1))
'/* Check valid */
IF ((A < BYTE1.BEGIN) OR (A > BYTE1.END)) THEN
v = 0
ELSEIF (b < BYTE2A.BEGIN) OR (b > BYTE2B.END) THEN
v = 0
ELSEIF (b > BYTE2A.END) AND (b < BYTE2A.BEGIN) THEN
v = 0
ELSE
v = 1
END IF
'/* print */
IF v = 1 AND b <= BYTE2A.END THEN 'Big-Five character
c = A - BYTE1.BEGIN + 1
d = b - BYTE2A.BEGIN + 1
IF (ASC(tableA(c, d)) > 0) THEN
PRINT #2, tableA(c, d); 'HZ character
ELSE
PRINT #2, "!u"; 'Square symbol
END IF
ELSEIF v = 1 AND b <= BYTE2B.END THEN 'Big-Five character
c = A - BYTE1.BEGIN + 1
d = b - BYTE2B.BEGIN + 1
IF (ASC(tableB(c, d)) > 0) THEN
PRINT #2, tableB(c, d); 'HZ character
ELSE
PRINT #2, "!u"; 'Square symbol
END IF
ELSE 'Invalid Big-Five character
PRINT #2, tableA(1, 1); 'Square symbol
END IF
END SUB
SUB ChinLineEnd
END SUB
'/*----------------------------------------------------------------------
' chin_to_asc: Chinese mode -- change to ASCII mode.
' ----------------------------------------------------------------------*/
SUB ChinToAsc
PRINT #2, "~}";
END SUB
SUB FileFin
CLOSE #1
CLOSE #2
END SUB
FUNCTION FileInit
FileInit = 1
FileInit.exit:
END FUNCTION
SUB Fin
END SUB
'/* read table */
PRINT "reading conversion table ..."
InitReadTable (HC.TAB)
'/* read supplementary table */
PRINT "reading supplementary conversion table ..."
InitReadTable (HC.SUPP.TAB)
'/* corrections of symbols */
'/* or to make multiple symbol conversion firm */
tableA(&HA1 - BYTE1.BEGIN + 1, &H45 - BYTE2A.BEGIN + 1) = "!$"
tableA(&HA1 - BYTE1.BEGIN + 1, &H4F - BYTE2A.BEGIN + 1) = "!$"
tableA(&HA2 - BYTE1.BEGIN + 1, &H44 - BYTE2A.BEGIN + 1) = "#$"
tableA(&HA3 - BYTE1.BEGIN + 1, &H4E - BYTE2A.BEGIN + 1) = "&+"
tableA(&HA3 - BYTE1.BEGIN + 1, &H53 - BYTE2A.BEGIN + 1) = "&0"
tableA(&HA3 - BYTE1.BEGIN + 1, &H55 - BYTE2A.BEGIN + 1) = "&2"
'/* correction of character */
tableA(&HA4 - BYTE1.BEGIN + 1, &H5C - BYTE2A.BEGIN + 1) = "g["
'/* to make multiple character conversion firm */
tableA(&HC6 - BYTE1.BEGIN + 1, &H50 - BYTE2A.BEGIN + 1) = "<n"
tableA(&HA4 - BYTE1.BEGIN + 1, &H54 - BYTE2A.BEGIN + 1) = "H}"
tableB(&HB0 - BYTE1.BEGIN + 1, &HD1 - BYTE2B.BEGIN + 1) = "2N"
tableB(&HB5 - BYTE1.BEGIN + 1, &HDB - BYTE2B.BEGIN + 1) = "Vx"
tableB(&HBB - BYTE1.BEGIN + 1, &HF2 - BYTE2B.BEGIN + 1) = "wa"
Init = 1
END FUNCTION
SUB InitReadTable (f$)
OPEN f$ FOR INPUT AS #3
WHILE NOT EOF(3)
LINE INPUT #3, s$
IF MID$(s$, 1, 1) <> "#" THEN
'/* HZ */
A = ASC(MID$(s$, 1, 1)) - 128
b = ASC(MID$(s$, 2, 1)) - 128
'/* dawu */
FOR I = 3 TO LEN(s$) - 1 STEP 2
c = ASC(MID$(s$, I, 1)) - BYTE1.BEGIN + 1
d = ASC(MID$(s$, I + 1, 1))
IF (d >= BYTE2A.BEGIN) AND (d <= BYTE2A.END) THEN
d = d - BYTE2A.BEGIN + 1
IF ASC(tableA(c, d)) = 0 THEN
tableA(c, d) = CHR$(A) + CHR$(b)
END IF
ELSEIF (d >= BYTE2B.BEGIN) AND (d <= BYTE2B.END) THEN
d = d - BYTE2B.BEGIN + 1
IF ASC(tableB(c, d)) = 0 THEN
tableB(c, d) = CHR$(A) + CHR$(b)
END IF
END IF
NEXT I
END IF
WEND
CLOSE #3
END SUB
SUB LineEnd
PRINT ".";
PRINT #2, ""
END SUB
'*----------------------------------------------------------------------
' line_print: Finite state machine for printing line.
' ----------------------------------------------------------------------*/
SUB LineParse
x = 1
s = AM 'local variable: "state"
'/* string length */
strlen = 0
FOR I = LEN(str) TO 1 STEP -1
IF MID$(str, I, 1) <> " " THEN
strlen = I
GOTO brk
END IF
NEXT I