summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/uptexdir
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2011-08-14 14:23:26 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2011-08-14 14:23:26 +0000
commiteeefc6bc7d0b3af828a0c623ff63020b19d3bdcd (patch)
treebba70e0540f6b6149b1e29c5c5ff9615a6924636 /Build/source/texk/web2c/uptexdir
parent9ab7c0f8a5cfedd0f440ee28479755646a521f3f (diff)
upTeX and e-upTeX (preliminary)
git-svn-id: svn://tug.org/texlive/trunk@23549 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/uptexdir')
-rw-r--r--Build/source/texk/web2c/uptexdir/am/uptex.am86
-rw-r--r--Build/source/texk/web2c/uptexdir/kanji.c364
-rw-r--r--Build/source/texk/web2c/uptexdir/kanji.h58
-rw-r--r--Build/source/texk/web2c/uptexdir/uptex-m.ch1209
-rw-r--r--Build/source/texk/web2c/uptexdir/uptex.defines48
-rw-r--r--Build/source/texk/web2c/uptexdir/uptexextra.c11
-rw-r--r--Build/source/texk/web2c/uptexdir/uptexextra.h25
7 files changed, 1801 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/uptexdir/am/uptex.am b/Build/source/texk/web2c/uptexdir/am/uptex.am
new file mode 100644
index 00000000000..b231964f896
--- /dev/null
+++ b/Build/source/texk/web2c/uptexdir/am/uptex.am
@@ -0,0 +1,86 @@
+## texk/web2c/uptexdir/am/uptex.am: Makefile fragment for upTeX.
+##
+## Copyright (C) 2011 Peter Breitenlohner <tex-live@tug.org>
+## You may freely use, modify and/or distribute this file.
+
+uptex_cppflags = $(PTEXENC_INCLUDES) $(AM_CPPFLAGS)
+
+## libukanji.a for upTeX and e-upTeX
+##
+EXTRA_LIBRARIES += libukanji.a
+libukanji_a_SOURCES = uptexdir/kanji.c uptexdir/kanji.h
+libukanji_a_CPPFLAGS = $(uptex_cppflags)
+
+## upTeX
+##
+if UPTEX
+bin_PROGRAMS += uptex
+endif UPTEX
+EXTRA_PROGRAMS += uptex
+
+uptex_CPPFLAGS = $(uptex_cppflags)
+
+# With --enable-ipc, upTeX may need to link with -lsocket.
+uptex_LDADD = libukanji.a $(pproglib) $(PTEXENC_LIBS) $(LDADD) $(ipc_socketlibs)
+
+# upTeX C sources
+uptex_c_h = uptexini.c uptex0.c uptexcoerce.h uptexd.h
+nodist_uptex_SOURCES = $(uptex_c_h) uptex-pool.c uptexdir/ptex_version.h uptexdir/uptex_version.h
+dist_uptex_SOURCES = uptexdir/uptexextra.c uptexdir/uptexextra.h
+
+# We must create uptexd.h and uptexdir/*ptex_version.h before building the uptex_OBJECTS.
+uptex_prereq = uptexd.h uptexdir/ptex_version.h uptexdir/uptex_version.h
+$(uptex_OBJECTS): $(uptex_prereq)
+
+$(uptex_c_h): uptex-web2c
+ @$(web2c) uptex
+uptex-web2c: uptex.p $(web2c_texmf) uptexdir/uptex.defines
+ @$(web2c) uptex
+
+uptex-pool.c: uptex.pool uptexd.h $(makecpool_stamp)
+ $(makecpool) uptex >$@ || rm -f $@
+
+# Tangling upTeX
+uptex.p uptex.pool: uptex-tangle
+ @$(texmf_tangle) uptex uptex
+uptex-tangle: tangle$(EXEEXT) uptex.web uptex.ch tangle-sh
+ @$(texmf_tangle) uptex uptex
+
+# Extract ptex version
+uptexdir/ptex_version.h: ptexdir/ptex-base.ch
+ $(MKDIR_P) uptexdir
+ grep '^@d pTeX_version_string==' $(srcdir)/ptexdir/ptex-base.ch \
+ | sed "s/^.*'-/#define PTEX_VERSION \"/;s/'.*$$/\"/" >$@
+
+# Extract uptex version
+uptexdir/uptex_version.h: uptexdir/uptex-m.ch
+ $(MKDIR_P) uptexdir
+ grep '^@d upTeX_version_string==' $(srcdir)/uptexdir/uptex-m.ch \
+ | sed "s/^.*'-/#define UPTEX_VERSION \"/;s/'.*$$/\"/" >$@
+
+# Generate uptex.web
+uptex.web: tie$(EXEEXT) $(uptex_web_srcs)
+ $(tie) -m uptex.web $(uptex_web_srcs)
+uptex_web_srcs = \
+ tex.web \
+ tex.ch
+
+# Generate uptex.ch
+uptex.ch: tie$(EXEEXT) uptex.web $(uptex_ch_srcs)
+ $(tie) -c uptex.ch uptex.web $(uptex_ch_srcs)
+uptex_ch_srcs = \
+ ptexdir/ptex-base.ch \
+ uptexdir/uptex-m.ch \
+ $(uptex_ch_synctex) \
+ tex-binpool.ch
+
+EXTRA_DIST += $(uptex_web_srcs) $(uptex_ch_srcs) uptexdir/uptex.defines
+
+DISTCLEANFILES += $(nodist_uptex_SOURCES) uptex.web uptex.ch uptex-web2c \
+ uptex.p uptex.pool uptex-tangle
+
+## =============
+
+upTeX.w: uptex.p
+ $(tie) -m upTeX.w uptex.web uptex.ch
+
diff --git a/Build/source/texk/web2c/uptexdir/kanji.c b/Build/source/texk/web2c/uptexdir/kanji.c
new file mode 100644
index 00000000000..5e46647ef06
--- /dev/null
+++ b/Build/source/texk/web2c/uptexdir/kanji.c
@@ -0,0 +1,364 @@
+/*
+ * KANJI Code conversion routines.
+ * (for ptex only)
+ */
+
+#include "kanji.h"
+
+#define CS_TOKEN_FLAG 0x1FFFFFFF
+#define CJK_CHAR_LIMIT 0x1000000
+#define CJK_TOKEN_FLAG 0xFFFFFF
+#define KCAT_KANJI 16
+#define KCAT_HANGUL 19
+
+/* m: for debug */
+integer check_kanji (integer c,integer m)
+{
+ if (c > CS_TOKEN_FLAG) return 0;
+ if (is_internalUPTEX()) {
+ if ((c & CJK_TOKEN_FLAG) < CJK_CHAR_LIMIT) {
+ if (XXHi(c)==0) return 1;
+ else if (XXHi(c)>=KCAT_KANJI && XXHi(c)<=KCAT_HANGUL) return 2;
+ }
+ } else {
+ if ((XHi(c)==0) &&
+ iskanji1(Hi(c)) && iskanji2(Lo(c))) {
+ if (XXHi(c)==0) return 1;
+ else if (XXHi(c)>=KCAT_KANJI && XXHi(c)<=KCAT_HANGUL) return 2;
+ }
+ }
+ if (0 <= c && c <= 255) return -1; /* ascii without catcode */
+ return 0; /* ascii with catcode */
+}
+
+boolean is_kanji(integer c)
+{
+ return (iskanji1(Hi(c)) && iskanji2(Lo(c)));
+}
+
+boolean is_char_ascii(integer c)
+{
+ return (0 <= c && c < 0x100);
+}
+
+boolean is_wchar_ascii(integer c)
+{
+ return (!is_char_ascii(c) && !is_kanji(c));
+}
+
+boolean ismultiprn(integer c)
+{
+ int i, j;
+
+ for (i=2; i<=4; i++) for (j=1; j<=i; j++) {
+ if (ismultichr(i,j,c)) return true;
+ }
+ return false;
+}
+
+integer calc_pos(integer c)
+{
+ unsigned char c1, c2;
+
+ if(c>=0 && c<=255) return(c);
+ c1 = Hi(c);
+ c2 = Lo(c);
+
+ c1 = (c1 % 4) * 64; /* c1 = 0, 64, 128, 192 */
+ c2 = c2 % 64; /* c2 = 0..63 */
+ return(c1 + c2); /* ret = 0..255 */
+}
+
+/* Ref. http://www.unicode.org/Public/UNIDATA/Blocks.txt */
+static long ucs_range[]={
+ 0x0000, /* Basic Latin 0x00 */
+ 0x0080, /* Latin-1 Supplement 0x01 */
+ 0x0100, /* Latin Extended-A 0x02 */
+ 0x0180, /* Latin Extended-B 0x03 */
+ 0x0250, /* IPA Extensions 0x04 */
+ 0x02B0, /* Spacing Modifier Letters 0x05 */
+ 0x0300, /* Combining Diacritical Marks 0x06 */
+ 0x0370, /* Greek and Coptic 0x07 */
+ 0x0400, /* Cyrillic 0x08 */
+ 0x0500, /* Cyrillic Supplement 0x09 */
+ 0x0530, /* Armenian 0x0a */
+ 0x0590, /* Hebrew 0x0b */
+ 0x0600, /* Arabic 0x0c */
+ 0x0700, /* Syriac 0x0d */
+ 0x0750, /* Arabic Supplement 0x0e */
+ 0x0780, /* Thaana 0x0f */
+ 0x07C0, /* NKo 0x10 */
+ 0x0800, /* Samaritan 0x11 */
+ 0x0900, /* Devanagari 0x12 */
+ 0x0980, /* Bengali 0x13 */
+ 0x0A00, /* Gurmukhi 0x14 */
+ 0x0A80, /* Gujarati 0x15 */
+ 0x0B00, /* Oriya 0x16 */
+ 0x0B80, /* Tamil 0x17 */
+ 0x0C00, /* Telugu 0x18 */
+ 0x0C80, /* Kannada 0x19 */
+ 0x0D00, /* Malayalam 0x1a */
+ 0x0D80, /* Sinhala 0x1b */
+ 0x0E00, /* Thai 0x1c */
+ 0x0E80, /* Lao 0x1d */
+ 0x0F00, /* Tibetan 0x1e */
+ 0x1000, /* Myanmar 0x1f */
+ 0x10A0, /* Georgian 0x20 */
+ 0x1100, /* Hangul Jamo 0x21 */
+ 0x1200, /* Ethiopic 0x22 */
+ 0x1380, /* Ethiopic Supplement 0x23 */
+ 0x13A0, /* Cherokee 0x24 */
+ 0x1400, /* Unified Canadian Aboriginal Syllabics 0x25 */
+ 0x1680, /* Ogham 0x26 */
+ 0x16A0, /* Runic 0x27 */
+ 0x1700, /* Tagalog 0x28 */
+ 0x1720, /* Hanunoo 0x29 */
+ 0x1740, /* Buhid 0x2a */
+ 0x1760, /* Tagbanwa 0x2b */
+ 0x1780, /* Khmer 0x2c */
+ 0x1800, /* Mongolian 0x2d */
+ 0x18B0, /* Unified Canadian Aboriginal Syllabics Extended 0x2e */
+ 0x1900, /* Limbu 0x2f */
+ 0x1950, /* Tai Le 0x30 */
+ 0x1980, /* New Tai Lue 0x31 */
+ 0x19E0, /* Khmer Symbols 0x32 */
+ 0x1A00, /* Buginese 0x33 */
+ 0x1A20, /* Tai Tham 0x34 */
+ 0x1B00, /* Balinese 0x35 */
+ 0x1B80, /* Sundanese 0x36 */
+ 0x1C00, /* Lepcha 0x37 */
+ 0x1C50, /* Ol Chiki 0x38 */
+ 0x1CD0, /* Vedic Extensions 0x39 */
+ 0x1D00, /* Phonetic Extensions 0x3a */
+ 0x1D80, /* Phonetic Extensions Supplement 0x3b */
+ 0x1DC0, /* Combining Diacritical Marks Supplement 0x3c */
+ 0x1E00, /* Latin Extended Additional 0x3d */
+ 0x1F00, /* Greek Extended 0x3e */
+ 0x2000, /* General Punctuation 0x3f */
+ 0x2070, /* Superscripts and Subscripts 0x40 */
+ 0x20A0, /* Currency Symbols 0x41 */
+ 0x20D0, /* Combining Diacritical Marks for Symbols 0x42 */
+ 0x2100, /* Letterlike Symbols 0x43 */
+ 0x2150, /* Number Forms 0x44 */
+ 0x2190, /* Arrows 0x45 */
+ 0x2200, /* Mathematical Operators 0x46 */
+ 0x2300, /* Miscellaneous Technical 0x47 */
+ 0x2400, /* Control Pictures 0x48 */
+ 0x2440, /* Optical Character Recognition 0x49 */
+ 0x2460, /* Enclosed Alphanumerics 0x4a */
+ 0x2500, /* Box Drawing 0x4b */
+ 0x2580, /* Block Elements 0x4c */
+ 0x25A0, /* Geometric Shapes 0x4d */
+ 0x2600, /* Miscellaneous Symbols 0x4e */
+ 0x2700, /* Dingbats 0x4f */
+ 0x27C0, /* Miscellaneous Mathematical Symbols-A 0x50 */
+ 0x27F0, /* Supplemental Arrows-A 0x51 */
+ 0x2800, /* Braille Patterns 0x52 */
+ 0x2900, /* Supplemental Arrows-B 0x53 */
+ 0x2980, /* Miscellaneous Mathematical Symbols-B 0x54 */
+ 0x2A00, /* Supplemental Mathematical Operators 0x55 */
+ 0x2B00, /* Miscellaneous Symbols and Arrows 0x56 */
+ 0x2C00, /* Glagolitic 0x57 */
+ 0x2C60, /* Latin Extended-C 0x58 */
+ 0x2C80, /* Coptic 0x59 */
+ 0x2D00, /* Georgian Supplement 0x5a */
+ 0x2D30, /* Tifinagh 0x5b */
+ 0x2D80, /* Ethiopic Extended 0x5c */
+ 0x2DE0, /* Cyrillic Extended-A 0x5d */
+ 0x2E00, /* Supplemental Punctuation 0x5e */
+ 0x2E80, /* CJK Radicals Supplement 0x5f */
+ 0x2F00, /* Kangxi Radicals 0x60 */
+ 0x2FF0, /* Ideographic Description Characters 0x61 */
+ 0x3000, /* CJK Symbols and Punctuation 0x62 */
+ 0x3040, /* Hiragana 0x63 */
+ 0x30A0, /* Katakana 0x64 */
+ 0x3100, /* Bopomofo 0x65 */
+ 0x3130, /* Hangul Compatibility Jamo 0x66 */
+ 0x3190, /* Kanbun 0x67 */
+ 0x31A0, /* Bopomofo Extended 0x68 */
+ 0x31C0, /* CJK Strokes 0x69 */
+ 0x31F0, /* Katakana Phonetic Extensions 0x6a */
+ 0x3200, /* Enclosed CJK Letters and Months 0x6b */
+ 0x3300, /* CJK Compatibility 0x6c */
+ 0x3400, /* CJK Unified Ideographs Extension A 0x6d */
+ 0x4DC0, /* Yijing Hexagram Symbols 0x6e */
+ 0x4E00, /* CJK Unified Ideographs 0x6f */
+ 0xA000, /* Yi Syllables 0x70 */
+ 0xA490, /* Yi Radicals 0x71 */
+ 0xA4D0, /* Lisu 0x72 */
+ 0xA500, /* Vai 0x73 */
+ 0xA640, /* Cyrillic Extended-B 0x74 */
+ 0xA6A0, /* Bamum 0x75 */
+ 0xA700, /* Modifier Tone Letters 0x76 */
+ 0xA720, /* Latin Extended-D 0x77 */
+ 0xA800, /* Syloti Nagri 0x78 */
+ 0xA830, /* Common Indic Number Forms 0x79 */
+ 0xA840, /* Phags-pa 0x7a */
+ 0xA880, /* Saurashtra 0x7b */
+ 0xA8E0, /* Devanagari Extended 0x7c */
+ 0xA900, /* Kayah Li 0x7d */
+ 0xA930, /* Rejang 0x7e */
+ 0xA960, /* Hangul Jamo Extended-A 0x7f */
+ 0xA980, /* Javanese 0x80 */
+ 0xAA00, /* Cham 0x81 */
+ 0xAA60, /* Myanmar Extended-A 0x82 */
+ 0xAA80, /* Tai Viet 0x83 */
+ 0xABC0, /* Meetei Mayek 0x84 */
+ 0xAC00, /* Hangul Syllables 0x85 */
+ 0xD7B0, /* Hangul Jamo Extended-B 0x86 */
+ 0xD800, /* High Surrogates 0x87 */
+ 0xDB80, /* High Private Use Surrogates 0x88 */
+ 0xDC00, /* Low Surrogates 0x89 */
+ 0xE000, /* Private Use Area 0x8a */
+ 0xF900, /* CJK Compatibility Ideographs 0x8b */
+ 0xFB00, /* Alphabetic Presentation Forms 0x8c */
+ 0xFB50, /* Arabic Presentation Forms-A 0x8d */
+ 0xFE00, /* Variation Selectors 0x8e */
+ 0xFE10, /* Vertical Forms 0x8f */
+ 0xFE20, /* Combining Half Marks 0x90 */
+ 0xFE30, /* CJK Compatibility Forms 0x91 */
+ 0xFE50, /* Small Form Variants 0x92 */
+ 0xFE70, /* Arabic Presentation Forms-B 0x93 */
+ 0xFF00, /* Halfwidth and Fullwidth Forms 0x94 */
+ 0xFFF0, /* Specials 0x95 */
+ 0x10000, /* Linear B Syllabary 0x96 */
+ 0x10080, /* Linear B Ideograms 0x97 */
+ 0x10100, /* Aegean Numbers 0x98 */
+ 0x10140, /* Ancient Greek Numbers 0x99 */
+ 0x10190, /* Ancient Symbols 0x9a */
+ 0x101D0, /* Phaistos Disc 0x9b */
+ 0x10280, /* Lycian 0x9c */
+ 0x102A0, /* Carian 0x9d */
+ 0x10300, /* Old Italic 0x9e */
+ 0x10330, /* Gothic 0x9f */
+ 0x10380, /* Ugaritic 0xa0 */
+ 0x103A0, /* Old Persian 0xa1 */
+ 0x10400, /* Deseret 0xa2 */
+ 0x10450, /* Shavian 0xa3 */
+ 0x10480, /* Osmanya 0xa4 */
+ 0x10800, /* Cypriot Syllabary 0xa5 */
+ 0x10840, /* Imperial Aramaic 0xa6 */
+ 0x10900, /* Phoenician 0xa7 */
+ 0x10920, /* Lydian 0xa8 */
+ 0x10A00, /* Kharoshthi 0xa9 */
+ 0x10A60, /* Old South Arabian 0xaa */
+ 0x10B00, /* Avestan 0xab */
+ 0x10B40, /* Inscriptional Parthian 0xac */
+ 0x10B60, /* Inscriptional Pahlavi 0xad */
+ 0x10C00, /* Old Turkic 0xae */
+ 0x10E60, /* Rumi Numeral Symbols 0xaf */
+ 0x11080, /* Kaithi 0xb0 */
+ 0x12000, /* Cuneiform 0xb1 */
+ 0x12400, /* Cuneiform Numbers and Punctuation 0xb2 */
+ 0x13000, /* Egyptian Hieroglyphs 0xb3 */
+ 0x1D000, /* Byzantine Musical Symbols 0xb4 */
+ 0x1D100, /* Musical Symbols 0xb5 */
+ 0x1D200, /* Ancient Greek Musical Notation 0xb6 */
+ 0x1D300, /* Tai Xuan Jing Symbols 0xb7 */
+ 0x1D360, /* Counting Rod Numerals 0xb8 */
+ 0x1D400, /* Mathematical Alphanumeric Symbols 0xb9 */
+ 0x1F000, /* Mahjong Tiles 0xba */
+ 0x1F030, /* Domino Tiles 0xbb */
+ 0x1F100, /* Enclosed Alphanumeric Supplement 0xbc */
+ 0x1F200, /* Enclosed Ideographic Supplement 0xbd */
+ 0x20000, /* CJK Unified Ideographs Extension B 0xbe */
+ 0x2A700, /* CJK Unified Ideographs Extension C 0xbf */
+ 0x2F800, /* CJK Compatibility Ideographs Supplement 0xc0 */
+ 0x30000, /* reserved 0xc1 */
+ 0x40000, /* reserved 0xc2 */
+ 0x50000, /* reserved 0xc3 */
+ 0x60000, /* reserved 0xc4 */
+ 0x70000, /* reserved 0xc5 */
+ 0x80000, /* reserved 0xc6 */
+ 0x90000, /* reserved 0xc7 */
+ 0xA0000, /* reserved 0xc8 */
+ 0xB0000, /* reserved 0xc9 */
+ 0xC0000, /* reserved 0xca */
+ 0xD0000, /* reserved 0xcb */
+ 0xE0000, /* Tags 0xcc */
+ 0xE0100, /* Variation Selectors Supplement 0xcd */
+ 0xF0000, /* Supplementary Private Use Area-A 0xce */
+ 0x100000, /* Supplementary Private Use Area-B 0xcf */
+ /* Value over 0x10FFFF is illegal under Unicode,
+ They are for some special use. *** experimental *** */
+ 0x110000, /* Reserved 0xd0 */
+ 0x120000, /* Reserved 0xd1 */
+ 0x130000, /* Reserved 0xd2 */
+ 0x140000, /* Reserved 0xd3 */
+ 0x150000, /* Reserved 0xd4 */
+ 0x160000, /* Reserved 0xd5 */
+ 0x170000, /* Reserved 0xd6 */
+ 0x180000, /* Reserved 0xd7 */
+ 0x190000, /* Reserved 0xd8 */
+ 0x1A0000, /* Reserved 0xd9 */
+ 0x1B0000, /* Reserved 0xda */
+ 0x1C0000, /* Reserved 0xdb */
+ 0x1D0000, /* Reserved 0xdc */
+ 0x1E0000, /* Reserved 0xdd */
+ 0x1F0000, /* Reserved 0xde */
+ 0x200000, /* Reserved 0xdf */
+ 0x210000, /* Reserved 0xe0 */
+ 0x220000, /* Reserved 0xe1 */
+ CJK_CHAR_LIMIT
+};
+
+#define NUCS_RANGE (sizeof(ucs_range)/sizeof(ucs_range[0]))
+
+/* Return i, which satisfies a[i] <= x < a[i+1]. */
+/* 'i' is serached between left <= i <= right. */
+/* If no i satisfies such condition, return left-1. */
+/* [Okumura et al.] An algorithm encyclopedia in Java, p.236. */
+static int
+binary_search (long x, long *a, int left, int right)
+{
+ right++;
+ while (left < right) {
+ int mid = (left + right) / 2;
+ if (a[mid] <= x ) left = mid + 1;
+ else right = mid;
+ }
+ return left - 1;
+}
+
+#define FULLWIDTH_DIGIT_0 0xFF10
+#define FULLWIDTH_DIGIT_9 0xFF19
+#define FULLWIDTH_CAPITAL_A 0xFF21
+#define FULLWIDTH_CAPITAL_Z 0xFF3A
+#define FULLWIDTH_SMALL_A 0xFF41
+#define FULLWIDTH_SMALL_Z 0xFF5A
+#define HALFWIDTH_KATAKANA_WO 0xFF66
+#define HALFWIDTH_KATAKANA_SMALL_TSU 0xFF6F
+#define HALFWIDTH_KATAKANA_A 0xFF71
+#define HALFWIDTH_KATAKANA_N 0xFF9D
+
+integer kcatcodekey(integer c)
+{
+ if (is_internalUPTEX()) {
+ if ( (FULLWIDTH_DIGIT_0 <=c && c<=FULLWIDTH_DIGIT_9 )
+ || (FULLWIDTH_CAPITAL_A<=c && c<=FULLWIDTH_CAPITAL_Z)
+ || (FULLWIDTH_SMALL_A <=c && c<=FULLWIDTH_SMALL_Z ) )
+ return 0xFE;
+ if ( (HALFWIDTH_KATAKANA_WO <=c && c<=HALFWIDTH_KATAKANA_SMALL_TSU )
+ || (HALFWIDTH_KATAKANA_A <=c && c<=HALFWIDTH_KATAKANA_N ) )
+ return 0xFF;
+ return binary_search((long)c, ucs_range, 0, NUCS_RANGE-1);
+ } else {
+ return Hi(toDVI(c));
+ }
+}
+
+integer multilenbuffchar(integer c)
+{
+ c=toBUFF(c);
+ if (BYTE1(c)) return 4;
+ if (BYTE2(c)) return 3;
+ if (BYTE3(c)) return 2;
+ if (BYTE4(c)) return 1;
+ return 0;
+}
+
+/* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME */
+/* Temporary fix for functions still missing in the ptexenc library. */
+boolean is_internalUPTEX(void) { return false; }
+boolean ismultichr (int length, int nth, int c) { return false; }
+/* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME */
diff --git a/Build/source/texk/web2c/uptexdir/kanji.h b/Build/source/texk/web2c/uptexdir/kanji.h
new file mode 100644
index 00000000000..a1b5328041c
--- /dev/null
+++ b/Build/source/texk/web2c/uptexdir/kanji.h
@@ -0,0 +1,58 @@
+/*
+ kanji.h: Handling 2byte char, and so on.
+*/
+#ifndef KANJI_H
+#define KANJI_H
+#include "cpascal.h"
+#include <ptexenc/ptexenc.h>
+#include <ptexenc/unicode.h>
+#ifdef eupTeX
+#define getintone(w) ((w).cint1)
+#define setintone(w,a) ((w).cint1=(a))
+#endif
+
+#define KANJI
+
+/* functions */
+#define XXHi(x) BYTE1(x)
+#define XHi(x) BYTE2(x)
+#define Hi(x) BYTE3(x)
+#define Lo(x) BYTE4(x)
+
+extern integer check_kanji (integer c, integer m);
+#define checkkanji check_kanji
+extern boolean is_kanji (integer c);
+#define iskanji is_kanji
+extern boolean is_char_ascii (integer c);
+#define ischarascii is_char_ascii
+extern boolean is_wchar_ascii (integer c);
+#define iswcharascii is_wchar_ascii
+extern boolean ismultiprn (integer c);
+extern integer calc_pos (integer c);
+#define calcpos calc_pos
+extern integer kcatcodekey (integer c);
+extern integer multilenbuffchar (integer c);
+#define setptexencuptex() set_enc_string("utf8", "uptex");
+
+/* number of rest of multi-char for kcode_pos */
+#define nrestmultichr(x) ( (x)!=0 ? ((x) / 8) + 2 - ((x) % 8) : -1 )
+
+#ifndef PRESERVE_PUTC
+#undef putc
+#define putc(c,fp) putc2(c,fp)
+#endif /* !PRESERVE_PUTC */
+
+#if defined(UPBIBTEX) || defined(BIBTEX)
+#define inputline2(fp,buff,pos,size,ptr) input_line2(fp,buff,pos,size,ptr)
+#else
+#define inputline2(fp,buff,pos,size) input_line2(fp,buff,pos,size,NULL)
+#endif
+
+/* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME */
+/* Temporary fix for functions still missing in the ptexenc library. */
+extern boolean is_internalUPTEX(void);
+#define isinternalUPTEX is_internalUPTEX
+extern boolean ismultichr (int length, int nth, int c);
+/* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME */
+
+#endif /* not KANJI_H */
diff --git a/Build/source/texk/web2c/uptexdir/uptex-m.ch b/Build/source/texk/web2c/uptexdir/uptex-m.ch
new file mode 100644
index 00000000000..b9f1b76911b
--- /dev/null
+++ b/Build/source/texk/web2c/uptexdir/uptex-m.ch
@@ -0,0 +1,1209 @@
+% This is a change file for upTeX u0.30
+% By Takuji Tanaka.
+%
+% (02/26/2007) TTK upTeX u0.01
+% (03/18/2007) TTK upTeX u0.03
+% (04/08/2007) TTK upTeX u0.05
+% (04/15/2007) TTK upTeX u0.06
+% (05/13/2007) TTK upTeX u0.07
+% (05/28/2007) TTK upTeX u0.08
+% (06/16/2007) TTK upTeX u0.09
+% (07/28/2007) TTK upTeX u0.10
+% (08/07/2007) TTK upTeX u0.11
+% (08/25/2007) TTK upTeX u0.12
+% (09/15/2007) TTK upTeX u0.13
+% (09/25/2007) TTK upTeX u0.14
+% (10/18/2007) TTK upTeX u0.15
+% (11/10/2007) TTK upTeX u0.16
+% (11/13/2007) TTK upTeX u0.17
+% (12/08/2007) TTK upTeX u0.18
+% (12/26/2007) TTK upTeX u0.19
+% (01/12/2008) TTK upTeX u0.20
+% (03/13/2008) TTK upTeX u0.21
+% (08/03/2008) TTK upTeX u0.22
+% (09/04/2008) TTK upTeX u0.23
+% (10/18/2008) TTK upTeX u0.24
+% (12/13/2008) TTK upTeX u0.25
+% (02/21/2009) TTK upTeX u0.26
+% (03/12/2009) TTK upTeX u0.27
+% (08/23/2009) TTK upTeX u0.28
+% (01/31/2010) TTK upTeX u0.29
+% (04/10/2010) TTK upTeX u0.30
+
+@x upTeX: banner
+ {printed when p\TeX\ starts}
+@y
+ {printed when p\TeX\ starts}
+@#
+@d upTeX_version_string=='-u0.30' {current up\TeX\ version}
+@#
+@d upTeX_version==pTeX_version_string,upTeX_version_string
+@d upTeX_banner=='This is upTeX, Version 3.1415926',upTeX_version
+@d upTeX_banner_k==upTeX_banner
+ {printed when up\TeX\ starts}
+@z
+
+@x upTeX: banner
+@d banner==pTeX_banner
+@d banner_k==pTeX_banner_k
+@y
+@d banner==upTeX_banner
+@d banner_k==upTeX_banner_k
+@z
+
+@x
+@!KANJI_code=0..65535; {sixteen-bit numbers}
+@y
+@!KANJI_code=0..@"FFFFFF; {0..0x10FFFF: Unicode, 0x110000..0xFFFFFF: special}
+@z
+
+@x
+@!trick_buf2:array[0..ssup_error_line] of 0..2; {pTeX: buffer for KANJI}
+@!kcode_pos: 0..2; {pTeX: denotes whether first byte or second byte of KANJI}
+@y
+@!trick_buf2:array[0..ssup_error_line] of 0..@'24; {pTeX: buffer for KANJI}
+@!kcode_pos: 0..@'24; {pTeX: denotes whether first byte or second byte of KANJI
+ 1..2:2byte-char, 11..13:3byte-char, 21..24:4byte-char}
+@!kcp: 0..@'24; {temporary kcode_pos}
+@z
+
+@x
+procedure print_ln; {prints an end-of-line}
+@y
+procedure print_ln; {prints an end-of-line}
+var @!ii: integer;
+@z
+
+@x
+ if kcode_pos=1 then begin wterm(' '); wlog(' '); end;
+@y
+ if nrestmultichr(kcode_pos)>0 then
+ for ii:=0 to nrestmultichr(kcode_pos)-1 do
+ begin wterm(' '); wlog(' '); end;
+@z
+
+@x
+log_only: begin if kcode_pos=1 then wlog(' ');
+@y
+log_only: begin
+ if nrestmultichr(kcode_pos)>0 then
+ for ii:=0 to nrestmultichr(kcode_pos)-1 do wlog(' ');
+@z
+
+@x
+term_only: begin if kcode_pos=1 then wterm(' ');
+@y
+term_only: begin
+ if nrestmultichr(kcode_pos)>0 then
+ for ii:=0 to nrestmultichr(kcode_pos)-1 do wterm(' ');
+@z
+
+@x
+if kcode_pos=1 then kcode_pos:=2
+@y
+if (kcode_pos=1)or((kcode_pos>=@'11)and(kcode_pos<=@'12))
+ or((kcode_pos>=@'21)and(kcode_pos<=@'23)) then incr(kcode_pos)
+@z
+
+@x
+ begin kcode_pos:=1;
+@y
+ begin
+ if (ismultichr(4,1,xchr[s])) then kcode_pos:=@'21
+ else if (ismultichr(3,1,xchr[s])) then kcode_pos:=@'11
+ else kcode_pos:=1;
+@z
+
+@x
+ if file_offset>=max_print_line-1 then
+@y
+ if file_offset>=max_print_line-nrestmultichr(kcode_pos) then
+@z
+
+@x
+ if term_offset>=max_print_line-1 then
+@y
+ if term_offset>=max_print_line-nrestmultichr(kcode_pos) then
+@z
+
+@x
+@d min_quarterword=0 {smallest allowable value in a |quarterword|}
+@d max_quarterword=255 {largest allowable value in a |quarterword|}
+@d min_halfword==-@"FFFFFFF {smallest allowable value in a |halfword|}
+@d max_halfword==@"FFFFFFF {largest allowable value in a |halfword|}
+@y
+@d min_quarterword=0 {smallest allowable value in a |quarterword|}
+@d max_quarterword=@"FFFF {largest allowable value in a |quarterword|}
+@d min_halfword=0 {smallest allowable value in a |halfword|}
+@d max_halfword=@"3FFFFFFF {largest allowable value in a |halfword|}
+@d max_cjk_val=@"1000000 {to separate wchar and kcatcode}
+@z
+
+@x
+@d xspace_ptr(#) == info(#+space_offset)
+@y
+@d xspace_ptr(#) == info(#+space_offset)
+@d read_sixteenx(#)==begin #:=fbyte;
+ if #>255 then abort;
+ fget; #:=#*@'400+fbyte;
+ end
+@z
+
+@x
+@d kanji=16 {kanji}
+@d kana=17 {hiragana, katakana, alphabet}
+@d other_kchar=18 {kanji codes}
+@d max_char_code=18 {largest catcode for individual characters}
+@y
+@d not_cjk=15 {is not cjk characters}
+@d kanji=16 {kanji}
+@d kana=17 {hiragana, katakana, alphabet}
+@d other_kchar=18 {cjk symbol codes}
+@d hangul=19 {hangul codes}
+@d max_char_code=19 {largest catcode for individual characters}
+@z
+
+@x
+@d math_comp=left_right+1 {component of formula ( \.{\\mathbin}, etc.~)}
+@y
+@d kchar_num=left_right+1 {cjk character specified numerically ( \.{\\kchar} )}
+@d math_comp=kchar_num+1 {component of formula ( \.{\\mathbin}, etc.~)}
+@z
+
+@x
+@d math_given=char_given+1 {math code defined by \.{\\mathchardef}}
+@y
+@d kchar_given=char_given+1 {cjk character code defined by \.{\\kchardef}}
+@d math_given=kchar_given+1 {math code defined by \.{\\mathchardef}}
+@z
+
+@x
+@d max_command=set_auto_spacing {the largest command code seen at |big_switch|}
+@y
+@d set_enable_cjk_token=set_auto_spacing+1 {set cjk mode ( \.{\\enablecjktoken}, \.{\\disablecjktoken}, \.{\\forcecjktoken} )}
+@d max_command=set_enable_cjk_token {the largest command code seen at |big_switch|}
+@z
+
+@x
+@d cat_code_base=auto_xspacing_code+1
+@y
+@d enable_cjk_token_code=auto_xspacing_code+1
+@d cat_code_base=enable_cjk_token_code+1
+@z
+
+@x
+@d auto_xspacing==equiv(auto_xspacing_code)
+@y
+@d auto_xspacing==equiv(auto_xspacing_code)
+@d enable_cjk_token==equiv(enable_cjk_token_code)
+@z
+
+@x
+eqtb[auto_xspacing_code]:=eqtb[cat_code_base];
+@y
+eqtb[auto_xspacing_code]:=eqtb[cat_code_base];
+eqtb[enable_cjk_token_code]:=eqtb[cat_code_base];
+@z
+
+@x
+@t\hskip10pt@>kcat_code(@"20+1):=other_kchar; {1 ku}
+@t\hskip10pt@>kcat_code(@"20+2):=other_kchar; {2 ku}
+@+@t\1@>for k:=3 to 6 do kcat_code(@"20+k):=kana; {3 ku ... 6 ku}
+@+@t\1@>for k:=7 to 8 do kcat_code(@"20+k):=other_kchar; {7 ku ... 8 ku}
+@+@t\1@>for k:=16 to 84 do kcat_code(@"20+k):=kanji; {16 ku ... 84 ku}
+{ $\.{@@"20}+|k| = |kcatcodekey|(|fromKUTEN|(|HILO|(k,1))$ }
+@y
+if (isinternalUPTEX) then begin
+ { default: other_kchar }
+ @t\hskip10pt@>kcat_code(@"0):=not_cjk;
+ @t\hskip10pt@>kcat_code(@"21):=hangul; { Hangul Jamo }
+ @+@t\1@>for k:=@"5F to @"61 do kcat_code(k):=kanji; { CJK Radicals Supplement .. Ideographic Description Characters }
+ @+@t\1@>for k:=@"63 to @"64 do kcat_code(k):=kana; { Hiragana, Katakana }
+ @t\hskip10pt@>kcat_code(@"65):=kanji; { Bopomofo }
+ @t\hskip10pt@>kcat_code(@"66):=hangul; { Hangul Compatibility Jamo }
+ @+@t\1@>for k:=@"67 to @"69 do kcat_code(k):=kanji; { Kanbun .. CJK Strokes }
+ @t\hskip10pt@>kcat_code(@"6A):=kana; { Katakana Phonetic Extensions }
+ @t\hskip10pt@>kcat_code(@"6D):=kanji; { CJK Unified Ideographs Extension A }
+ @t\hskip10pt@>kcat_code(@"6F):=kanji; { CJK Unified Ideographs }
+ @t\hskip10pt@>kcat_code(@"7F):=hangul; { Hangul Jamo Extended-A }
+ @t\hskip10pt@>kcat_code(@"85):=hangul; { Hangul Syllables }
+ @t\hskip10pt@>kcat_code(@"86):=hangul; { Hangul Jamo Extended-B }
+ @t\hskip10pt@>kcat_code(@"8B):=kanji; { CJK Compatibility Ideographs }
+ { @t\hskip10pt@>kcat_code(@"94):=other_kchar; Halfwidth and Fullwidth Forms }
+ @t\hskip10pt@>kcat_code(@"BE):=kanji; { CJK Unified Ideographs Extension B }
+ @t\hskip10pt@>kcat_code(@"BF):=kanji; { CJK Unified Ideographs Extension C }
+ @t\hskip10pt@>kcat_code(@"C0):=kanji; { CJK Compatibility Ideographs Supplement }
+ @t\hskip10pt@>kcat_code(@"FE):=kana; { Fullwidth digit and latin alphabet }
+ @t\hskip10pt@>kcat_code(@"FF):=kana; { Halfwidth katakana }
+end else begin
+ @t\hskip10pt@>kcat_code(@"20+1):=other_kchar; {1 ku}
+ @t\hskip10pt@>kcat_code(@"20+2):=other_kchar; {2 ku}
+ @+@t\1@>for k:=3 to 6 do kcat_code(@"20+k):=kana; {3 ku ... 6 ku}
+ @+@t\1@>for k:=7 to 13 do kcat_code(@"20+k):=other_kchar; {7 ku ... 13 ku}
+ @+@t\1@>for k:=14 to 120 do kcat_code(@"20+k):=kanji; {14 ku ... 120 ku}
+ { $\.{@@"20}+|k| = |kcatcodekey|(|fromKUTEN|(|HILO|(k,1))$ }
+ @+@t\1@>for k:=16 to 94 do kcat_code(@"A0+k):=kanji; {2 men 16 ku ... 94 ku}
+end;
+@z
+
+@x l.5897 - upTeX
+primitive("char",char_num,0);@/
+@!@:char_}{\.{\\char} primitive@>
+@y
+primitive("char",char_num,0);@/
+@!@:char_}{\.{\\char} primitive@>
+primitive("kchar",kchar_num,0);@/
+@!@:kchar_}{\.{\\kchar} primitive@>
+@z
+
+@x
+char_num: print_esc("char");
+cs_name: print_esc("csname");
+def_font: print_esc("font");
+@y
+char_num: print_esc("char");
+kchar_num: print_esc("kchar");
+cs_name: print_esc("csname");
+def_font: print_esc("font");
+@z
+
+@x
+@d cs_token_flag==@"FFFF {amount added to the |eqtb| location in a
+token that stands for a control sequence; is a multiple of~256, less~1}
+@d left_brace_token=@'0400 {$2^8\cdot|left_brace|$}
+@d left_brace_limit=@'1000 {$2^8\cdot(|left_brace|+1)$}
+@d right_brace_token=@'1000 {$2^8\cdot|right_brace|$}
+@d right_brace_limit=@'1400 {$2^8\cdot(|right_brace|+1)$}
+@d math_shift_token=@'1400 {$2^8\cdot|math_shift|$}
+@d tab_token=@'2000 {$2^8\cdot|tab_mark|$}
+@d out_param_token=@'2400 {$2^8\cdot|out_param|$}
+@d space_token=@'5040 {$2^8\cdot|spacer|+|" "|$}
+@d letter_token=@'5400 {$2^8\cdot|letter|$}
+@d other_token=@'6000 {$2^8\cdot|other_char|$}
+@d match_token=@'6400 {$2^8\cdot|match|$}
+@d end_match_token=@'7000 {$2^8\cdot|end_match|$}
+@y
+@d cs_token_flag=@"1FFFFFFF {amount added to the |eqtb| location in a
+ token that stands for a control sequence; is a multiple of~@"1000000, less~1}
+@d max_char_val=@"100 {to separate char and command code}
+@d left_brace_token=@"100 {$2^8\cdot|left_brace|$}
+@d left_brace_limit=@"200 {$2^8\cdot(|left_brace|+1)$}
+@d right_brace_token=@"200 {$2^8\cdot|right_brace|$}
+@d right_brace_limit=@"300 {$2^8\cdot(|right_brace|+1)$}
+@d math_shift_token=@"300 {$2^8\cdot|math_shift|$}
+@d tab_token=@"400 {$2^8\cdot|tab_mark|$}
+@d out_param_token=@"500 {$2^8\cdot|out_param|$}
+@d space_token=@"A20 {$2^8\cdot|spacer|+|" "|$}
+@d letter_token=@"B00 {$2^8\cdot|letter|$}
+@d other_token=@"C00 {$2^8\cdot|other_char|$}
+@d match_token=@"D00 {$2^8\cdot|match|$}
+@d end_match_token=@"E00 {$2^8\cdot|end_match|$}
+@z
+
+@x
+ if check_kanji(info(p)) then {|wchar_token|}
+ begin m:=kcat_code(kcatcodekey(info(p))); c:=info(p);
+ end
+ else begin m:=Hi(info(p)); c:=Lo(info(p));
+@y
+ if check_kanji(info(p),1)=2 then {|wchar_token|}
+ begin m:=info(p) div max_cjk_val; c:=info(p) mod max_cjk_val; end
+ else begin m:=info(p) div max_char_val; c:=info(p) mod max_char_val;
+@z
+
+@x
+kanji,kana,other_kchar: print_kanji(KANJI(c));
+@y
+kanji,kana,other_kchar,hangul: print_kanji(KANJI(c));
+@z
+
+@x
+kanji,kana,other_kchar: begin print("kanji character ");
+@y
+kanji,kana,other_kchar,hangul: begin print("kanji character ");
+@z
+
+@x
+ if (first_count>0)and(trick_buf2[(first_count-1)mod error_line]=1) then
+ incr(first_count);
+@y
+ kcp:=trick_buf2[(first_count-1)mod error_line];
+ if (first_count>0)and(kcp>0) then
+ first_count:=first_count+nrestmultichr(kcp);
+@z
+
+@x
+if trick_buf2[p mod error_line]=2 then
+ begin p:=p+1; n:=n-1;
+ end;
+@y
+kcp:=trick_buf2[p mod error_line];
+if (kcp mod @'10)>1 then begin
+ p:=p+nrestmultichr(kcp)+1; n:=n-nrestmultichr(kcp)-1; end;
+@z
+
+@x
+if trick_buf2[(p-1) mod error_line]=1 then p:=p-1;
+@y
+kcp:=trick_buf2[(p-1) mod error_line];
+if ((kcp mod @'10)>0)and(nrestmultichr(kcp)>0) then p:=p-(kcp mod @'10);
+@z
+
+@x
+ begin if (link(start)=null)and(check_kanji(info(start))) then {|wchar_token|}
+ begin cur_input:=input_stack[base_ptr-1];
+ s:=get_avail; info(s):=Lo(buffer[loc]);
+@y
+ begin if (link(start)=null)and(check_kanji(info(start),2)=2) then {|wchar_token|}
+ begin cur_input:=input_stack[base_ptr-1];
+ s:=get_avail; info(s):=(buffer[loc] mod max_char_val);
+@z
+
+@x
+ begin cur_chr:=buffer[loc]; incr(loc);
+ if multistrlen(stringcast(buffer), limit+1, loc-1)=2 then
+ begin cur_chr:=fromBUFF(stringcast(buffer), limit+1, loc-1);
+ cur_cmd:=kcat_code(kcatcodekey(cur_chr));
+ incr(loc);
+ end
+ else reswitch: cur_cmd:=cat_code(cur_chr);
+@y
+ begin
+ cur_chr:=fromBUFF(stringcast(buffer), limit, loc);
+ cur_cmd:=kcat_code(kcatcodekey(cur_chr));
+ if (multistrlen(stringcast(buffer), limit, loc)>1) and check_kcat_code(cur_cmd) then begin
+ if (cur_cmd=not_cjk) then cur_cmd:=other_kchar;
+ loc:=loc+multistrlen(stringcast(buffer), limit, loc) end
+ else begin
+ cur_chr:=buffer[loc]; incr(loc);
+ reswitch: cur_cmd:=cat_code(cur_chr);
+ end;
+@z
+
+@x
+@ @d add_delims_to(#)==#+math_shift,#+tab_mark,#+mac_param,
+ #+sub_mark,#+letter,#+other_char
+@d all_jcode(#)==#+kanji,#+kana,#+other_kchar
+@y
+@ @d add_delims_to(#)==#+math_shift,#+tab_mark,#+mac_param,
+ #+sub_mark,#+letter,#+other_char
+@d all_jcode(#)==#+kanji,#+kana,#+other_kchar
+@d hangul_code(#)==#+hangul
+@z
+
+@x
+all_jcode(skip_blanks),all_jcode(new_line),all_jcode(mid_line):
+ state:=mid_kanji;
+@y
+all_jcode(skip_blanks),all_jcode(new_line),all_jcode(mid_line):
+ state:=mid_kanji;
+hangul_code(skip_blanks),hangul_code(new_line),hangul_code(mid_kanji):
+ state:=mid_line;
+@z
+
+@x
+else begin k:=loc; cur_chr:=buffer[k]; incr(k);
+ if multistrlen(stringcast(buffer), limit+1, k-1)=2 then
+ begin cat:=kcat_code(kcatcodekey(fromBUFF(stringcast(buffer), limit+1, k-1))); incr(k);
+ end
+ else cat:=cat_code(cur_chr);
+start_cs:
+ if (cat=letter)or(cat=kanji)or(cat=kana) then state:=skip_blanks
+@y
+else begin k:=loc;
+ cur_chr:=fromBUFF(stringcast(buffer), limit, k);
+ cat:=kcat_code(kcatcodekey(cur_chr));
+ if (multistrlen(stringcast(buffer), limit, k)>1) and check_kcat_code(cat) then begin
+ if (cat=not_cjk) then cat:=other_kchar;
+ k:=k+multistrlen(stringcast(buffer), limit, k) end
+ else begin {not multi-byte char}
+ cur_chr:=buffer[k];
+ cat:=cat_code(cur_chr);
+ incr(k);
+ end;
+start_cs:
+ if (cat=letter)or(cat=kanji)or(cat=kana)or(cat=hangul) then state:=skip_blanks
+@z
+
+@x
+ else if ((cat=letter)or(cat=kanji)or(cat=kana))and(k<=limit) then
+@y
+ else if ((cat=letter)or(cat=kanji)or(cat=kana)or(cat=hangul))and(k<=limit) then
+@z
+
+@x
+begin repeat cur_chr:=buffer[k]; incr(k);
+ if multistrlen(stringcast(buffer), limit+1, k-1)=2 then
+ begin cat:=kcat_code(kcatcodekey(fromBUFF(stringcast(buffer), limit+1, k-1))); incr(k);
+ end
+ else cat:=cat_code(cur_chr);
+@y
+begin repeat
+ cur_chr:=fromBUFF(stringcast(buffer), limit, k);
+ cat:=kcat_code(kcatcodekey(cur_chr));
+ if (multistrlen(stringcast(buffer), limit, k)>1) and check_kcat_code(cat) then begin
+ if (cat=not_cjk) then cat:=other_kchar;
+ k:=k+multistrlen(stringcast(buffer), limit, k) end
+ else begin {not multi-byte char}
+ cur_chr:=buffer[k];
+ cat:=cat_code(cur_chr);
+ incr(k);
+ end;
+@z
+
+@x
+until not((cat=letter)or(cat=kanji)or(cat=kana))or(k>limit);
+{@@<If an expanded...@@>;}
+if not((cat=letter)or(cat=kanji)or(cat=kana)) then decr(k);
+if cat=other_kchar then decr(k); {now |k| points to first nonletter}
+@y
+until not((cat=letter)or(cat=kanji)or(cat=kana)or(cat=hangul))or(k>limit);
+{@@<If an expanded...@@>;}
+if not((cat=letter)or(cat=kanji)or(cat=kana)or(cat=hangul)) then decr(k);
+if cat=other_kchar then k:=k-multilenbuffchar(cur_chr)+1; {now |k| points to first nonletter}
+@z
+
+@x
+ else if check_kanji(t) then {|wchar_token|}
+ begin cur_chr:=t; cur_cmd:=kcat_code(kcatcodekey(t));
+ end
+ else
+ begin cur_cmd:=Hi(t); cur_chr:=Lo(t);
+@y
+ else if check_kanji(t,3)=2 then {|wchar_token|}
+ begin cur_cmd:=t div max_cjk_val; cur_chr:=t mod max_cjk_val; end
+ else
+ begin cur_cmd:=t div max_char_val; cur_chr:=t mod max_char_val;
+@z
+
+@x
+ if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then {|wchar_token|}
+ cur_tok:=cur_chr
+ else cur_tok:=(cur_cmd*@'400)+cur_chr
+@y
+ if (cur_cmd>=kanji)and(cur_cmd<=hangul) then {|wchar_token|}
+ cur_tok:=(cur_cmd*max_cjk_val)+cur_chr
+ else cur_tok:=(cur_cmd*max_char_val)+cur_chr
+@z
+
+@x
+ if check_kanji(info(p)) then {|wchar_token|}
+ begin buffer[j]:=Hi(info(p)); incr(j);
+ end;
+ buffer[j]:=Lo(info(p)); incr(j); p:=link(p);
+@y
+ if check_kanji(info(p),4)=2 then {|wchar_token|}
+ begin t:=toBUFF(info(p) mod max_cjk_val);
+ if BYTE1(t)<>0 then begin buffer[j]:=BYTE1(t); incr(j); end;
+ if BYTE2(t)<>0 then begin buffer[j]:=BYTE2(t); incr(j); end;
+ if BYTE3(t)<>0 then begin buffer[j]:=BYTE3(t); incr(j); end;
+ buffer[j]:=BYTE4(t); incr(j);
+ p:=link(p);
+ end
+ else
+ begin buffer[j]:=info(p) mod max_char_val; incr(j); p:=link(p);
+ end;
+@z
+
+@x
+ if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then
+ cur_tok:=cur_chr
+ else cur_tok:=(cur_cmd*@'400)+cur_chr
+@y
+ if (cur_cmd>=kanji)and(cur_cmd<=hangul) then
+ cur_tok:=(cur_cmd*max_cjk_val)+cur_chr
+ else cur_tok:=(cur_cmd*max_char_val)+cur_chr
+@z
+
+@x
+ if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then
+ cur_tok:=cur_chr
+ else cur_tok:=(cur_cmd*@'400)+cur_chr
+@y
+ if (cur_cmd>=kanji)and(cur_cmd<=hangul) then
+ cur_tok:=(cur_cmd*max_cjk_val)+cur_chr
+ else cur_tok:=(cur_cmd*max_char_val)+cur_chr
+@z
+
+@x
+char_given,math_given: scanned_result(cur_chr)(int_val);
+@y
+kchar_given,
+char_given,math_given: scanned_result(cur_chr)(int_val);
+@z
+
+@x
+ begin if is_kanji(cur_val) then
+@y
+ begin if (cur_val<0)or(cur_val>255) then
+@z
+
+@x
+if not is_char_ascii(cur_val)and not check_kanji(cur_val) then {|wchar_token|}
+@y
+if ((cur_val<0)or(cur_val>255))and(check_kanji(cur_val,6)<>1) then {|wchar_token|}
+@z
+
+@x
+ if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then {|wchar_token|}
+@y
+ if (cur_cmd>=kanji)and(cur_cmd<=hangul) then {|wchar_token|}
+@z
+
+@x
+@!t:halfword; {token being appended}
+@!k:pool_pointer; {index into |str_pool|}
+begin str_room(1);
+p:=temp_head; link(p):=null; k:=b;
+while k<pool_ptr do
+ begin t:=so(str_pool[k]);
+ if multistrlen(stringcast(str_pool), pool_ptr, k)=2 then
+ begin t:=fromBUFF(stringcast(str_pool), pool_ptr, k); incr(k);
+ end
+ else if t=" " then t:=space_token
+ else t:=other_token+t;
+@y
+@!t:halfword; {token being appended}
+@!k:pool_pointer; {index into |str_pool|}
+@!cc:escape..max_char_code;
+begin str_room(1);
+p:=temp_head; link(p):=null; k:=b;
+while k<pool_ptr do
+ begin t:=fromBUFF(stringcast(str_pool), pool_ptr, k);
+ cc:=kcat_code(kcatcodekey(t));
+ if (multistrlen(stringcast(str_pool), pool_ptr, k)>1)and
+ check_kcat_code(cc) then
+ begin if (cc=not_cjk) then cc:=other_kchar;
+ t:=t+cc*max_cjk_val;
+ k:=k+multistrlen(stringcast(str_pool), pool_ptr, k)-1;
+ end
+ else begin t:=so(str_pool[k]);
+ if t=" " then t:=space_token
+ else t:=other_token+t;
+ end;
+@z
+
+@x
+@d ptex_convert_codes=10 {end of \eTeX's command codes}
+@y
+@d ucs_code=10 {command code for \.{\\ucs}}
+@d ptex_convert_codes=11 {end of \eTeX's command codes}
+@z
+
+@x
+@!@:kuten_}{\.{\\kuten} primitive@>
+@y
+@!@:kuten_}{\.{\\kuten} primitive@>
+primitive("ucs",convert,ucs_code);
+@!@:ucs_}{\.{\\ucs} primitive@>
+@z
+
+@x
+ kuten_code:print_esc("kuten");
+@y
+ kuten_code:print_esc("kuten");
+ ucs_code:print_esc("ucs");
+@z
+
+@x
+kansuji_code,euc_code,sjis_code,jis_code,kuten_code: scan_int;
+string_code, meaning_code: begin save_scanner_status:=scanner_status;
+ scanner_status:=normal; get_token;
+ if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then {|wchar_token|}
+@y
+kansuji_code,euc_code,sjis_code,jis_code,kuten_code,ucs_code: scan_int;
+string_code, meaning_code: begin save_scanner_status:=scanner_status;
+ scanner_status:=normal; get_token;
+ if (cur_cmd>=kanji)and(cur_cmd<=hangul) then {|wchar_token|}
+@z
+
+@x
+kuten_code: print_int(fromKUTEN(cur_val));
+@y
+kuten_code: print_int(fromKUTEN(cur_val));
+ucs_code: print_int(fromUCS(cur_val));
+@z
+
+@x
+if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then
+@y
+if (cur_cmd>=kanji)and(cur_cmd<=hangul) then
+@z
+
+@x
+get_x_token_or_active_char;
+if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then
+@y
+get_x_token_or_active_char;
+if (cur_cmd>=kanji)and(cur_cmd<=hangul) then
+@z
+
+@x
+ if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then {is kanji}
+ begin str_room(2);
+ append_char(Hi(cur_chr)); {kanji upper byte}
+ append_char(Lo(cur_chr)); {kanji lower byte}
+@y
+ if (cur_cmd>=kanji)and(cur_cmd<=hangul) then {|wchar_token|}
+ begin str_room(4); {4 is maximum}
+ cur_chr:=toBUFF(cur_chr);
+ if BYTE1(cur_chr)<>0 then append_char(BYTE1(cur_chr));
+ if BYTE2(cur_chr)<>0 then append_char(BYTE2(cur_chr));
+ if BYTE3(cur_chr)<>0 then append_char(BYTE3(cur_chr));
+ append_char(BYTE4(cur_chr));
+@z
+
+@x
+ fget; read_sixteen(cx); font_info[k].hh.rh:=tokanji(cx); {|kchar_code|}
+@y
+ fget; read_sixteenx(cx); font_info[k].hh.rh:=tokanji(cx); {|kchar_code|}
+@z
+
+@x
+@d set2=129 {typeset a character and move right}
+@y
+@d set2=129 {typeset a character and move right}
+@d set3=130 {typeset a character and move right}
+@z
+
+@x
+ jc:=toDVI(KANJI(info(p)));
+ dvi_out(set2); dvi_out(Hi(jc)); dvi_out(Lo(jc));
+@y
+ jc:=toDVI(KANJI(info(p)) mod max_cjk_val);
+ if (jc<@"10000) then begin
+ dvi_out(set2);
+ end else begin
+ dvi_out(set3); dvi_out(BYTE2(jc));
+ end;
+ dvi_out(BYTE3(jc)); dvi_out(BYTE4(jc));
+@z
+
+@x
+loop@+ begin get_x_token;
+ reswitch: case cur_cmd of
+ letter,other_char,char_given:@<Append a new letter or hyphen@>;
+ char_num: begin scan_char_num; cur_chr:=cur_val; cur_cmd:=char_given;
+ goto reswitch;
+ end;
+@y
+loop@+ begin get_x_token;
+ reswitch: case cur_cmd of
+ letter,other_char,char_given,kchar_given:@<Append a new letter or hyphen@>;
+ char_num,kchar_num: begin scan_char_num; cur_chr:=cur_val; cur_cmd:=char_given;
+ goto reswitch;
+ end;
+@z
+
+@x
+hmode+kanji,hmode+kana,hmode+other_kchar: goto main_loop_j;
+hmode+char_given:
+ if is_char_ascii(cur_chr) then goto main_loop else goto main_loop_j;
+hmode+char_num: begin scan_char_num; cur_chr:=cur_val;
+ if is_char_ascii(cur_chr) then goto main_loop else goto main_loop_j;
+ end;
+hmode+no_boundary: begin get_x_token;
+ if (cur_cmd=letter)or(cur_cmd=other_char)or
+ (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar)or
+ (cur_cmd=char_given)or(cur_cmd=char_num) then cancel_boundary:=true;
+@y
+hmode+kanji,hmode+kana,hmode+other_kchar,hmode+hangul,hmode+kchar_given: goto main_loop_j;
+hmode+char_given:
+ if check_echar_range(cur_chr) then goto main_loop else goto main_loop_j;
+hmode+char_num: begin scan_char_num; cur_chr:=cur_val;
+ if check_echar_range(cur_chr) then goto main_loop else goto main_loop_j;
+ end;
+hmode+kchar_num: begin scan_char_num; cur_chr:=cur_val;
+ goto main_loop_j;
+ end;
+hmode+no_boundary: begin get_x_token;
+ if (cur_cmd=letter)or(cur_cmd=other_char)or
+ ((cur_cmd>=kanji)and(cur_cmd<=hangul))or
+ (cur_cmd=char_given)or(cur_cmd=char_num)or
+ (cur_cmd=kchar_given)or(cur_cmd=kchar_num) then cancel_boundary:=true;
+@z
+
+@x
+if cur_cmd=letter then goto main_loop_lookahead+1;
+if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then
+ @<goto |main_lig_loop|@>;
+if cur_cmd=other_char then goto main_loop_lookahead+1;
+if cur_cmd=char_given then
+ begin if is_char_ascii(cur_chr) then goto main_loop_lookahead+1
+ else @<goto |main_lig_loop|@>;
+ end;
+x_token; {now expand and set |cur_cmd|, |cur_chr|, |cur_tok|}
+if cur_cmd=letter then goto main_loop_lookahead+1;
+if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then
+ @<goto |main_lig_loop|@>;
+if cur_cmd=other_char then goto main_loop_lookahead+1;
+if cur_cmd=char_given then
+ begin if is_char_ascii(cur_chr) then goto main_loop_lookahead+1
+ else @<goto |main_lig_loop|@>;
+ end;
+if cur_cmd=char_num then
+ begin scan_char_num; cur_chr:=cur_val;
+ if is_char_ascii(cur_chr) then goto main_loop_lookahead+1
+ else @<goto |main_lig_loop|@>;
+ end;
+@y
+if cur_cmd=letter then goto main_loop_lookahead+1;
+if (cur_cmd>=kanji)and(cur_cmd<=hangul) then
+ @<goto |main_lig_loop|@>;
+if cur_cmd=other_char then goto main_loop_lookahead+1;
+if cur_cmd=char_given then
+ begin if check_echar_range(cur_chr) then goto main_loop_lookahead+1
+ else @<goto |main_lig_loop|@>;
+ end;
+if cur_cmd=kchar_given then
+ @<goto |main_lig_loop|@>;
+x_token; {now expand and set |cur_cmd|, |cur_chr|, |cur_tok|}
+if cur_cmd=letter then goto main_loop_lookahead+1;
+if (cur_cmd>=kanji)and(cur_cmd<=hangul) then
+ @<goto |main_lig_loop|@>;
+if cur_cmd=other_char then goto main_loop_lookahead+1;
+if cur_cmd=char_given then
+ begin if check_echar_range(cur_chr) then goto main_loop_lookahead+1
+ else @<goto |main_lig_loop|@>;
+ end;
+if cur_cmd=char_num then
+ begin scan_char_num; cur_chr:=cur_val;
+ if check_echar_range(cur_chr) then goto main_loop_lookahead+1
+ else @<goto |main_lig_loop|@>;
+ end;
+if cur_cmd=kchar_num then
+ begin scan_char_num; cur_chr:=cur_val;
+ @<goto |main_lig_loop|@>;
+ end;
+@z
+
+@x
+vmode+letter,vmode+other_char,vmode+char_num,vmode+char_given,
+ vmode+math_shift,vmode+un_hbox,vmode+vrule,
+ vmode+accent,vmode+discretionary,vmode+hskip,vmode+valign,
+ vmode+kanji,vmode+kana,vmode+other_kchar,
+@y
+vmode+letter,vmode+other_char,vmode+char_num,vmode+char_given,
+ vmode+kchar_num,vmode+kchar_given,
+ vmode+math_shift,vmode+un_hbox,vmode+vrule,
+ vmode+accent,vmode+discretionary,vmode+hskip,vmode+valign,
+ vmode+kanji,vmode+kana,vmode+other_kchar,vmode+hangul,
+@z
+
+@x
+if not is_char_ascii(cur_val) then
+ begin KANJI(cx):=cur_val;
+ if direction=dir_tate then f:=cur_tfont else f:=cur_jfont;
+ p:=new_character(f,get_jfm_pos(KANJI(cx),f));
+ if p<>null then
+ begin
+ link(p):=get_avail; info(link(p)):=KANJI(cx);
+ end;
+@y
+if check_echar_range(cur_val)=0 then
+ begin KANJI(cx):=cur_val;
+ if direction=dir_tate then f:=cur_tfont else f:=cur_jfont;
+ p:=new_character(f,get_jfm_pos(KANJI(cx),f));
+ if p<>null then
+ begin
+ link(p):=get_avail;
+ info(link(p)):=KANJI(cx) + kcat_code(kcatcodekey(cx))*max_cjk_val;
+ end;
+@z
+
+@x
+if (cur_cmd=letter)or(cur_cmd=other_char) then
+ q:=new_character(f,cur_chr)
+else if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then
+ begin if direction=dir_tate then f:=cur_tfont else f:=cur_jfont;
+ cx:=cur_chr;
+ end
+else if cur_cmd=char_given then
+ if is_char_ascii(cur_chr) then q:=new_character(f,cur_chr)
+ else begin
+ if direction=dir_tate then f:=cur_tfont else f:=cur_jfont;
+ KANJI(cx):=cur_chr
+ end
+ else if cur_cmd=char_num then
+ begin scan_char_num;
+ if is_char_ascii(cur_val) then q:=new_character(f,cur_val)
+ else begin
+ if direction=dir_tate then f:=cur_tfont else f:=cur_jfont;
+ KANJI(cx):=cur_val
+ end
+ end
+@y
+if (cur_cmd=letter)or(cur_cmd=other_char) then
+ q:=new_character(f,cur_chr)
+else if (cur_cmd>=kanji)and(cur_cmd<=hangul) then
+ begin if direction=dir_tate then f:=cur_tfont else f:=cur_jfont;
+ cx:=cur_chr;
+ end
+else if cur_cmd=char_given then
+ if check_echar_range(cur_chr) then q:=new_character(f,cur_chr)
+ else begin
+ if direction=dir_tate then f:=cur_tfont else f:=cur_jfont;
+ KANJI(cx):=cur_chr
+ end
+else if cur_cmd=char_num then
+ begin scan_char_num;
+ if check_echar_range(cur_val) then q:=new_character(f,cur_val)
+ else begin
+ if direction=dir_tate then f:=cur_tfont else f:=cur_jfont;
+ KANJI(cx):=cur_val
+ end
+ end
+else if cur_cmd=kchar_given then
+ begin
+ if direction=dir_tate then f:=cur_tfont else f:=cur_jfont;
+ KANJI(cx):=cur_chr
+ end
+else if cur_cmd=kchar_num then
+ begin scan_char_num;
+ if direction=dir_tate then f:=cur_tfont else f:=cur_jfont;
+ KANJI(cx):=cur_val
+ end
+@z
+
+@x
+ begin q:=new_character(f,get_jfm_pos(KANJI(cx),f));
+ link(q):=get_avail; info(link(q)):=KANJI(cx); last_jchr:=q;
+@y
+ begin q:=new_character(f,get_jfm_pos(KANJI(cx),f));
+ link(q):=get_avail;
+ info(link(q)):=KANJI(cx) + kcat_code(kcatcodekey(cx))*max_cjk_val;
+ last_jchr:=q;
+@z
+
+@x
+letter,other_char,char_given:
+ if (is_char_ascii(cur_chr) or (cur_chr=256)) then begin
+@y
+letter,other_char,char_given:
+ if (cur_chr>=0)and(cur_chr<=256) then begin
+@z
+
+@x
+ KANJI(cx):=cur_chr;
+kanji,kana,other_kchar: cx:=cur_chr;
+@y
+ KANJI(cx):=cur_chr;
+kchar_given:
+ KANJI(cx):=cur_chr;
+kanji,kana,other_kchar,hangul: cx:=cur_chr;
+@z
+
+@x
+ math_type(p):=math_jchar; fam(p):=cur_jfam; character(p):=qi(0);
+ math_kcode(p-1):=KANJI(cx);
+@y
+ math_type(p):=math_jchar; fam(p):=cur_jfam; character(p):=qi(0);
+ math_kcode(p-1):=KANJI(cx) + kcat_code(kcatcodekey(cx))*max_cjk_val;
+@z
+
+@x
+mmode+letter,mmode+other_char,mmode+char_given:
+ if is_char_ascii(cur_chr) then
+ if cur_chr<128 then set_math_char(ho(math_code(cur_chr)))
+ else set_math_char(cur_chr)
+ else set_math_kchar(cur_chr);
+mmode+kanji,mmode+kana,mmode+other_kchar: begin
+ cx:=cur_chr; set_math_kchar(KANJI(cx));
+ end;
+mmode+char_num: begin scan_char_num; cur_chr:=cur_val;
+ if is_char_ascii(cur_chr) then
+ if cur_chr<128 then set_math_char(ho(math_code(cur_chr)))
+ else set_math_char(cur_chr)
+ else set_math_kchar(cur_chr);
+ end;
+@y
+mmode+letter,mmode+other_char,mmode+char_given:
+ if check_echar_range(cur_chr) then
+ if cur_chr<128 then set_math_char(ho(math_code(cur_chr)))
+ else set_math_char(cur_chr)
+ else set_math_kchar(cur_chr);
+mmode+kanji,mmode+kana,mmode+other_kchar,mmode+hangul: begin
+ cx:=cur_chr; set_math_kchar(KANJI(cx));
+ end;
+mmode+char_num: begin scan_char_num; cur_chr:=cur_val;
+ if check_echar_range(cur_chr) then
+ if cur_chr<128 then set_math_char(ho(math_code(cur_chr)))
+ else set_math_char(cur_chr)
+ else set_math_kchar(cur_chr);
+ end;
+mmode+kchar_given:
+ set_math_kchar(cur_chr);
+mmode+kchar_num: begin scan_char_num; cur_chr:=cur_val;
+ set_math_kchar(cur_chr);
+ end;
+@z
+
+@x
+any_mode(assign_inhibit_xsp_code),
+any_mode(set_auto_spacing),
+@y
+any_mode(assign_inhibit_xsp_code),
+any_mode(set_auto_spacing),
+any_mode(set_enable_cjk_token),
+@z
+
+@x l.23666 - upTeX
+@d char_sub_def_code=7 {|shorthand_def| for \.{\\charsubdef}}
+
+@<Put each...@>=
+primitive("chardef",shorthand_def,char_def_code);@/
+@!@:char_def_}{\.{\\chardef} primitive@>
+@y
+@d char_sub_def_code=7 {|shorthand_def| for \.{\\charsubdef}}
+@d kchar_def_code=8 {|shorthand_def| for \.{\\kchardef}}
+
+@<Put each...@>=
+primitive("chardef",shorthand_def,char_def_code);@/
+@!@:char_def_}{\.{\\chardef} primitive@>
+primitive("kchardef",shorthand_def,kchar_def_code);@/
+@!@:kchar_def_}{\.{\\kchardef} primitive@>
+@z
+
+@x l.23698 - upTeX
+char_given: begin print_esc("char"); print_hex(chr_code);
+ end;
+@y
+char_given: begin print_esc("char"); print_hex(chr_code);
+ end;
+kchar_given: begin print_esc("kchar"); print_hex(chr_code);
+ end;
+@z
+
+@x l.23729 - upTeX
+ char_def_code: begin scan_char_num; define(p,char_given,cur_val);
+ end;
+@y
+ char_def_code: begin scan_char_num; define(p,char_given,cur_val);
+ end;
+ kchar_def_code: begin scan_char_num; define(p,kchar_given,cur_val);
+ end;
+@z
+
+@x
+@ @<Let |m| be the minimal...@>=
+if cur_chr=kcat_code_base then m:=kanji else m:=0
+@y
+@ @<Let |m| be the minimal...@>=
+if cur_chr=kcat_code_base then m:=not_cjk else m:=0
+@z
+
+@x
+@<Change the case of the token in |p|, if a change is appropriate@>=
+t:=info(p);
+if (t<cs_token_flag+single_base)and(not check_kanji(t)) then
+ begin c:=t mod 256;
+@y
+@<Change the case of the token in |p|, if a change is appropriate@>=
+t:=info(p);
+if (t<cs_token_flag+single_base)and(check_kanji(t,7)<2) then
+ begin c:=t mod max_char_val;
+@z
+
+@x
+begin p:=cur_chr; scan_int; n:=cur_val; scan_optional_equals; scan_int;
+if not check_kanji(cur_val) then
+@y
+begin p:=cur_chr; scan_int; n:=cur_val; scan_optional_equals; scan_int;
+if check_kanji(cur_val,8)<>1 then
+@z
+
+@x
+@d set_auto_xspacing_code=3
+@y
+@d set_auto_xspacing_code=3
+@d reset_enable_cjk_token_code=0
+@d set_enable_cjk_token_code=1
+@d set_force_cjk_token_code=2
+@z
+
+@x
+@!@:no_auto_xspacing_}{\.{\\noautoxspacing} primitive@>
+@y
+@!@:no_auto_xspacing_}{\.{\\noautoxspacing} primitive@>
+primitive("enablecjktoken",set_enable_cjk_token,reset_enable_cjk_token_code);
+@!@:enable_cjk_token_}{\.{\\enablecjktoken} primitive@>
+primitive("disablecjktoken",set_enable_cjk_token,set_enable_cjk_token_code);
+@!@:disable_cjk_token_}{\.{\\disablecjktoken} primitive@>
+primitive("forcecjktoken",set_enable_cjk_token,set_force_cjk_token_code);
+@!@:force_cjk_token_}{\.{\\forcecjktoken} primitive@>
+@z
+
+@x
+ if (chr_code mod 2)=0 then print_esc("noauto") else print_esc("auto");
+ if chr_code<2 then print("spacing") else print("xspacing");
+end;
+@y
+ if (chr_code mod 2)=0 then print_esc("noauto") else print_esc("auto");
+ if chr_code<2 then print("spacing") else print("xspacing");
+end;
+set_enable_cjk_token:begin
+ if chr_code=0 then print_esc("enable")
+ else if chr_code=1 then print_esc("disable") else print_esc("force");
+ print("cjktoken");
+end;
+@z
+
+@x
+ else begin p:=auto_xspacing_code; cur_chr:=(cur_chr mod 2); end;
+ define(p,data,cur_chr);
+end;
+@y
+ else begin p:=auto_xspacing_code; cur_chr:=(cur_chr mod 2); end;
+ define(p,data,cur_chr);
+end;
+set_enable_cjk_token: define(enable_cjk_token_code,data,cur_chr);
+@z
+
+@x
+assign_inhibit_xsp_code:
+begin p:=cur_chr; scan_int; n:=cur_val; scan_optional_equals; scan_int;
+if check_kanji(n) then
+@y
+assign_inhibit_xsp_code:
+begin p:=cur_chr; scan_int; n:=cur_val; scan_optional_equals; scan_int;
+if check_kanji(n,9)=1 then
+@z
+
+@x
+assign_kinsoku:
+begin p:=cur_chr; scan_int; n:=cur_val; scan_optional_equals; scan_int;
+if is_char_ascii(n) or check_kanji(n) then
+@y
+assign_kinsoku:
+begin p:=cur_chr; scan_int; n:=cur_val; scan_optional_equals; scan_int;
+if abs(check_kanji(n,10))=1 then
+@z
+
+@x
+@ @<Insert a space around the character |p|@>=
+if font_dir[font(p)]<>dir_default then
+ begin KANJI(cx):=info(link(p));
+@y
+@ @<Insert a space around the character |p|@>=
+if font_dir[font(p)]<>dir_default then
+ begin KANJI(cx):=info(link(p)) mod max_cjk_val;
+@z
+
+@x
+@ @<Insert a space before the |first_char|@>=
+if font_dir[font(first_char)]<>dir_default then
+ begin KANJI(cx):=info(link(first_char));
+@y
+@ @<Insert a space before the |first_char|@>=
+if font_dir[font(first_char)]<>dir_default then
+ begin KANJI(cx):=info(link(first_char)) mod max_cjk_val;
+@z
+
+@x
+begin if is_char_node(link(p)) then
+ begin q:=p; p:=link(p);
+ if font_dir[font(p)]<>dir_default then
+ begin KANJI(cx):=info(link(p));
+@y
+begin if is_char_node(link(p)) then
+ begin q:=p; p:=link(p);
+ if font_dir[font(p)]<>dir_default then
+ begin KANJI(cx):=info(link(p)) mod max_cjk_val;
+@z
+
+@x
+ begin KANJI(cx):=info(link(p)); i:=kcat_code(kcatcodekey(cx)); k:=0;
+ if (i=kanji)or(i=kana) then begin t:=q; s:=p; end;
+@y
+ begin KANJI(cx):=info(link(p)) mod max_cjk_val;
+ i:=info(link(p)) div max_cjk_val; k:=0;
+ if (i=kanji)or(i=kana)or(i=hangul) then begin t:=q; s:=p; end;
+@z
+
+@x
+ fast_get_avail(main_p); font(main_p):=main_f; character(main_p):=cur_l;
+ link(tail):=main_p; tail:=main_p; last_jchr:=tail;
+ fast_get_avail(main_p); info(main_p):=KANJI(cur_chr);
+@y
+ fast_get_avail(main_p); font(main_p):=main_f; character(main_p):=cur_l;
+ link(tail):=main_p; tail:=main_p; last_jchr:=tail;
+ fast_get_avail(main_p); info(main_p):=KANJI(cur_chr)+cur_cmd*max_cjk_val;
+@z
+
+@x
+ main_i:=orig_char_info(main_f)(cur_l);
+ case cur_cmd of
+ kanji,kana,other_kchar: begin
+@y
+ main_i:=orig_char_info(main_f)(cur_l);
+ case cur_cmd of
+ kanji,kana,other_kchar,hangul: begin
+@z
+
+@x
+ kanji,kana,other_kchar: cur_l:=qi(get_jfm_pos(KANJI(cur_chr),main_f));
+ letter,other_char: begin ins_kp:=true; cur_l:=qi(0); end;
+ char_given: begin
+ if is_char_ascii(cur_chr) then
+ begin ins_kp:=true; cur_l:=qi(0);
+ end
+ else cur_l:=qi(get_jfm_pos(KANJI(cur_chr),main_f));
+ end;
+ char_num: begin scan_char_num; cur_chr:=cur_val;
+ if is_char_ascii(cur_chr) then
+ begin ins_kp:=true; cur_l:=qi(0);
+ end
+ else cur_l:=qi(get_jfm_pos(KANJI(cur_chr),main_f));
+ end;
+@y
+ kanji,kana,other_kchar,hangul: cur_l:=qi(get_jfm_pos(KANJI(cur_chr),main_f));
+ letter,other_char: begin ins_kp:=true; cur_l:=qi(0); end;
+ char_given: begin
+ if check_echar_range(cur_chr) then
+ begin ins_kp:=true; cur_l:=qi(0);
+ end
+ else cur_l:=qi(get_jfm_pos(KANJI(cur_chr),main_f));
+ end;
+ char_num: begin scan_char_num; cur_chr:=cur_val;
+ if check_echar_range(cur_chr) then
+ begin ins_kp:=true; cur_l:=qi(0);
+ end
+ else cur_l:=qi(get_jfm_pos(KANJI(cur_chr),main_f));
+ end;
+ kchar_given: begin
+ cur_l:=qi(get_jfm_pos(KANJI(cur_chr),main_f));
+ end;
+ kchar_num: begin scan_char_num; cur_chr:=cur_val;
+ cur_l:=qi(get_jfm_pos(KANJI(cur_chr),main_f));
+ end;
+@z
+
+@x
+procedure print_kanji(@!s:KANJI_code); {prints a single character}
+begin
+if s>255 then
+ begin print_char(Hi(s)); print_char(Lo(s));
+ end else print_char(s);
+@y
+procedure print_kanji(@!s:KANJI_code); {prints a single character}
+begin
+s:=toBUFF(s mod max_cjk_val);
+if BYTE1(s)<>0 then print_char(BYTE1(s));
+if BYTE2(s)<>0 then print_char(BYTE2(s));
+if BYTE3(s)<>0 then print_char(BYTE3(s));
+ print_char(BYTE4(s));
+end;
+
+function check_kcat_code(@!ct:integer):integer;
+begin
+if ((ct>=kanji)and(enable_cjk_token=0))or(enable_cjk_token=2)then
+ check_kcat_code:=1
+else check_kcat_code:=0;
+end;
+
+function check_echar_range(@!c:integer):integer;
+begin
+if (c>=0)and(c<256)then
+ check_echar_range:=1
+else check_echar_range:=0;
+@z
diff --git a/Build/source/texk/web2c/uptexdir/uptex.defines b/Build/source/texk/web2c/uptexdir/uptex.defines
new file mode 100644
index 00000000000..e477f082092
--- /dev/null
+++ b/Build/source/texk/web2c/uptexdir/uptex.defines
@@ -0,0 +1,48 @@
+{ defined at kanji.c, kanji.h, ptexenc/ptexenc.h, ptexenc/unicode.h }
+@define function BYTE1 ();
+@define function BYTE2 ();
+@define function BYTE3 ();
+@define function BYTE4 ();
+@define function Hi ();
+@define function Lo ();
+@define procedure initdefaultkanji;
+@define procedure forcesjisterm ();
+
+@define function getencstring;
+@define function setencstring ();
+@define procedure setpriorfileenc;
+@define function isinternalUPTEX;
+@define procedure setptexencuptex;
+
+@define function iskanji1 ();
+@define function is1stchr ();
+@define function ismultichr ();
+
+@define function multistrlen ();
+@define function fromBUFF ();
+@define function toBUFF ();
+
+@define function fromDVI ();
+@define function toDVI ();
+@define function putc2 ();
+@define function inputline2 ();
+
+@define function fromJIS ();
+@define function fromEUC ();
+@define function fromSJIS ();
+@define function fromKUTEN ();
+@define function fromUCS ();
+
+@define function checkkanji ();
+@define function iskanji ();
+@define function ischarascii ();
+@define function iswcharascii ();
+@define function ismultiprn ();
+@define function calcpos ();
+@define function kcatcodekey ();
+@define function multilenbuffchar ();
+@define function nrestmultichr ();
+
+@define const PTEXTFTOPLHELP;
+@define const PTEXPLTOTFHELP;
+@define const UPDVITYPEHELP;
diff --git a/Build/source/texk/web2c/uptexdir/uptexextra.c b/Build/source/texk/web2c/uptexdir/uptexextra.c
new file mode 100644
index 00000000000..055f1ae613a
--- /dev/null
+++ b/Build/source/texk/web2c/uptexdir/uptexextra.c
@@ -0,0 +1,11 @@
+/* uptexextra.c: Hand-coded routines for upTeX.
+
+ This file is public domain. */
+
+#define EXTERN /* Instantiate data from uptexd.h here. */
+
+/* This file defines TeX and upTeX. */
+#include <uptexd.h>
+
+/* Hand-coded routines for TeX or Metafont in C. */
+#include <lib/texmfmp.c>
diff --git a/Build/source/texk/web2c/uptexdir/uptexextra.h b/Build/source/texk/web2c/uptexdir/uptexextra.h
new file mode 100644
index 00000000000..833a82ce3b9
--- /dev/null
+++ b/Build/source/texk/web2c/uptexdir/uptexextra.h
@@ -0,0 +1,25 @@
+/* uptexextra.h: banner etc. for upTeX.
+
+ This is included by upTeX, from uptexextra.c
+*/
+
+#include <uptexdir/ptex_version.h> /* for PTEX_VERSION */
+#include <uptexdir/uptex_version.h> /* for UPTEX_VERSION */
+
+#define BANNER "This is upTeX, Version 3.1415926-" PTEX_VERSION "-" UPTEX_VERSION
+#define COPYRIGHT_HOLDER "D.E. Knuth"
+#define AUTHOR NULL
+#define PROGRAM_HELP UPTEXHELP
+#define BUG_ADDRESS "ptex-staff@ml.asciimw.jp"
+#define DUMP_VAR TEXformatdefault
+#define DUMP_LENGTH_VAR formatdefaultlength
+#define DUMP_OPTION "fmt"
+#define DUMP_EXT ".fmt"
+#define INPUT_FORMAT kpse_tex_format
+#define INI_PROGRAM "iniuptex"
+#define VIR_PROGRAM "viruptex"
+
+#ifdef Xchr
+#undef Xchr
+#define Xchr(x) (x)
+#endif /* Xchr */