From 72e71ef56d754ce1193726b2bbb4877dae09763c Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 9 Nov 2013 00:35:54 +0000 Subject: kotex-utils git-svn-id: svn://tug.org/texlive/trunk@32101 c570f23f-e606-0410-a88d-b1316a301751 --- .../scripts/kotex-utils/jamo-normalize.pl | 6645 ++++++++++++++++++++ Master/texmf-dist/scripts/kotex-utils/komkindex.pl | 918 +++ .../scripts/kotex-utils/ttf2kotexfont.pl | 818 +++ 3 files changed, 8381 insertions(+) create mode 100755 Master/texmf-dist/scripts/kotex-utils/jamo-normalize.pl create mode 100755 Master/texmf-dist/scripts/kotex-utils/komkindex.pl create mode 100755 Master/texmf-dist/scripts/kotex-utils/ttf2kotexfont.pl (limited to 'Master/texmf-dist/scripts/kotex-utils') diff --git a/Master/texmf-dist/scripts/kotex-utils/jamo-normalize.pl b/Master/texmf-dist/scripts/kotex-utils/jamo-normalize.pl new file mode 100755 index 00000000000..f6ed6e70496 --- /dev/null +++ b/Master/texmf-dist/scripts/kotex-utils/jamo-normalize.pl @@ -0,0 +1,6645 @@ +#!/usr/bin/perl + +# jamo-normalize.pl +# +# Copyright (c) 2003-2013 Dohyun Kim +# +# This work may be distributed and/or modified under the +# conditions of the LaTeX Project Public License, either version 1.3c +# of this license or (at your option) any later version. +# The latest version of this license is in +# http://www.latex-project.org/lppl.txt +# and version 1.3c or later is part of all distributions of LaTeX +# version 2006/05/20 or later. +# +# written by Dohyun Kim +# public domain +# + +#use strict; +#use warnings; + +my %OPT; + +while (@ARGV) { + my $opt = shift @ARGV; + if ($opt =~ /-b/i) { $OPT{boundary} = 1 } + elsif ($opt =~ /-p/i) { $OPT{topua} = 1 } + elsif ($opt =~ /-d/i) { $OPT{decompose} = 1 } + elsif ($opt =~ /-o/i) { $OPT{frompua} = 1 } + elsif ($opt =~ /-t/i) { $OPT{latintm} = 1 } + elsif ($opt =~ /-r/i) { $OPT{reordertm} = 1 } + elsif ($opt =~ /-i/i) { $OPT{normalhanja} = 1 } + elsif ($opt =~ /-c/i) { $OPT{compatjamo} = 1 } + else { + print + "Usage: $0 [options] < in_file > out_file\n\n", + " Translate Hangul Jamo sequence to Hangul syllables\n\n", + " -b : insert ZWS between syllable blocks (not for practical use)\n", + " -c : convert conjoining Jamo to compatibility Jamo\n", + " -d : decomposition only, and no further recomposition\n", + " -i : convert compatibility Hanja to normal Hanja\n", + " -o : decompose PUA Old Hangul syllables to Jamo sequence\n", + " -p : compose Jamo sequence to PUA Old Hangul syllables\n", + " -r : reorder Hangul Tone Marks to the first of syllable block\n", + " (not for practical use)\n", + " -t : convert U+00B7 or U+003A to Hangul Tone Marks\n"; + exit; + } +} + +##### variables ##### + +my $cho = "\x{1100}-\x{115F}\x{A960}-\x{A97C}"; +my $jung = "\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}"; +my $jong = "\x{11A8}-\x{11FF}\x{D7CB}-\x{D7FB}"; +my $tmrk = "\x{302E}\x{302F}"; +my $boundary = "\x{200B}"; +my $syllblock = "[$cho][$jung][$jong]?[$tmrk]?"; +my $jamos = "[$cho$jung$jong$tmrk]"; + +my %jamo2cjamo = ( + 0x1100 => 0x3131, 0x1101 => 0x3132, 0x1102 => 0x3134, 0x1103 => 0x3137, + 0x1104 => 0x3138, 0x1105 => 0x3139, 0x1106 => 0x3141, 0x1107 => 0x3142, + 0x1108 => 0x3143, 0x1109 => 0x3145, 0x110A => 0x3146, 0x110B => 0x3147, + 0x110C => 0x3148, 0x110D => 0x3149, 0x110E => 0x314A, 0x110F => 0x314B, + 0x1110 => 0x314C, 0x1111 => 0x314D, 0x1112 => 0x314E, 0x1114 => 0x3165, + 0x1115 => 0x3166, 0x111A => 0x3140, 0x111C => 0x316E, 0x111D => 0x3171, + 0x111E => 0x3172, 0x1120 => 0x3173, 0x1121 => 0x3144, 0x1122 => 0x3174, + 0x1123 => 0x3175, 0x1127 => 0x3176, 0x1129 => 0x3177, 0x112B => 0x3178, + 0x112C => 0x3179, 0x112D => 0x317A, 0x112E => 0x317B, 0x112F => 0x317C, + 0x1132 => 0x317D, 0x1136 => 0x317E, 0x1140 => 0x317F, +# 0x1145 => 0x3182, 0x1146 => 0x3183, + 0x1147 => 0x3180, 0x114C => 0x3181, 0x1157 => 0x3184, 0x1158 => 0x3185, + 0x1159 => 0x3186, 0x115B => 0x3167, 0x115C => 0x3135, 0x115D => 0x3136, + 0x1161 => 0x314F, 0x1162 => 0x3150, 0x1163 => 0x3151, 0x1164 => 0x3152, + 0x1165 => 0x3153, 0x1166 => 0x3154, 0x1167 => 0x3155, 0x1168 => 0x3156, + 0x1169 => 0x3157, 0x116A => 0x3158, 0x116B => 0x3159, 0x116C => 0x315A, + 0x116D => 0x315B, 0x116E => 0x315C, 0x116F => 0x315D, 0x1170 => 0x315E, + 0x1171 => 0x315F, 0x1172 => 0x3160, 0x1173 => 0x3161, 0x1174 => 0x3162, + 0x1175 => 0x3163, 0x1184 => 0x3187, 0x1185 => 0x3188, 0x1188 => 0x3189, + 0x1191 => 0x318A, 0x1192 => 0x318B, 0x1194 => 0x318C, 0x119E => 0x318D, + 0x11A1 => 0x318E, +# 0x11A8 => 0x3131, 0x11A9 => 0x3132, 0x11AA => 0x3133, 0x11AB => 0x3134, +# 0x11AC => 0x3135, 0x11AD => 0x3136, 0x11AE => 0x3137, 0x11AF => 0x3139, +# 0x11B0 => 0x313A, 0x11B1 => 0x313B, 0x11B2 => 0x313C, 0x11B3 => 0x313D, +# 0x11B4 => 0x313E, 0x11B5 => 0x313F, 0x11B6 => 0x3140, 0x11B7 => 0x3141, +# 0x11B8 => 0x3142, 0x11B9 => 0x3144, 0x11BA => 0x3145, 0x11BB => 0x3146, +# 0x11BC => 0x3147, 0x11BD => 0x3148, 0x11BE => 0x314A, 0x11BF => 0x314B, +# 0x11C0 => 0x314C, 0x11C1 => 0x314D, 0x11C2 => 0x314E, 0x11C6 => 0x3166, +# 0x11C7 => 0x3167, 0x11C8 => 0x3168, 0x11CC => 0x3169, 0x11CE => 0x316A, +# 0x11D3 => 0x316B, 0x11D7 => 0x316C, 0x11D9 => 0x316D, 0x11DC => 0x316E, +# 0x11DD => 0x316F, 0x11DF => 0x3170, 0x11E2 => 0x3171, 0x11E6 => 0x3178, +# 0x11E7 => 0x317A, 0x11E8 => 0x317C, 0x11EA => 0x317D, 0x11EB => 0x317F, +# 0x11EE => 0x3180, 0x11F0 => 0x3181, 0x11F1 => 0x3182, 0x11F2 => 0x3183, +# 0x11F4 => 0x3184, 0x11F9 => 0x3186, 0x11FF => 0x3165, + 0xA964 => 0x313A, 0xA966 => 0x316A, 0xA968 => 0x313B, 0xA969 => 0x313C, + 0xA96C => 0x313D, 0xA971 => 0x316F, +# 0xD7CD => 0x3138, 0xD7E3 => 0x3173, 0xD7E6 => 0x3143, 0xD7E7 => 0x3175, +# 0xD7E8 => 0x3176, 0xD7EF => 0x317E, 0xD7F9 => 0x3149, +); + +my @HYpuaJamo; +if ($OPT{frompua} or $OPT{topua}) { @HYpuaJamo = arr_hypua2jamo(); } + +##### main routine ##### + +binmode (STDIN,":utf8"); +binmode (STDOUT,":utf8"); + +while (<>) { + print STDERR "."; + &syllable2jamo; + if ($OPT{frompua}) { + &hypua2jamo; + &hypuasingle2jamo; + } + &compose_jamo; + &insert_filler; + &ascii2tonemark if $OPT{latintm}; + &insert_boundary if $OPT{boundary}; + &reorder_tonemark if $OPT{reordertm}; + unless ($OPT{decompose}) { + &jamo2hypua if $OPT{topua}; + &jamo2syllable; + &jamo2jamocomp if $OPT{compatjamo}; + } + &normalize_hanja if $OPT{normalhanja}; + print; +} + +print STDERR "\n"; + +##### subroutines ##### + +sub reorder_tonemark { + my @blocks = split /($syllblock)/; + for my $i (0 .. $#blocks) { + if ($i % 2 == 0) { + $blocks[$i] =~ s/([$tmrk])/$1\x{25CC}/g; + } + else { + $blocks[$i] =~ s/([$cho$jung$jong]+)([$tmrk])$/$2$1/; + } + } + $_ = join '',@blocks; +} + +sub ascii2tonemark { + s/\x{B7}([$cho][$jung][$jong]?)(?![$tmrk])/$1\x{302E}/g; + s/\x{3A}([$cho][$jung][$jong]?)(?![$tmrk])/$1\x{302F}/g; +} + +sub hypua2jamo { + for my $i (0 .. $#HYpuaJamo) { + my $puachar = chr $HYpuaJamo[$i][0]; + my $jamoseq = ""; + for my $j (1 .. $#{$HYpuaJamo[$i]}) { + $jamoseq .= chr $HYpuaJamo[$i][$j]; + } + s/$puachar/$jamoseq/g; + } +} + +sub jamo2hypua { + for my $i (0 .. $#HYpuaJamo) { + my $puachar = chr $HYpuaJamo[$i][0]; + my $jamoseq = ""; + for my $j (1 .. $#{$HYpuaJamo[$i]}) { + $jamoseq .= chr $HYpuaJamo[$i][$j]; + } + s/$jamoseq/$puachar/g; + } +} + +sub insert_boundary { + chomp; + my @parts = split /($syllblock)/, $_; + my @newparts; + for my $i (0 .. $#parts) { + if ($i % 2 == 0) { + next unless $parts[$i]; + my @subparts = split /($jamos)/, $parts[$i]; + my @newsubparts; + for my $i (0 .. $#subparts) { + push @newsubparts, $subparts[$i] if $subparts[$i]; + } + push @newparts, join ($boundary, @newsubparts); + } + else { + push @newparts, $parts[$i]; + } + } + $_ = join $boundary, @newparts; + $_ .= "\n"; +} + +sub insert_filler { + s/(? +# +# This work may be distributed and/or modified under the +# conditions of the LaTeX Project Public License, either version 1.3c +# of this license or (at your option) any later version. +# The latest version of this license is in +# http://www.latex-project.org/lppl.txt +# and version 1.3c or later is part of all distributions of LaTeX +# version 2006/05/20 or later. + +### +### TODO: how to distinguish malformed utf8 string in IND file? +### + +#use warnings; +#use strict; +use 5.8.0; +use Getopt::Std; + +## -euc option +for (@ARGV) { + if ( /^\-+euc/ ) { + $_ = ''; + exec ("hmakeindex @ARGV") or die "couldn't exec hmakeindex: $!"; + } +} + +binmode STDOUT,":utf8"; + +my $progname = $0; +$progname =~ s/^.*\///; + +print "This is $progname, a makeindex wrapper for ko.TeX package.\n"; + +@ARGV == 0 and die "\n", + "Usage: $progname [-euc] [makeindex options] idx_filename[s]\n", + " -euc: exec hmakeindex, passing other arguments as they are.\n\n", + " $progname [-k] [makeindex options] idx_filename[s]\n", + " -k: put hangul index entries before than others.\n\n"; + + +### +### Many thanks to Jinsuk Kim, http://www.jinsuk.pe.kr +### +my @hanja_to_hangul = get_hanja_hangul_table("hanja_hangul.tab"); +my @hanjacompat_to_hangul = get_hanja_hangul_table("hanjacom_hangul.tab"); +my @hanjaextA_to_hangul = get_hanja_hangul_table("hanjaexa_hangul.tab"); + +my @cjamo_jamo = + qw/ + 1100 1101 11aa 1102 11ac 11ad 1103 1104 + 1105 11b0 11b1 11b2 11b3 11b4 11b5 111a + 1106 1107 1108 1121 1109 110a 110b 110c + 110d 110e 110f 1110 1111 1112 1161 1162 + 1163 1164 1165 1166 1167 1168 1169 116a + 116b 116c 116d 116e 116f 1170 1171 1172 + 1173 1174 1175 1160 1114 1115 11c7 11c8 + 11cc 11ce 11d3 11d7 11d9 111c 11dd 11df + 111d 111e 1120 1122 1123 1127 1129 112b + 112c 112d 112e 112f 1132 1136 1140 1147 + 114c 11f1 11f2 1157 1158 1159 1184 1185 + 1188 1191 1192 1194 119e 11a1 + /; + +my @hangul_grouping = + qw/ + F785 F788 F790 F798 F7A8 F7AE F7C2 F7D8 + F7D9 F7E7 F7E8 F7F0 F7F5 F7F6 F7F8 F7FC + F7FF F807 F80C F811 F816 F81B F828 F831 + F83C F846 F84F F85E F86B + /; +# ㄱ ㄴ ㄷ ㄹ ㅁ ㅂ ㅅ ㅿ +# ㅇ ㆁ ㅈ ㅊ ㅋ ㅌ ㅍ ㅎ +# ㆆ ㅏ ㅑ ㅓ ㅕ ㅗ ㅛ ㅜ +# ㅠ ㅡ ㅣ ㆍ 종성 + + +# u+115F => U+F784 => U+F801 # 초성채움 +my @jamo_puajamo_1100 = qw/ + F785 F786 F788 F790 F792 F798 F7A8 F7AE + F7B2 F7C2 F7CA F7D9 F7E8 F7EA F7F0 F7F5 + F7F6 F7F8 F7FC F789 F78A F78B F78C F791 + F79B F79E F7A6 F7A7 F7AB F7AD F7AF F7B0 + F7B1 F7B3 F7B4 F7B5 F7B6 F7B7 F7B8 F7BA + F7BB F7BD F7BE F7C0 F7C1 F7C3 F7C4 F7C5 + F7C6 F7C7 F7C8 F7C9 F7CC F7CD F7CE F7CF + F7D0 F7D1 F7D2 F7D3 F7D4 F7D5 F7D6 F7D7 + F7D8 F7DA F7DB F7DD F7DE F7DF F7E0 F7E1 + F7E2 F7E3 F7E4 F7E5 F7E7 F7E9 F7EC F7ED + F7EE F7EF F7F1 F7F2 F7F3 F7F4 F7F9 F7FB + F7FE F7FF F787 F78D F78E F78F F793 F801 + F806 F807 F80B F80C F810 F811 F815 F816 + F81A F81B F81C F81D F827 F828 F831 F834 + F836 F83A F83C F846 F84D F84F F808 F809 + F80D F80E F812 F813 F814 F818 F819 F820 + F821 F823 F824 F826 F82B F82C F82E F82F + F830 F832 F833 F835 F838 F839 F83D F83F + F840 F841 F842 F844 F845 F84B F84C F84E + F850 F851 F856 F859 F85B F85D F85E F860 + F862 F863 F864 F80A F80F F817 F81E F81F + F86B F86C F870 F875 F87C F87F F880 F88B + F88C F895 F899 F89F F8A4 F8A5 F8A6 F8AA + F8B9 F8BF F8C6 F8CD F8D8 F8E6 F8EA F8EB + F8EC F8ED F8F2 F86E F871 F876 F878 F87A + F87B F87E F881 F884 F88E F890 F891 F892 + F893 F896 F897 F89B F89D F89E F8A0 F8A1 + F8A3 F8A7 F8AB F8AE F8B0 F8B2 F8B3 F8B4 + F8B6 F8B7 F8B8 F8BB F8C3 F8C4 F8C5 F8C7 + F8C8 F8C9 F8CB F8D5 F8E1 F8DA F8DD F8E4 + F8E0 F8E2 F8E3 F8EE F8F1 F8F3 F8F4 F8F5 + F8F6 F8F7 F86D F86F F872 F873 F874 F877 + /; + +my @jamo_puajamo_A960 = qw/ + F794 F795 F796 F797 F799 F79A F79C F79D + F79F F7A0 F7A1 F7A2 F7A3 F7A4 F7A5 F7A9 + F7AA F7AC F7B9 F7BC F7BF F7CB F7DC F7E6 + F7EB F7F7 F7FA F7FD F800 + /; + +my @jamo_puajamo_D7B0 = qw/ + F822 F825 F829 F82A F82D F837 F83B F83E + F843 F847 F848 F849 F84A F852 F853 F854 + F855 F857 F858 F85A F85C F85F F861 + /; + +my @jamo_puajamo_D7CB = qw/ + F879 F87D F882 F883 F885 F886 F887 F888 + F889 F88A F88D F88F F894 F898 F89A F89C + F8A2 F8A8 F8A9 F8AC F8AD F8AF F8B1 F8B5 + F8BA F8BC F8BD F8BE F8C0 F8C1 F8C2 F8CA + F8CC F8CE F8CF F8D0 F8D1 F8D2 F8D3 F8D4 + F8D6 F8D7 F8DB F8E5 F8E7 F8E8 F8E9 F8EF + F8F0 + /; + +### +### parse options +### +my ( + %args, + @IDXfiles, + $istfile, + $indfile, + $logfile, + $idx0 + ); +getopts('kcgilo:p:qrs:t:LT',\%args); +@IDXfiles = @ARGV or die "No .idx file specified!\n"; + +if ($args{s}) { + $istfile = $args{s}; + $istfile =~ s/(\.ist)?$/\.ist/; +} + +$idx0 = $IDXfiles[0]; +$idx0 =~s/\.idx$//; + +$indfile = $args{o} || $idx0; +$indfile =~ /(\..+?)$/ or $indfile .= ".ind"; + +$logfile = $args{t} || $idx0; +$logfile =~ /(\..+?)$/ or $logfile .= ".ilg"; + +foreach my $file (@IDXfiles) { + $file =~ /(\..+?)$/ or $file .= ".idx"; +} + +### +### read .ist file +### +my $ist_heading_flag = 0; +my $ist_heading_prefix = ''; +my $ist_heading_suffix = ''; +my $ist_group_skip = '\indexspace'; +my $ist_item_0 = '\item '; +my $ist_delim_0 = ', '; +my $ist_keyword = '\indexentry'; +my $ist_actual = '@'; +my $ist_encap = '|'; +my $ist_level = '!'; +my $ist_quote = '"'; +my $ist_arg_open = '{'; +my $ist_arg_close = '}'; +my $ist_postamble = '\end{theindex}'; + +if ($istfile) { + $istfile = `kpsewhich $istfile`; + chomp $istfile; + open IST,"<:utf8",$istfile or die "$args{s} : $!\n"; + while () { + s/\%.*//; + s/\\n\b//g; + s/\\\\/\\/g; + if (/headings_flag\s+(.+)/) { + $ist_heading_flag = $1; + } elsif (/heading_prefix\s+"(.*)"/) { + $ist_heading_prefix = $1; + } elsif (/heading_suffix\s+"(.*)"/) { + $ist_heading_suffix = $1; + } elsif (/group_skip\s+"(.*)"/) { + $ist_group_skip = $1; + } elsif (/item_0\s+"(.*)"/) { + $ist_item_0 = $1; + } elsif (/delim_0\s+"(.*)"/) { + $ist_delim_0 = $1; + } elsif (/keyword\s+"(.*)"/) { + $ist_keyword = $1; + } elsif (/actual\s+'(.*)'/) { + $ist_actual = $1; + } elsif (/encap\s+'(.*)'/) { + $ist_encap = $1; + } elsif (/level\s+'(.*)'/) { + $ist_level = $1; + } elsif (/quote\s+'(.*)'/) { + $ist_quote = $1; + } elsif (/arg_open\s+'(.*)'/) { + $ist_arg_open = $1; + } elsif (/arg_close\s+'(.*)'/) { + $ist_arg_close = $1; + } elsif (/postamble\s+"(.*)"/) { + $ist_postamble = $1; + } + } + close IST; +} + + +# prepare to run makeindex +my $makeindexoption = "-i -o $indfile -t $logfile"; +foreach ('c','l','q','r','L','g','T') { + $makeindexoption .= " -$_" if $args{$_}; +} +$makeindexoption .= " -s $istfile" if $args{s}; +$makeindexoption .= " -p $args{p}" if $args{p}; + +### +### read .idx files +### +my ( @idxarr, %idxhash ); +foreach my $file (@IDXfiles) { + open IDX,"<:utf8",$file or die "$file : $!\n"; + while () { + s/\^\^([0-9a-f]{2})/pack "U0C", hex $1/ge; + s/\\unihangulchar\s*\{(\d+)\}/chr $1/ge; + + # \indexentry{ ..... }{ .. } + # -> $pre $body $post + if (/(\Q$ist_keyword\E\s*\Q$ist_arg_open\E) + (.*?[^\Q$ist_quote\E]) + (\Q$ist_arg_close$ist_arg_open\E.+?\Q$ist_arg_close\E) + $/x) { + my($pre,$body,$post) = ($1,$2,$3); + + # \indexentry{ ..... | .. }{ .. } + # -> $pre $body $post + my @xbody = split /(?0; $i--) { + $post = $ist_encap.$xbody[$i].$post; + } + $body = $xbody[0]; + + # !을 경계로 가름. + @xbody = split /(?> 8 and die "\nmakeindex failed!\n"; + +### +### read .ind file and group hangul items +### +my @indarr; +my $indgroup = 0; +# (indgroup) 0 = header; +# 1 = latin; +# 2 = hangul; +# 3 = footer. + +my $cho = -1; + +open IND,"<:utf8",$indfile or die "$indfile : $!\n"; +while () { + if (/\Q$ist_postamble\E/) { + $indgroup = 3; + } elsif ($ist_heading_flag and + /\Q$ist_heading_prefix\E/) { + if (/\Q$ist_heading_prefix\E.+?\Q$ist_heading_suffix\E/) { + ### 깨진 글자가 index head로 하나 들어가는데 이를 제거하기 위해 + ### 복잡하게 이중으로 조건검사를 하였다. 깨진 글자는 두번째 조건을 + ### 통과하지 못한다. + $indgroup++ if $indgroup == 0; + } else { + next; + } + } elsif (/\Q$ist_item_0\E(.+?)(\Q$ist_delim_0\E|$)/ ) { + my $body = $1; + if ( $idxhash{$body} =~ /[\x{F785}-\x{F8F7}]/ ) { + $indgroup++ if $indgroup == 1; + my $first = get_hindexhead_num($idxhash{$body}); + if ($first != $cho) { + my $tmp = ''; + $tmp .= "\n$ist_group_skip\n" if $cho >= 0; + $tmp .= "$ist_heading_prefix\\hindexhead{$first}$ist_heading_suffix\n" + if ($ist_heading_flag); + $_ = $tmp.$_; + $cho = $first; + } + } else { + $indgroup++ if $indgroup == 0; + } + } + push @{$indarr[$indgroup]} , $_; +} +close IND; + + +open IND,">:utf8",$indfile or die "$indfile : $!\n"; +if ($args{k}) { + # latin의 마지막 indexspace를 hangul 마지막으로 이동. (-k 옵션에서) + if ( @{ $indarr[1] } and @{ $indarr[2] } ) { + my $tmp; + $tmp = pop @{ $indarr[1] } + until ( $tmp =~ /\Q$ist_group_skip\E/ ); + push @{ $indarr[2] },$tmp; + } + + for my $i (0,2,1,3) { + for my $j (0 .. $#{$indarr[$i]} ) { + print IND $indarr[$i][$j]; + } + } +} else { + for my $i (0..3) { + for my $j (0 .. $#{$indarr[$i]} ) { + print IND $indarr[$i][$j]; + } + } +} +close IND; + + +########## SUBROUTINES ########## + +sub get_hindexhead_num { + my $fn = ord shift; + + for ( my $i=0; $i<@hangul_grouping; $i++ ) { + + my $divval = $fn / hex($hangul_grouping[$i]); + if ( $divval < 1 ) { + return --$i; + } + } +} + +sub symbolize_first { + my $first = shift; + my $symfirst = ''; + + for (unpack("U0C*", $first)) { + $symfirst .= sprintf "^^%02x",$_; + } + + return $symfirst; +} + +sub syllable_to_jamo_chr { + my $syl = ord shift; + my $cho = ($syl - 0xac00) / (21 * 28) + 0x1100; + my $jung = ($syl - 0xac00) % (21 * 28) / 28 + 0x1161; + my $jong = ($syl - 0xac00) % 28; + if ($jong) { + $jong += 0x11a7; + return chr($cho).chr($jung).chr($jong); + } + return chr($cho).chr($jung); +} + +sub cjamo_to_jamo_chr { + my $cj = ord shift; + $cj = hex $cjamo_jamo[$cj - 0x3131]; + if($cj <= 0x115f) { ### choseong: append U+F86A + return chr($cj).chr(0x1160).chr(0xF86A); + } + elsif($cj >= 0x1160 and $cj <= 0x11a2) { ### jungseong: append U+F86A + return chr(0x115f).chr($cj).chr(0xF86A); + } + else { ### jongseong + return chr(0x115f).chr(0x1160).chr($cj); + } +} + +sub insert_fillers { + my $cho = "\x{1100}-\x{115F}\x{A960}-\x{A97C}"; + my $jung = "\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}"; + my $jong = "\x{11A8}-\x{11FF}\x{D7CB}-\x{D7FB}\x{F86A}"; # include Tf + s/([$cho])([$jong])/$1\x{1160}\x{115F}\x{1160}$2/g; + s/([$cho])(?![$jung])/$1\x{1160}/g; + s/(?; + close TAB; + + chomp @HJHG; + return @HJHG; +} + +sub compose_jamo { + s/\x{1107}\x{1107}\x{110B}/\x{112C}/g; + s/\x{1107}\x{1109}\x{1100}/\x{1122}/g; + s/\x{1107}\x{1109}\x{1103}/\x{1123}/g; + s/\x{1107}\x{1109}\x{1107}/\x{1124}/g; + s/\x{1107}\x{1109}\x{1109}/\x{1125}/g; + s/\x{1107}\x{1109}\x{110C}/\x{1126}/g; + s/\x{1109}\x{1107}\x{1100}/\x{1133}/g; + s/\x{1109}\x{1109}\x{1109}/\x{1134}/g; + s/\x{1105}\x{1100}\x{1100}/\x{A965}/g; + s/\x{1105}\x{1103}\x{1103}/\x{A967}/g; + s/\x{1105}\x{1107}\x{1107}/\x{A96A}/g; + s/\x{1105}\x{1107}\x{110B}/\x{A96B}/g; + s/\x{1107}\x{1109}\x{1110}/\x{A972}/g; + s/\x{1109}\x{1109}\x{1107}/\x{A975}/g; + s/\x{110C}\x{110C}\x{1112}/\x{A978}/g; + s/\x{1100}\x{1100}/\x{1101}/g; + s/\x{1102}\x{1100}/\x{1113}/g; + s/\x{1102}\x{1102}/\x{1114}/g; + s/\x{1102}\x{1103}/\x{1115}/g; + s/\x{1102}\x{1107}/\x{1116}/g; + s/\x{1103}\x{1100}/\x{1117}/g; + s/\x{1103}\x{1103}/\x{1104}/g; + s/\x{1105}\x{1102}/\x{1118}/g; + s/\x{1105}\x{1105}/\x{1119}/g; + s/\x{1105}\x{110B}/\x{111B}/g; + s/\x{1105}\x{1112}/\x{111A}/g; + s/\x{1106}\x{1107}/\x{111C}/g; + s/\x{1106}\x{110B}/\x{111D}/g; + s/\x{1107}\x{1100}/\x{111E}/g; + s/\x{1107}\x{1102}/\x{111F}/g; + s/\x{1107}\x{1103}/\x{1120}/g; + s/\x{1107}\x{1107}/\x{1108}/g; + s/\x{1107}\x{1109}/\x{1121}/g; + s/\x{1107}\x{110A}/\x{1125}/g; + s/\x{1107}\x{110B}/\x{112B}/g; + s/\x{1107}\x{110C}/\x{1127}/g; + s/\x{1107}\x{110E}/\x{1128}/g; + s/\x{1107}\x{1110}/\x{1129}/g; + s/\x{1107}\x{1111}/\x{112A}/g; + s/\x{1107}\x{112B}/\x{112C}/g; + s/\x{1107}\x{112D}/\x{1122}/g; + s/\x{1107}\x{112F}/\x{1123}/g; + s/\x{1107}\x{1132}/\x{1124}/g; + s/\x{1107}\x{1136}/\x{1126}/g; + s/\x{1108}\x{110B}/\x{112C}/g; + s/\x{1109}\x{1100}/\x{112D}/g; + s/\x{1109}\x{1102}/\x{112E}/g; + s/\x{1109}\x{1103}/\x{112F}/g; + s/\x{1109}\x{1105}/\x{1130}/g; + s/\x{1109}\x{1106}/\x{1131}/g; + s/\x{1109}\x{1107}/\x{1132}/g; + s/\x{1109}\x{1109}/\x{110A}/g; + s/\x{1109}\x{110A}/\x{1134}/g; + s/\x{1109}\x{110B}/\x{1135}/g; + s/\x{1109}\x{110C}/\x{1136}/g; + s/\x{1109}\x{110E}/\x{1137}/g; + s/\x{1109}\x{110F}/\x{1138}/g; + s/\x{1109}\x{1110}/\x{1139}/g; + s/\x{1109}\x{1111}/\x{113A}/g; + s/\x{1109}\x{1112}/\x{113B}/g; + s/\x{1109}\x{111E}/\x{1133}/g; + s/\x{110A}\x{1109}/\x{1134}/g; + s/\x{110B}\x{1100}/\x{1141}/g; + s/\x{110B}\x{1103}/\x{1142}/g; + s/\x{110B}\x{1106}/\x{1143}/g; + s/\x{110B}\x{1107}/\x{1144}/g; + s/\x{110B}\x{1109}/\x{1145}/g; + s/\x{110B}\x{110B}/\x{1147}/g; + s/\x{110B}\x{110C}/\x{1148}/g; + s/\x{110B}\x{110E}/\x{1149}/g; + s/\x{110B}\x{1110}/\x{114A}/g; + s/\x{110B}\x{1111}/\x{114B}/g; + s/\x{110B}\x{1140}/\x{1146}/g; + s/\x{110C}\x{110B}/\x{114D}/g; + s/\x{110C}\x{110C}/\x{110D}/g; + s/\x{110E}\x{110F}/\x{1152}/g; + s/\x{110E}\x{1112}/\x{1153}/g; + s/\x{1111}\x{1107}/\x{1156}/g; + s/\x{1111}\x{110B}/\x{1157}/g; + s/\x{1112}\x{1112}/\x{1158}/g; + s/\x{1121}\x{1100}/\x{1122}/g; + s/\x{1121}\x{1103}/\x{1123}/g; + s/\x{1121}\x{1107}/\x{1124}/g; + s/\x{1121}\x{1109}/\x{1125}/g; + s/\x{1121}\x{110C}/\x{1126}/g; + s/\x{1132}\x{1100}/\x{1133}/g; + s/\x{113C}\x{113C}/\x{113D}/g; + s/\x{113E}\x{113E}/\x{113F}/g; + s/\x{114E}\x{114E}/\x{114F}/g; + s/\x{1150}\x{1150}/\x{1151}/g; + s/\x{1100}\x{1103}/\x{115A}/g; + s/\x{1102}\x{1109}/\x{115B}/g; + s/\x{1102}\x{110C}/\x{115C}/g; + s/\x{1102}\x{1112}/\x{115D}/g; + s/\x{1103}\x{1105}/\x{115E}/g; + s/\x{1103}\x{1106}/\x{A960}/g; + s/\x{1103}\x{1107}/\x{A961}/g; + s/\x{1103}\x{1109}/\x{A962}/g; + s/\x{1103}\x{110C}/\x{A963}/g; + s/\x{1105}\x{1100}/\x{A964}/g; + s/\x{A964}\x{1100}/\x{A965}/g; + s/\x{1105}\x{1101}/\x{A965}/g; + s/\x{1105}\x{1103}/\x{A966}/g; + s/\x{A966}\x{1103}/\x{A967}/g; + s/\x{1105}\x{1104}/\x{A967}/g; + s/\x{1105}\x{1106}/\x{A968}/g; + s/\x{1105}\x{1107}/\x{A969}/g; + s/\x{A969}\x{1107}/\x{A96A}/g; + s/\x{1105}\x{1108}/\x{A96A}/g; + s/\x{1105}\x{112B}/\x{A96B}/g; + s/\x{1105}\x{1109}/\x{A96C}/g; + s/\x{1105}\x{110C}/\x{A96D}/g; + s/\x{1105}\x{110F}/\x{A96E}/g; + s/\x{1106}\x{1100}/\x{A96F}/g; + s/\x{1106}\x{1103}/\x{A970}/g; + s/\x{1106}\x{1109}/\x{A971}/g; + s/\x{1121}\x{1110}/\x{A972}/g; + s/\x{1107}\x{1139}/\x{A972}/g; + s/\x{1107}\x{110F}/\x{A973}/g; + s/\x{1107}\x{1112}/\x{A974}/g; + s/\x{110A}\x{1107}/\x{A975}/g; + s/\x{1109}\x{1132}/\x{A975}/g; + s/\x{110B}\x{1105}/\x{A976}/g; + s/\x{110B}\x{1112}/\x{A977}/g; + s/\x{110D}\x{1112}/\x{A978}/g; + s/\x{1110}\x{1110}/\x{A979}/g; + s/\x{1111}\x{1112}/\x{A97A}/g; + s/\x{1112}\x{1109}/\x{A97B}/g; + s/\x{1159}\x{1159}/\x{A97C}/g; + s/\x{1169}\x{1161}\x{1175}/\x{116B}/g; + s/\x{1169}\x{1165}\x{1175}/\x{1180}/g; + s/\x{1169}\x{1167}\x{1175}/\x{1181}/g; + s/\x{116D}\x{1163}\x{1175}/\x{1185}/g; + s/\x{116E}\x{1161}\x{1175}/\x{118A}/g; + s/\x{116E}\x{1165}\x{1173}/\x{118B}/g; + s/\x{116E}\x{1165}\x{1175}/\x{1170}/g; + s/\x{116E}\x{1167}\x{1175}/\x{118C}/g; + s/\x{1172}\x{1165}\x{1175}/\x{1190}/g; + s/\x{1172}\x{1167}\x{1175}/\x{1192}/g; + s/\x{1173}\x{1175}\x{116E}/\x{1197}/g; + s/\x{1169}\x{1163}\x{1175}/\x{11A7}/g; + s/\x{1169}\x{1169}\x{1175}/\x{D7B1}/g; + s/\x{116D}\x{1161}\x{1175}/\x{D7B3}/g; + s/\x{116E}\x{1175}\x{1175}/\x{D7B6}/g; + s/\x{1172}\x{1161}\x{1175}/\x{D7B7}/g; + s/\x{1173}\x{1165}\x{1175}/\x{D7BB}/g; + s/\x{1175}\x{1163}\x{1169}/\x{D7BD}/g; + s/\x{1175}\x{1163}\x{1175}/\x{D7BE}/g; + s/\x{1175}\x{1167}\x{1175}/\x{D7C0}/g; + s/\x{1175}\x{1169}\x{1175}/\x{D7C1}/g; + s/\x{119E}\x{1165}\x{1175}/\x{D7C6}/g; + s/\x{1161}\x{1169}/\x{1176}/g; + s/\x{1161}\x{116E}/\x{1177}/g; + s/\x{1161}\x{1175}/\x{1162}/g; + s/\x{1163}\x{1169}/\x{1178}/g; + s/\x{1163}\x{116D}/\x{1179}/g; + s/\x{1163}\x{1175}/\x{1164}/g; + s/\x{1165}\x{1169}/\x{117A}/g; + s/\x{1165}\x{116E}/\x{117B}/g; + s/\x{1165}\x{1173}/\x{117C}/g; + s/\x{1165}\x{1175}/\x{1166}/g; + s/\x{1167}\x{1169}/\x{117D}/g; + s/\x{1167}\x{116E}/\x{117E}/g; + s/\x{1167}\x{1175}/\x{1168}/g; + s/\x{1169}\x{1161}/\x{116A}/g; + s/\x{1169}\x{1162}/\x{116B}/g; + s/\x{1169}\x{1165}/\x{117F}/g; + s/\x{1169}\x{1166}/\x{1180}/g; + s/\x{1169}\x{1168}/\x{1181}/g; + s/\x{1169}\x{1169}/\x{1182}/g; + s/\x{1169}\x{116E}/\x{1183}/g; + s/\x{1169}\x{1175}/\x{116C}/g; + s/\x{116A}\x{1175}/\x{116B}/g; + s/\x{116D}\x{1163}/\x{1184}/g; + s/\x{116D}\x{1164}/\x{1185}/g; + s/\x{116D}\x{1167}/\x{1186}/g; + s/\x{116D}\x{1169}/\x{1187}/g; + s/\x{116D}\x{1175}/\x{1188}/g; + s/\x{116E}\x{1161}/\x{1189}/g; + s/\x{116E}\x{1162}/\x{118A}/g; + s/\x{116E}\x{1165}/\x{116F}/g; + s/\x{116E}\x{1166}/\x{1170}/g; + s/\x{116E}\x{1168}/\x{118C}/g; + s/\x{116E}\x{116E}/\x{118D}/g; + s/\x{116E}\x{1175}/\x{1171}/g; + s/\x{116E}\x{117C}/\x{118B}/g; + s/\x{116F}\x{1173}/\x{118B}/g; + s/\x{116F}\x{1175}/\x{1170}/g; + s/\x{1172}\x{1161}/\x{118E}/g; + s/\x{1172}\x{1165}/\x{118F}/g; + s/\x{1172}\x{1166}/\x{1190}/g; + s/\x{1172}\x{1167}/\x{1191}/g; + s/\x{1172}\x{1168}/\x{1192}/g; + s/\x{1172}\x{116E}/\x{1193}/g; + s/\x{1172}\x{1175}/\x{1194}/g; + s/\x{1173}\x{116E}/\x{1195}/g; + s/\x{1173}\x{1173}/\x{1196}/g; + s/\x{1173}\x{1175}/\x{1174}/g; + s/\x{1173}\x{119B}/\x{1197}/g; + s/\x{1174}\x{116E}/\x{1197}/g; + s/\x{1175}\x{1161}/\x{1198}/g; + s/\x{1175}\x{1163}/\x{1199}/g; + s/\x{1175}\x{1169}/\x{119A}/g; + s/\x{1175}\x{116E}/\x{119B}/g; + s/\x{1175}\x{1173}/\x{119C}/g; + s/\x{1175}\x{119E}/\x{119D}/g; + s/\x{117F}\x{1175}/\x{1180}/g; + s/\x{1184}\x{1175}/\x{1185}/g; + s/\x{1189}\x{1175}/\x{118A}/g; + s/\x{118F}\x{1175}/\x{1190}/g; + s/\x{1191}\x{1175}/\x{1192}/g; + s/\x{119E}\x{1165}/\x{119F}/g; + s/\x{119E}\x{116E}/\x{11A0}/g; + s/\x{119E}\x{1175}/\x{11A1}/g; + s/\x{119E}\x{119E}/\x{11A2}/g; + s/\x{1161}\x{1173}/\x{11A3}/g; + s/\x{1163}\x{116E}/\x{11A4}/g; + s/\x{1167}\x{1163}/\x{11A5}/g; + s/\x{1169}\x{1163}/\x{11A6}/g; + s/\x{1169}\x{1164}/\x{11A7}/g; + s/\x{1169}\x{1167}/\x{D7B0}/g; + s/\x{1182}\x{1175}/\x{D7B1}/g; + s/\x{1169}\x{116C}/\x{D7B1}/g; + s/\x{116D}\x{1161}/\x{D7B2}/g; + s/\x{116D}\x{1162}/\x{D7B3}/g; + s/\x{116D}\x{1165}/\x{D7B4}/g; + s/\x{116E}\x{1167}/\x{D7B5}/g; + s/\x{1171}\x{1175}/\x{D7B6}/g; + s/\x{116E}\x{D7C4}/\x{D7B6}/g; + s/\x{1172}\x{1162}/\x{D7B7}/g; + s/\x{1172}\x{1169}/\x{D7B8}/g; + s/\x{1173}\x{1161}/\x{D7B9}/g; + s/\x{1173}\x{1165}/\x{D7BA}/g; + s/\x{1173}\x{1166}/\x{D7BB}/g; + s/\x{1173}\x{1169}/\x{D7BC}/g; + s/\x{1199}\x{1169}/\x{D7BD}/g; + s/\x{1175}\x{1178}/\x{D7BD}/g; + s/\x{1175}\x{1164}/\x{D7BE}/g; + s/\x{1175}\x{1167}/\x{D7BF}/g; + s/\x{1175}\x{1168}/\x{D7C0}/g; + s/\x{119A}\x{1175}/\x{D7C1}/g; + s/\x{1175}\x{116C}/\x{D7C1}/g; + s/\x{1175}\x{116D}/\x{D7C2}/g; + s/\x{1175}\x{1172}/\x{D7C3}/g; + s/\x{1175}\x{1175}/\x{D7C4}/g; + s/\x{119E}\x{1161}/\x{D7C5}/g; + s/\x{119E}\x{1166}/\x{D7C6}/g; + s/\x{11A8}\x{11BA}\x{11A8}/\x{11C4}/g; + s/\x{11AF}\x{11A8}\x{11BA}/\x{11CC}/g; + s/\x{11AF}\x{11AE}\x{11C2}/\x{11CF}/g; + s/\x{11AF}\x{11B7}\x{11A8}/\x{11D1}/g; + s/\x{11AF}\x{11B7}\x{11BA}/\x{11D2}/g; + s/\x{11AF}\x{11B8}\x{11BA}/\x{11D3}/g; + s/\x{11AF}\x{11B8}\x{11BC}/\x{11D5}/g; + s/\x{11AF}\x{11B8}\x{11C2}/\x{11D4}/g; + s/\x{11AF}\x{11BA}\x{11BA}/\x{11D6}/g; + s/\x{11B7}\x{11BA}\x{11BA}/\x{11DE}/g; + s/\x{11BC}\x{11A8}\x{11A8}/\x{11ED}/g; # legacy enc + s/\x{11F0}\x{11A8}\x{11A8}/\x{11ED}/g; + s/\x{11AE}\x{11AE}\x{11B8}/\x{D7CE}/g; + s/\x{11AE}\x{11BA}\x{11A8}/\x{D7D1}/g; + s/\x{11AF}\x{11A8}\x{11A8}/\x{D7D5}/g; + s/\x{11AF}\x{11A8}\x{11C2}/\x{D7D6}/g; + s/\x{11AF}\x{11AF}\x{11BF}/\x{D7D7}/g; + s/\x{11AF}\x{11B7}\x{11C2}/\x{D7D8}/g; + s/\x{11AF}\x{11B8}\x{11AE}/\x{D7D9}/g; + s/\x{11AF}\x{11B8}\x{11C1}/\x{D7DA}/g; + s/\x{11AF}\x{11F9}\x{11C2}/\x{D7DC}/g; + s/\x{11B7}\x{11AB}\x{11AB}/\x{D7DF}/g; + s/\x{11B7}\x{11B8}\x{11BA}/\x{D7E1}/g; + s/\x{11B8}\x{11AF}\x{11C1}/\x{D7E4}/g; + s/\x{11B8}\x{11BA}\x{11AE}/\x{D7E7}/g; + s/\x{11BA}\x{11B8}\x{11BC}/\x{D7EB}/g; + s/\x{11BA}\x{11BA}\x{11A8}/\x{D7EC}/g; + s/\x{11BA}\x{11BA}\x{11AE}/\x{D7ED}/g; + s/\x{11EB}\x{11B8}\x{11BC}/\x{D7F4}/g; + s/\x{11BD}\x{11B8}\x{11B8}/\x{D7F8}/g; + s/\x{11A8}\x{11A8}/\x{11A9}/g; + s/\x{11A8}\x{11AF}/\x{11C3}/g; + s/\x{11A8}\x{11BA}/\x{11AA}/g; + s/\x{11A8}\x{11E7}/\x{11C4}/g; + s/\x{11AA}\x{11A8}/\x{11C4}/g; + s/\x{11AB}\x{11A8}/\x{11C5}/g; + s/\x{11AB}\x{11AE}/\x{11C6}/g; + s/\x{11AB}\x{11BA}/\x{11C7}/g; + s/\x{11AB}\x{11BD}/\x{11AC}/g; + s/\x{11AB}\x{11C0}/\x{11C9}/g; + s/\x{11AB}\x{11C2}/\x{11AD}/g; + s/\x{11AB}\x{11EB}/\x{11C8}/g; + s/\x{11AE}\x{11A8}/\x{11CA}/g; + s/\x{11AE}\x{11AF}/\x{11CB}/g; + s/\x{11AF}\x{11A8}/\x{11B0}/g; + s/\x{11AF}\x{11AA}/\x{11CC}/g; + s/\x{11AF}\x{11AB}/\x{11CD}/g; + s/\x{11AF}\x{11AE}/\x{11CE}/g; + s/\x{11AF}\x{11AF}/\x{11D0}/g; + s/\x{11AF}\x{11B7}/\x{11B1}/g; + s/\x{11AF}\x{11B8}/\x{11B2}/g; + s/\x{11AF}\x{11B9}/\x{11D3}/g; + s/\x{11AF}\x{11BA}/\x{11B3}/g; + s/\x{11AF}\x{11BB}/\x{11D6}/g; + s/\x{11AF}\x{11BF}/\x{11D8}/g; + s/\x{11AF}\x{11C0}/\x{11B4}/g; + s/\x{11AF}\x{11C1}/\x{11B5}/g; + s/\x{11AF}\x{11C2}/\x{11B6}/g; + s/\x{11AF}\x{11DA}/\x{11D1}/g; + s/\x{11AF}\x{11DD}/\x{11D2}/g; + s/\x{11AF}\x{11E5}/\x{11D4}/g; + s/\x{11AF}\x{11E6}/\x{11D5}/g; + s/\x{11AF}\x{11EB}/\x{11D7}/g; + s/\x{11AF}\x{11F9}/\x{11D9}/g; + s/\x{11B0}\x{11BA}/\x{11CC}/g; + s/\x{11B1}\x{11A8}/\x{11D1}/g; + s/\x{11B1}\x{11BA}/\x{11D2}/g; + s/\x{11B2}\x{11BA}/\x{11D3}/g; + s/\x{11B2}\x{11BC}/\x{11D5}/g; + s/\x{11B2}\x{11C2}/\x{11D4}/g; + s/\x{11B3}\x{11BA}/\x{11D6}/g; + s/\x{11B7}\x{11A8}/\x{11DA}/g; + s/\x{11B7}\x{11AF}/\x{11DB}/g; + s/\x{11B7}\x{11B8}/\x{11DC}/g; + s/\x{11B7}\x{11BA}/\x{11DD}/g; + s/\x{11B7}\x{11BB}/\x{11DE}/g; + s/\x{11B7}\x{11BC}/\x{11E2}/g; + s/\x{11B7}\x{11BE}/\x{11E0}/g; + s/\x{11B7}\x{11C2}/\x{11E1}/g; + s/\x{11B7}\x{11EB}/\x{11DF}/g; + s/\x{11B8}\x{11AF}/\x{11E3}/g; + s/\x{11B8}\x{11BA}/\x{11B9}/g; + s/\x{11B8}\x{11BC}/\x{11E6}/g; + s/\x{11B8}\x{11C1}/\x{11E4}/g; + s/\x{11B8}\x{11C2}/\x{11E5}/g; + s/\x{11BA}\x{11A8}/\x{11E7}/g; + s/\x{11BA}\x{11AE}/\x{11E8}/g; + s/\x{11BA}\x{11AF}/\x{11E9}/g; + s/\x{11BA}\x{11B8}/\x{11EA}/g; + s/\x{11BA}\x{11BA}/\x{11BB}/g; + s/\x{11BC}\x{11A8}/\x{11EC}/g; # legacy enc + s/\x{11F0}\x{11A8}/\x{11EC}/g; + s/\x{11BC}\x{11A9}/\x{11ED}/g; # legacy enc + s/\x{11F0}\x{11A9}/\x{11ED}/g; + s/\x{11BC}\x{11BC}/\x{11EE}/g; # legacy enc + s/\x{11F0}\x{11F0}/\x{11EE}/g; + s/\x{11BC}\x{11BF}/\x{11EF}/g; # legacy enc + s/\x{11F0}\x{11BF}/\x{11EF}/g; + s/\x{11C1}\x{11B8}/\x{11F3}/g; + s/\x{11C1}\x{11BC}/\x{11F4}/g; + s/\x{11C2}\x{11AB}/\x{11F5}/g; + s/\x{11C2}\x{11AF}/\x{11F6}/g; + s/\x{11C2}\x{11B7}/\x{11F7}/g; + s/\x{11C2}\x{11B8}/\x{11F8}/g; + s/\x{11CE}\x{11C2}/\x{11CF}/g; + s/\x{11DD}\x{11BA}/\x{11DE}/g; + s/\x{11EC}\x{11A8}/\x{11ED}/g; + s/\x{11F0}\x{11BA}/\x{11F1}/g; + s/\x{11F0}\x{11EB}/\x{11F2}/g; + s/\x{11A8}\x{11AB}/\x{11FA}/g; + s/\x{11A8}\x{11B8}/\x{11FB}/g; + s/\x{11A8}\x{11BE}/\x{11FC}/g; + s/\x{11A8}\x{11BF}/\x{11FD}/g; + s/\x{11A8}\x{11C2}/\x{11FE}/g; + s/\x{11AB}\x{11AB}/\x{11FF}/g; + s/\x{11AB}\x{11AF}/\x{D7CB}/g; + s/\x{11AB}\x{11BE}/\x{D7CC}/g; + s/\x{11AE}\x{11AE}/\x{D7CD}/g; + s/\x{D7CD}\x{11B8}/\x{D7CE}/g; + s/\x{11AE}\x{D7CF}/\x{D7CE}/g; + s/\x{11AE}\x{11B8}/\x{D7CF}/g; + s/\x{11AE}\x{11BA}/\x{D7D0}/g; + s/\x{D7D0}\x{11A8}/\x{D7D1}/g; + s/\x{11AE}\x{11E7}/\x{D7D1}/g; + s/\x{11AE}\x{11BD}/\x{D7D2}/g; + s/\x{11AE}\x{11BE}/\x{D7D3}/g; + s/\x{11AE}\x{11C0}/\x{D7D4}/g; + s/\x{11B0}\x{11A8}/\x{D7D5}/g; + s/\x{11AF}\x{11A9}/\x{D7D5}/g; + s/\x{11B0}\x{11C2}/\x{D7D6}/g; + s/\x{11AF}\x{11FE}/\x{D7D6}/g; + s/\x{11D0}\x{11BF}/\x{D7D7}/g; + s/\x{11AF}\x{11D8}/\x{D7D7}/g; + s/\x{11B1}\x{11C2}/\x{D7D8}/g; + s/\x{11AF}\x{11E1}/\x{D7D8}/g; + s/\x{11B2}\x{11AE}/\x{D7D9}/g; + s/\x{11AF}\x{D7E3}/\x{D7D9}/g; + s/\x{11B2}\x{11C1}/\x{D7DA}/g; + s/\x{11AF}\x{11E4}/\x{D7DA}/g; + s/\x{11AF}\x{11F0}/\x{D7DB}/g; + s/\x{11D9}\x{11C2}/\x{D7DC}/g; + s/\x{11AF}\x{11BC}/\x{D7DD}/g; + s/\x{11B7}\x{11AB}/\x{D7DE}/g; + s/\x{D7DE}\x{11AB}/\x{D7DF}/g; + s/\x{11B7}\x{11FF}/\x{D7DF}/g; + s/\x{11B7}\x{11B7}/\x{D7E0}/g; + s/\x{11DC}\x{11BA}/\x{D7E1}/g; + s/\x{11B7}\x{11B9}/\x{D7E1}/g; + s/\x{11B7}\x{11BD}/\x{D7E2}/g; + s/\x{11B8}\x{11AE}/\x{D7E3}/g; + s/\x{11E3}\x{11C1}/\x{D7E4}/g; + s/\x{11B8}\x{11B5}/\x{D7E4}/g; + s/\x{11B8}\x{11B7}/\x{D7E5}/g; + s/\x{11B8}\x{11B8}/\x{D7E6}/g; + s/\x{11B9}\x{11AE}/\x{D7E7}/g; + s/\x{11B8}\x{11E8}/\x{D7E7}/g; + s/\x{11B8}\x{11BD}/\x{D7E8}/g; + s/\x{11B8}\x{11BE}/\x{D7E9}/g; + s/\x{11BA}\x{11B7}/\x{D7EA}/g; + s/\x{11EA}\x{11BC}/\x{D7EB}/g; + s/\x{11BA}\x{11E6}/\x{D7EB}/g; + s/\x{11BB}\x{11A8}/\x{D7EC}/g; + s/\x{11BA}\x{11E7}/\x{D7EC}/g; + s/\x{11BB}\x{11AE}/\x{D7ED}/g; + s/\x{11BA}\x{11E8}/\x{D7ED}/g; + s/\x{11BA}\x{11EB}/\x{D7EE}/g; + s/\x{11BA}\x{11BD}/\x{D7EF}/g; + s/\x{11BA}\x{11BE}/\x{D7F0}/g; + s/\x{11BA}\x{11C0}/\x{D7F1}/g; + s/\x{11BA}\x{11C2}/\x{D7F2}/g; + s/\x{11EB}\x{11B8}/\x{D7F3}/g; + s/\x{D7F3}\x{11BC}/\x{D7F4}/g; + s/\x{11EB}\x{11E6}/\x{D7F4}/g; + s/\x{11F0}\x{11B7}/\x{D7F5}/g; + s/\x{11F0}\x{11C2}/\x{D7F6}/g; + s/\x{11BD}\x{11B8}/\x{D7F7}/g; + s/\x{D7F7}\x{11B8}/\x{D7F8}/g; + s/\x{11BD}\x{D7E6}/\x{D7F8}/g; + s/\x{11BD}\x{11BD}/\x{D7F9}/g; + s/\x{11C1}\x{11BA}/\x{D7FA}/g; + s/\x{11C1}\x{11C0}/\x{D7FB}/g; +} + +sub jamo_to_puajamo { + s/([\x{1100}-\x{11FF}])/chr hex $jamo_puajamo_1100[ord($1)-0x1100]/ge; + s/([\x{A960}-\x{A97C}])/chr hex $jamo_puajamo_A960[ord($1)-0xa960]/ge; + s/([\x{D7B0}-\x{D7C6}])/chr hex $jamo_puajamo_D7B0[ord($1)-0xd7b0]/ge; + s/([\x{D7CB}-\x{D7FB}])/chr hex $jamo_puajamo_D7CB[ord($1)-0xd7cb]/ge; +} + +### EOF diff --git a/Master/texmf-dist/scripts/kotex-utils/ttf2kotexfont.pl b/Master/texmf-dist/scripts/kotex-utils/ttf2kotexfont.pl new file mode 100755 index 00000000000..0dea955460e --- /dev/null +++ b/Master/texmf-dist/scripts/kotex-utils/ttf2kotexfont.pl @@ -0,0 +1,818 @@ +#!/usr/bin/env perl + +# ttf2kotexfont.pl +# +# Copyright (c) 2003-2013 Dohyun Kim +# +# This work may be distributed and/or modified under the +# conditions of the LaTeX Project Public License, either version 1.3c +# of this license or (at your option) any later version. +# The latest version of this license is in +# http://www.latex-project.org/lppl.txt +# and version 1.3c or later is part of all distributions of LaTeX +# version 2006/05/20 or later. + +#use strict; +#use warnings; +use Getopt::Std; +use File::Copy; +use File::Path; + +# 저작권 정보 표시 +print "ttf2kotexfont v0.9 2007/07/03 \n", +"Copyright (c) 2003-2007 Dohyun Kim \n", +"Redistribution and use, with or without modification, are permitted\n", +"provided that this coryright notice is retained. If you redistribute\n", +"a modified version, please attach a note about what you have modified.\n\n"; + +# command line option을 읽어들임 +my %args; +getopts("pc:i:",\%args); +unless($args{c}) { + print <<"ENDOFHELP"; +Usage: $0 -c CONFIGFILE + $0 -c CONFIGFILE -i TEXMFROOT + + -c CONFIGFILE + obtain font-related configuration from CONFIGFILE and + make TFMs and settings for ko.TeX. needs ttf2tfm 1.5 or higher + -c CONFIGFILE -i TEXMFROOT + install generated files to TEXMFROOT directory according to TDS + +CONFIGFILE syntax example: + + FOUNDRY: xy + FONTmj: f=bt m=BTmedium.ttf b=BTbold.ttf l=BTlight.ttf + FONTgt: f=dt m=DTmedium.ttf b=DTbold.ttf + FONTtz: f=tz m=TZmedium.ttf + ... +ENDOFHELP + exit 1; +} + +# 사용자 설정파일을 읽어 %FONTS(hash of hash)에 저장 +my($foundry,%FONTS); +open FILE,$args{c} or die "$args{c}: $!\n"; +while() { + s/#.*//; + if(/FOUNDRY:\s*(\w+)/) { + $foundry = $1; + } + elsif(/FONT(\w+?):\s*(.*)/) { + foreach my $field ( split /\s+/,$2 ) { + my($key,$value) = split /=/,$field; + $FONTS{$1}{$key} = $value; + } + } +} +close FILE; + +# 사용자 설정을 체크 +error("FOUNDRY must have 1 or 2 byte length.") + if(!$foundry or length($foundry) >2); + +error("`m' field of FONTmj is not defined in `$args{c}'.") + unless $FONTS{mj}{'m'}; # \mjdefault는 반드시 있어야 함 + +foreach my $hlatex (keys %FONTS) { + # FONTxx의 xx는 영문 2글자만 허용 + error("`$hlatex' of `FONT$hlatex' must have 2 or 3 byte length.") + unless(length($hlatex) == 2 or length($hlatex) == 3); + + # \textrm 같은 라텍 고유 명령을 재정의하는 것을 방지 + error("`FONT$hlatex' is not a valid name.") if $hlatex =~ + /^(rm|sf|tt|md|bf|up|it|sc|sl|mu|pm|bb|yen|bar|kra|mho|ohm|won|div)$/; + + # f 필드가 지정되지 않았다면 FONTxx의 xx를 f 필드값으로 사용 + $FONTS{$hlatex}{f} = $hlatex unless $FONTS{$hlatex}{f}; +} + + +# define global variables +my $ttf2tfm = 'ttf2tfm'; +##### $ttf2tfm = 'echo'; +my $styname = $foundry.'ttf.sty'; +my $pkmap = $foundry.'ttf2pk.map'; +my $pkcfg = 'ttf2pk.cfg'; +my $cidmap = 'cid-'.$foundry.'ttf.map'; +my $dvipdfmxcfg = 'dvipdfmx.cfg'; +my $pdfmap = $foundry.'ttf-pdftex.map'; +my $pdfcfg = 'pdftex.cfg'; +my %SERIES = ( + 'm'=>['m','c'], + 'b'=>['b','bc'], + 'l'=>['l'], + ); +my $slant = 'o'; +my $cshape = '-e .92'; +my $oshape = '-s .167'; +my $bshape = '-b .15'; # for dvipdfmx fakebold feature +my @Wsh = qw/w s h/; +my $sansfonts = 'jgt|jsr|jnv|gt|tz|pg|gr|bm|yt|gl'; # for curemaphangulfamily() + +my(@StyMapHangul,@StyOther,@CidMap,@PkMap,@PdfMap); + + +# variables for HLaTeX +my $prefix = ''; +my $hlatexencoding = 'H'; +my $cmap = 'UniKSCms-UCS2-H'; +my $sfd = 'UKS-HLaTeX'; +my $opt = '-q -L KS-HLaTeX -P 3 -E 1'; +my $wancmap = 'KSCms-UHC-H'; +my $wansfd = 'KS-HLaTeX'; +my $wanopt = '-q -l -P 3 -E 5'; +my $texteststr = '^^b0^^a1^^b2^^e5^^b5^^cb^^b8^^b1^^ba^^f5^^bd^^db'. +'^^c0^^c1^^c3^^a7^^c5^^eb^^c8^^d1 ^^a8^^b1^^a1^^db^^aa^^a2^^a5^^d2'. +' ^^ca^^a1^^cc^^e5^^cf^^cb^^d2^^b1^^d4^^f5^^d7^^db^^da^^c1^^dd^^a7'. +'^^df^^eb^^e2^^d1^^e5^^b7^^e7^^fb^^ea^^e1^^ed^^c7^^f0^^ad^^f2^^f1'. +'^^f5^^d7^^f8^^bd^^fb^^a3^^fd^^e7'; +my $texstyname = 'hfont'; +my $euctexname = 'testeuc.tex'; +my $eucmjdefault = 'wmj'; +my $eucgtdefault = 'wgt'; +my $euctzdefault = 'wtt'; +my $testtexname = $euctexname; +my $encoding = $hlatexencoding ; + +domainprocess() unless $args{i}; + +$prefix = 'o'; +my $ucsencoding = 'LUC'; +$cmap = 'unicode'; # dvipdfmx 20040912 up is recommended +$sfd = 'UCS2'; +$opt = '-q -P 3 -E 1'; +$wancmap = 'KSCms-UHC-H'; +$wansfd = "UKS-UCS2"; +$wanopt = '-q -P 3 -E 5'; +$texteststr = '\\unihangulchar{47924}\\unihangulchar{44417}'. + '\\unihangulchar{54868} \\unihangulchar{44867}\\unihangulchar{51060} '. + '\\unihangulchar{54588}\\unihangulchar{50632}\\unihangulchar{49845}'. + '\\unihangulchar{45768}\\unihangulchar{45796}. \\unihangulchar{12298}'. + '\\unihangulchar{12593}\\unihangulchar{12800}\\unihangulchar{12896}'. + '\\unihangulchar{12299} \\unihangulchar{19968}\\unihangulchar{20108}'. + '\\unihangulchar{19977}\\unihangulchar{22235}'; +$texstyname = 'dhucs'; +my $utftexname = 'testutf.tex'; +my $utfmjdefault = 'unbt'; +my $utfgtdefault = 'ungt'; +my $utftzdefault = 'untz'; +$testtexname = $utftexname ; +$encoding = $ucsencoding ; + +domainprocess() unless $args{i}; + +doremainderprocess() unless $args{i}; + +exit 0 unless $args{i}; + +my $texmf = $args{i}; +my $ttfd = "$texmf/fonts/truetype/kotex/${foundry}ttf"; +my $latexd = "$texmf/tex/latex/kotex/${foundry}ttf/euc"; +my $styd = "$texmf/tex/latex/kotex/${foundry}ttf"; +my $dhucsd = "$texmf/tex/latex/kotex/${foundry}ttf/utf"; +my $euctfmd = "$texmf/fonts/tfm/kotex/${foundry}ttf/euc"; +my $utftfmd = "$texmf/fonts/tfm/kotex/${foundry}ttf/utf"; +my $ttf2pkd = "$texmf/fonts/map/ttf2pk/kotex/${foundry}ttf"; +my $dvipdfmd = "$texmf/fonts/map/dvipdfm/kotex/${foundry}ttf"; +my $pdftexd = "$texmf/fonts/map/pdftex/kotex/${foundry}ttf"; +my $eucpdftexencd = "$texmf/fonts/enc/kotex/${foundry}ttf/euc"; +my $utfpdftexencd = "$texmf/fonts/enc/kotex/${foundry}ttf/utf"; +my $pdfcfgd = "$texmf/pdftex/config"; +my $ttf2pkcfgd = "$texmf/ttf2pk/base"; +my $dvipdfmxcfgd = "$texmf/dvipdfmx"; + +installfiles(); + +sub installfiles { + error("Cannot find $styname, $pkmap or $cidmap in current directory.\n". + "Run $0 without -i option before installing.") + unless(-e $styname and -e $pkmap and -e $cidmap); + + + unless(mkpath($texmf)) { + print + "Some error occured while making $texmf.\n", + "It seems that the directory already exists.\n", + "Installing into an existing directory is very DANGEROUS!\n", + "Any file of the same name will be overwritten without notice.\n", + "Do you really want to install files into $texmf? [yes/no]: "; + my $answer = ; + exit 1 unless $answer =~ /yes/; + } + + mymove($styd,$styname); + mymove($ttf2pkd,$pkmap); + mymove($dvipdfmd,$cidmap); + mymove($pdftexd,$pdfmap) ; + + foreach my $hlatex (keys %FONTS) { + next unless $FONTS{$hlatex}{f}; + my $font = $foundry.$FONTS{$hlatex}{f}; + my $ttcount = 0; + + foreach my $mbl (keys %SERIES) { + my $ttf = $FONTS{$hlatex}{$mbl}; + ($ttf) = parsettf($ttf); + next unless $ttf; + ++$ttcount; + + mymove("$ttfd",$ttf) if -e $ttf; + + if ($args{p}) { + mymove("$eucpdftexencd/$font", + glob("$font$SERIES{$mbl}[0]*.enc")); + mymove("$utfpdftexencd/$font", + glob("$prefix$font$SERIES{$mbl}[0]*.enc")); + } + + foreach my $ser (@{$SERIES{$mbl}}) { + mymove("$euctfmd/$font",glob("$font$ser*.tfm")); + mymove("$utftfmd/$font",glob("$prefix$font$ser*.tfm")); + } + } # loop for ttfs ends here + + if($ttcount) { + foreach my $wsh (@Wsh) { + mymove($latexd,"$hlatexencoding$wsh$font.fd"); + } + mymove($dhucsd,"$ucsencoding$font.fd") + if -e "$ucsencoding$font.fd"; + } + } # loop for families ends here + + addtocfg("f $cidmap",$dvipdfmxcfg,$dvipdfmxcfgd) or print + "Failed!\n Add `f $cidmap' at the end of $dvipdfmxcfg manually.\n"; + + addtocfg("map +$pkmap",$pkcfg,$ttf2pkcfgd) or print + "Failed!\n Add `map +$pkmap' at th end of $pkcfg manually.\n"; + + if($args{p}) { + addtocfg("map +$pdfmap",$pdfcfg,$pdfcfgd) or print + "Failed!\n Add `map +$pdfmap' at the end of $pdfcfg manually.\n"; + } + + print + "\nThe followings have to be done manually:\n", + "1. register `$texmf' as the first TEXMF root directory\n", + " in texmf.cnf or in MikTeX Options.\n", + "2. run `mktexlsr'.\n\n", + "Happy TeX'ing!\a\n"; +} + +sub mymove { + my($dest,@Files) = @_; + + mkpath $dest; + foreach my $file (@Files) { + print "$dest/$file\n"; + move($file,$dest) or die "$file: $!\n"; + } +} + + +sub doremainderprocess { + if(@PdfMap) { + open MAP,">$pdfmap" or die "$pdfmap: $!\n"; + print MAP @PdfMap; + close MAP; + } + + open MAP,">$cidmap" or die "$cidmap: $!\n"; + print MAP @CidMap; + close MAP; + + open MAP,">$pkmap" or die "$pkmap: $!\n"; + print MAP @PkMap; + close MAP; + + printstyfile(@StyMapHangul,@StyOther); + + unless(addtocfg("f $cidmap",$dvipdfmxcfg,'.')) { + open CFG,">$dvipdfmxcfg" or die "$dvipdfmxcfg: $!\n"; + print CFG "f $cidmap\n"; + close CFG; + } + unless(addtocfg("map +$pkmap",$pkcfg,'.')) { + open CFG,">$pkcfg" or die "$pkcfg: $!\n"; + print CFG "map +$pkmap\n"; + close CFG; + } + if(@PdfMap and $args{p} and !addtocfg("map +$pdfmap",$pdfcfg,'.')) { + open CFG,">$pdfcfg" or die "$pdfcfg: $!\n"; + print CFG "output_format 1\n", + "page_width 210 true mm\n", + "page_height 297 true mm\n", + "horigin 1 true in\n", + "vorigin 1 true in\n", + "map psfonts.map\n", + "map +$pdfmap\n"; + close CFG; + } + + ### cure maphangul + @StyMapHangul = curemaphangulfamily(@StyMapHangul); + print "\nTried to cure MapHangulFamily in $styname.\n", + "Edit $styname to your taste :\n", + @StyMapHangul; + move($styname,"$styname.orig") or + warn "Couldn't rename $styname to $styname.orig: $!\n"; + printstyfile(@StyMapHangul,@StyOther); + + $euctexname =~s/\.tex$//; + $utftexname =~s/\.tex$//; + print "\nAll done ...\n", + "Try `latex $euctexname && dvipdfmx $euctexname' for testing.\n", + "Try `latex $utftexname && dvipdfmx $utftexname' for testing.\a\n"; + +} + + +sub domainprocess { + my @TestTeX; + + foreach my $hlatex (keys %FONTS) { # loop for each FONTxx families + my $family = $FONTS{$hlatex}{f}; + my $font = $prefix.$foundry.$family; + my(%TeXFd,@UCSFd,$nohangul,$nohanja); + + foreach my $mbl (keys %SERIES) { # loop for TTFs + my($iswan,$isttc,$cidmapcnt,$ttf2pkcnt); + my $ttf = $FONTS{$hlatex}{$mbl}; + next unless $ttf; + ++$isttc if $ttf =~ /\.ttc\b/i; + $args{p} = 0 if $isttc; + + ($iswan,$cidmapcnt,$ttf2pkcnt) = + maketfmandmap($font,$ttf,@{$SERIES{$mbl}}); + + $mbl eq 'b' and $ttf eq $FONTS{$hlatex}{m} and + @{$cidmapcnt} = addfakeboldoption(@{$cidmapcnt}); + + push @CidMap,@{$cidmapcnt}; + push @PkMap,@{$ttf2pkcnt}; + if($args{p}) { + push @PdfMap,getpdfmapdata($font.$SERIES{$mbl}[0],$ttf) + unless $isttc; + } + else { + push @PdfMap,$font,$SERIES{$mbl}[0],"\@", + $iswan ? $wansfd : $sfd, + "\@\t<$ttf\tPidEid=3,", + $iswan ? "5" : "1", + "\n" unless $isttc; + } + + if($prefix) { + -e "$font${mbl}ac.tfm" or ++$nohangul; + -e "$font${mbl}4e.tfm" or ++$nohanja; + push @UCSFd,getucsfd($font,@{$SERIES{$mbl}}); + } + else { + foreach my $wsh (@Wsh) { # w/s/h 각 fd 내용을 %TeXFd에 저장 + push @{$TeXFd{$wsh}},gettexfd($font,$wsh,@{$SERIES{$mbl}}); + } + } + + push @TestTeX,gettexfilecnt($font,$mbl,$ttf,$hlatex); + } # loop for ttfs ends here + + my $fdname = $font; $fdname =~ s/^$prefix//; + + if($prefix and @UCSFd) { + open FD,">$encoding$fdname.fd" or + die "$encoding$fdname.fd: $!\n"; + print FD "\\DeclareFontFamily{$encoding}{$fdname}", + "{\\hyphenchar\\font\\m\@ne}\n",@UCSFd; + close FD; + } + else { + foreach my $wsh (keys %TeXFd) { # %TeXFd를 각 w/s/h .fd파일에 쓰기 + open FD,">$encoding$wsh$font.fd" or + die "$encoding$wsh$font.fd: $!\n"; + print FD "\\DeclareFontFamily{$encoding}{$wsh$font}", + "{\\hyphenchar\\font\\m\@ne}\n", @{$TeXFd{$wsh}}; + close FD; + } + } + + if(!$prefix and keys %TeXFd) { + push @StyMapHangul, + "\\MapHangulFamily{$family}{$font,$font,$font}\n"; + if($hlatex =~ /^(mj|gt|tz)$/) { + push @StyOther, + "\\renewcommand\\${hlatex}default{$family}\n"; + } + else { + push @StyOther, "\\DeclareRobustCommand\\${hlatex}family", + "{\\hfontfamily{$family}}\n", + "\\DeclareTextFontCommand\\text$hlatex", + "{\\${hlatex}family}\n"; + } + } + + if($prefix) { + if($hlatex eq 'mj') { + push @StyOther, + "\\def\\dhucs\@serifhangulfont\{", + $nohangul ? $utfmjdefault : $fdname, + "\}\\def\\dhucs\@serifhanjafont\{", + $nohanja ? $utfmjdefault : $fdname, + "\}\n"; + } + elsif($hlatex eq 'gt') { + push @StyOther, + "\\def\\dhucs\@sanshangulfont\{", + $nohangul ? $utfgtdefault : $fdname, + "\}\\def\\dhucs\@sanshanjafont\{", + $nohanja ? $utfgtdefault : $fdname, + "\}\n"; + } + elsif($hlatex eq 'tz') { + push @StyOther, + "\\def\\dhucs\@monohangulfont\{", + $nohangul ? $utftzdefault : $fdname, + "\}\\def\\dhucs\@monohanjafont\{", + $nohanja ? $utftzdefault : $fdname, + "\}\n"; + } + } + } # loop for families ends here + + unless($prefix) { + push @StyOther, + "\\DeclareErrorHFont{$encoding}{\\mjdefault}{m}{n}{10}\n", + "\\DeclareHFontSubstitution{$encoding}{\\mjdefault}{m}{n}\n", + "\\else\n" ; + } + + printtesttexfile(@TestTeX); + +} + +sub printtesttexfile { + my @texcnt = @_; + open TEX,">$testtexname" or die "$testtexname: $!\n"; + print TEX + "\\documentclass[a4paper]{article}\n", + "\\usepackage{",$texstyname,",${foundry}ttf}\n", + "\\usepackage{ifpdf}\n", + "\\ifpdf", + "\\expandafter\\ifx\\csname pdfmapfile\\endcsname\\relax\\else\n", + $prefix ? "\\pdfmapfile{=unttf-pdftex-dhucs.map}": "", + "\\pdfmapfile{=$pdfmap}\n", + "\\fi\\fi\n", + "\\begin{document}\n", + @texcnt, + "\\end{document}\n"; + close TEX; +} + + +sub printstyfile { + my(@stydata) = @_; + + open STY,">$styname" or die "$styname: $!\n"; + print STY "%%% $styname\n", + "%%%\n", + "%%% Automatically created by $0\n", + "%%% at ",scalar localtime,"\n", + "%%%\n", + "\\ProvidesPackage{${foundry}ttf}\n", + "\\expandafter\\ifx\\csname unihangulchar\\endcsname\\relax\n", + @stydata, + "\\fi\n", + "\\def\\hfontfamilynameprefix{$foundry}\n", + "\\endinput\n"; + close STY; +} + + + +sub maketfmandmap { + my($font,$ttf,@Series) = @_; + my($iswan,$findex,@cidmapdata,@ttf2pkdata); + ($ttf,$findex) = parsettf($ttf); + + foreach my $ser (@Series) { # eg. for 'm' and 'c' + foreach my $sla ('',$slant) { # for null and 'o' + my $font = $font.$ser.$sla; + my ($tfmcmd,$myopt,$mysfd); + + my $shape = ''; + $shape .= " $cshape" if $ser =~ /c/; + $shape .= " $oshape" if $sla eq 'o'; + + unless($iswan) { + $myopt = "$opt$shape -f $findex"; + $mysfd = $sfd; + } + else { + $myopt = "$wanopt$shape -f $findex"; + $mysfd = $wansfd; + } + + $myopt .= ' -w' if($args{p} and $shape eq ''); + + $tfmcmd = "$ttf2tfm $ttf $myopt $font\@$mysfd\@"; + print "$tfmcmd\n"; + + my $ttf2tfmresult = `$tfmcmd`; + if($? >> 8){ # ttf2tfm이 실패했다면 완성 인코딩 옵션으로 재시도 + $myopt = "$wanopt$shape -f $findex"; + $myopt .= ' -w' if($args{p} and $shape eq ''); + $tfmcmd = "$ttf2tfm $ttf $myopt $font\@$wansfd\@"; + print "... trying wansung ttf option ...\n$tfmcmd\n"; + $ttf2tfmresult = `$tfmcmd`; + $? >> 8 and die; # 이번에도 실패하면 프로그램 종료 + ++$iswan; # 성공했다면 완성형 TTF + } + push @ttf2pkdata,$ttf2tfmresult; + + my @tmp = ( "$font\@", + $iswan ? $wansfd : $sfd, + "\@\t", + $iswan ? $wancmap : $cmap, + "\t", + $findex ? ":$findex:" : "", + "$ttf$shape\n"); + push @cidmapdata, join '',@tmp; + } + } + + return($iswan,\@cidmapdata,\@ttf2pkdata); +} + + +sub parsettf { + my($ttf) = @_; + my $findex = 0; + + if($ttf =~ /\((\d)\)/) { + $findex = $1; + $ttf =~ s/\($1\)//; + } + + if($ttf =~ /\[([\w\-_\.]+?)\]/) { # old version compatible + $ttf =~ s/\[$1\]//; + } + + return($ttf,$findex); +} + + +sub addfakeboldoption { + my @cidmaplines = @_; + for(@cidmaplines) { + s/$/ $bshape/; + } + return @cidmaplines; +} + + +sub getpdfmapdata { + my($font,$ttf) = @_; + my(@Data,@PLANES); + ($ttf) = parsettf($ttf); + + if($prefix) { + for my $i(0 .. 255) { + $PLANES[$i] = sprintf "%02x",$i; + } + } + else { + @PLANES = ("04".."07",0 .. 29); + } + + foreach my $plane (@PLANES) { + push @Data,"$font$plane\t<$font$plane.enc\t<$ttf\n" + if -e "$font$plane.enc"; + } + + return @Data; +} + + +sub gettexfd { + my($font,$wsh,@Series) = @_; + my @texfd; + + foreach my $ser (@Series) { + push @texfd,"\n", + "\\DeclareFontShape{$encoding}{$wsh$font}{$ser}{n}", + "{<->$font$ser}{}\n", + "\\DeclareFontShape{$encoding}{$wsh$font}{$ser}{sl}", + "{<->$font$ser$slant}{}\n", + "\\DeclareHFontShape{$encoding}{$wsh$font}{$ser}{it}", + "{<->hssub*$wsh$font/$ser/sl}{}\n"; + } + + return @texfd; +} + +sub getucsfd { + my($ff,@Series) = @_; + my $font = $ff; + $font =~ s/^$prefix//; + my @ucsfd; + + foreach my $ser (@Series) { + push @ucsfd,"\n", + "\\DeclareFontShape{$encoding}{$font}{$ser}{n}", + "{<-> $encoding * $ff$ser}{}\n", + "\\DeclareFontShape{$encoding}{$font}{$ser}{sl}", + "{<-> $encoding * $ff$ser$slant}{}\n", + "\\DeclareFontShape{$encoding}{$font}{$ser}{it}", + "{<-> $encoding * $ff$ser$slant}{}\n"; + if($ser eq 'b') { + my $bxser = 'bx'; + push @ucsfd,"\n", + "\\DeclareFontShape{$encoding}{$font}{$bxser}{n}", + "{<-> ${encoding}ssub * $font/$ser/n}{}\n", + "\\DeclareFontShape{$encoding}{$font}{$bxser}{sl}", + "{<-> ${encoding}ssub * $font/$ser/sl}{}\n", + "\\DeclareFontShape{$encoding}{$font}{$bxser}{it}", + "{<-> ${encoding}ssub * $font/$ser/it}{}\n"; + } + } + return @ucsfd; +} + + +sub gettexfilecnt { + my($font,$mbl,$ttf,$hlatex) = @_; + my(@texcnt,$findex); + + ($ttf,$findex) = parsettf($ttf); + $ttf =~ s/_/\\_/g; + $ttf .= "($findex)" if $findex; + + push @texcnt,"$font$SERIES{$mbl}[0]($ttf):"; + unless($prefix) { + push @texcnt,"\\text$hlatex\{"; + push @texcnt,"\\bfseries" if $mbl eq 'b'; + push @texcnt,"\\hfontseries{l}" if $mbl eq 'l'; + } + else { + $font=~s/^$prefix//; + if($hlatex eq 'mj') { + push @texcnt,"\\textrm\{"; + } + elsif($hlatex eq 'gt') { + push @texcnt,"\\textsf\{"; + } + elsif($hlatex eq 'tz') { + push @texcnt,"\\texttt\{"; + } + else { + push @texcnt,"\{\\SetAdhocFonts{$font}{$font}"; + } + push @texcnt,"\\bfseries" if $mbl eq 'b'; + push @texcnt,"\\fontseries{l}" if $mbl eq 'l'; + } + push @texcnt,"\\\\$texteststr\}\n\n"; + + return @texcnt; +} + + +sub addtocfg { + my($line,$cfg,$destdir) = @_; + print "`$line' -> $destdir/$cfg ... "; + + # 현재디렉토리의 $cfg는 kpsewhich의 작업에 방해가 됨 + if(-e $cfg) { + move($cfg,"$cfg.exa") or return 0; + } + + # kpsewhich가 성공하길 기원하자 + my $progname = $cfg; + # $progname =~ s/dvipdfmx/dvipdfm/; + $progname =~ s/\.cfg//; + my $kpathcfg = + `kpsewhich -format="other text files" -progname=$progname $cfg`; + chomp $kpathcfg; + return 0 unless $kpathcfg; + + # 발견된 $cfg를 읽어들임 + # 단, 추가하려는 줄과 같은 줄이 있으면 무시 + my @Lines = (); + open(CFG,$kpathcfg) or return 0; + while() { + next if /^\Q$line/; + next if /^% ${foundry}ttf -- added by/; + push @Lines,$_; + } + close CFG; + + # .cfg를 $destdir에 쓰고 맨끝에 $line 추가 + mkpath $destdir; + open(CFG,">$destdir/$cfg") or return 0; + print CFG @Lines,"\n\% ${foundry}ttf -- added by $0\n$line\n"; + close CFG; + + # 여기까지 도달하면 성공 + print "Success.\n But check out the file.\n"; + return 1; +} + + +sub curemaphangulfamily { + my(@maphangul) = @_; + my $mjfamily = $FONTS{mj}{f}; + my $gtfamily = $FONTS{gt}{f} || $mjfamily; + my @serifcured = ($mjfamily,$mjfamily,$mjfamily); + my @sanscured = ($gtfamily,$gtfamily,$gtfamily); + my $texlog = $euctexname; $texlog =~ s/\.tex/\.log/; + my(@ERRFNT,%SFONTS); + + # latex을 돌려 에러난 폰트를 @ERRFNT에 저장 + system("latex -interaction=batchmode -no-mktex=tfm $euctexname"); + open LOG,$texlog or return @maphangul; + while() { + if(/^! Font H\/(\w)(\w+?)\/.* \(TFM\) /) { + push @{$ERRFNT[0]}, $2 if $1 eq 'w'; + push @{$ERRFNT[1]}, $2 if $1 eq 's'; + push @{$ERRFNT[2]}, $2 if $1 eq 'h'; + } + } + close LOG; + + # @ERRFNT에서 중복항목을 없앰 + foreach my $i (0..2) { + my %seen = (); + foreach (@{$ERRFNT[$i]}) { + $seen{$_}++; + } + @{$ERRFNT[$i]} = keys %seen; + } + + # @maphangul에서 %SFONTS 추출 + foreach (@maphangul) { + if(/\\MapHangulFamily\{(\w+)\}\{(\w+),(\w+),(\w+)\}/) { + push @{$SFONTS{$1}},$2,$3,$4; + } + } + + # FONTmj에 에러가 있으면 uhc 이용 + foreach my $i (0..2) { + foreach my $errfnt (@{$ERRFNT[$i]}) { + $serifcured[$i] = 'type1uhc' if $errfnt eq "$foundry$mjfamily"; + } + } + + # FONTgt에 에러가 있으면 FONTmj 이용 + if($gtfamily ne $mjfamily) { + foreach my $i (0..2) { + foreach my $errfnt (@{$ERRFNT[$i]}) { + $sanscured[$i] = 'type1uhc' + if $errfnt eq "$foundry$gtfamily"; + } + } + } + + # %SFONTS와 @ERRFNT를 비교하여 + # sans계열에 에러 있으면 FONTgt이용, serif계열이면 FONTmj이용 + foreach my $fam (keys %SFONTS) { + foreach my $i (0..2) { + foreach my $errfnt (@{$ERRFNT[$i]}) { + if($SFONTS{$fam}[$i] eq $errfnt) { + if($fam =~ /^($sansfonts)$/) { + $SFONTS{$fam}[$i] = + $sanscured[$i] eq 'type1uhc' ? + $eucgtdefault : + $SFONTS{$sanscured[$i]}[$i]; + } else { + $SFONTS{$fam}[$i] = + $serifcured[$i] eq 'type1uhc' ? + $eucmjdefault : + $SFONTS{$serifcured[$i]}[$i]; + } + } + } + } + } + + # 새로운 @maphangul 리턴 + @maphangul = (); + foreach my $fam (keys %SFONTS) { + push @maphangul,"\\MapHangulFamily{$fam}{"; + foreach my $i (0..2) { + push @maphangul,$SFONTS{$fam}[$i]; + push @maphangul,',' if $i < 2; + } + push @maphangul,"}\n"; + } + return @maphangul; +} + + +sub error { + my $message = shift; + + print "\n$message\nProgram Aborted!!!\n"; + exit 1; +} + +##### +# 2008/09/23. touched by Karnes. change dvipdfmx.cfg location -- cgit v1.2.3