1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
-- luatexko-uhc2utf8.lua
--
-- Copyright (c) 2013-2017 Dohyun Kim <nomos at ktug org>
-- Soojin Nam <jsunam at gmail com>
--
-- 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.
luatexbase.provides_module({
name = "luatexko-uhc2utf8",
version = "1.16",
date = "2017/02/06",
author = "Dohyun Kim, Soojin Nam",
description = "UHC (CP949) input encoding",
license = "LPPL v1.3+",
})
luatexkouhc2utf8 = luatexkouhc2utf8 or {}
local luatexkouhc2utf8 = luatexkouhc2utf8
local format = string.format
require "unicode"
local unicodeutf8 = unicode.utf8
local ugsub = unicodeutf8.gsub
local ubyte = unicodeutf8.byte
local uchar = unicodeutf8.char
local floor = math.floor
local kpse_find_file = kpse.find_file
local add_to_callback = luatexbase.add_to_callback
local remove_from_callback = luatexbase.remove_from_callback
local function get_uhc_uni_table()
local t_uhc2ucs = {}
local file = kpse_find_file("KSCms-UHC-UCS2","cmap files")
if file then
file = io.open(file, "r")
while true do
local line = file:read("*line")
if not line then break end
local ea,eb,uni = line:match("<(%x+)>%s+<(%x+)>%s+<(%x+)>")
if ea and eb and uni then
ea, eb, uni = tonumber(ea,16),tonumber(eb,16),tonumber(uni,16)
for i=ea,eb do
t_uhc2ucs[i] = uni
uni = uni + 1
end
end
end
file:close()
end
return t_uhc2ucs
end
local t_uhc2ucs = t_uhc2ucs or get_uhc_uni_table()
local function not_utf8lowbyte(t)
for _,v in ipairs(t) do
-- rough checking
if v < 0x80 or v > 0xBF then return true end
end
return false
end
local uhc_to_utf8 = function(buffer)
if not buffer then return end
-- check if buffer is already utf-8; better solution?
local i, buflen = 1, buffer:len()+1
while i < buflen do
local a = buffer:byte(i)
if a < 0x80 then
i = i + 1
elseif a < 0xC2 then
break
elseif a < 0xE0 then
if not_utf8lowbyte({buffer:byte(i+1)}) then break end
i = i + 2
elseif a < 0xF0 then
if not_utf8lowbyte({buffer:byte(i+1,i+2)}) then break end
i = i + 3
elseif a < 0xF5 then
if not_utf8lowbyte({buffer:byte(i+1,i+3)}) then break end
i = i + 4
else
break
end
end
if i == buflen then return nil end
-- now convert to utf8
buffer = buffer:gsub("([\129-\253])([\65-\254])",
function(a, b)
local utf = t_uhc2ucs[a:byte() * 256 + b:byte()]
if utf then return uchar(utf) end
end)
return buffer
end
local function startconvert ()
add_to_callback('process_input_buffer', uhc_to_utf8, 'luatexko-uhctoutf8', 1)
end
luatexkouhc2utf8.startconvert = startconvert
local function stopconvert ()
remove_from_callback('process_input_buffer', 'luatexko-uhctoutf8')
end
luatexkouhc2utf8.stopconvert = stopconvert
-----------------------------------------
-- Hangul Windows OS uses CP949 filenames
-----------------------------------------
local function get_uni_uhc_table()
local t_ucs2uhc = {}
for i,v in pairs(t_uhc2ucs) do
t_ucs2uhc[v] = i
end
return t_ucs2uhc
end
local t_ucs2uhc = t_ucs2uhc or get_uni_uhc_table()
local function utf8_to_uhc (name)
if not name then return end
name = ugsub(name, "[\161-\239\191\166]", -- 00A1..FFE6
function(u)
local c = t_ucs2uhc[ubyte(u)]
if c then
return format("%c%c", floor(c/256), c%256)
end
end)
return name
end
local function uhc_find_file (file, ...)
local f = kpse_find_file(file, ...)
if f then return f end
f = utf8_to_uhc(file)
return f and kpse_find_file(f, ...)
end
local function start_uhc_filename ()
add_to_callback('find_read_file', function(id, name) return uhc_find_file(name) end, 'luatexko-touhc-findreadfile')
add_to_callback('find_image_file', uhc_find_file, 'luatexko-touhc-findimagefile')
kpse.find_file = uhc_find_file
end
luatexkouhc2utf8.start_uhc_filename = start_uhc_filename
local function stop_uhc_filename ()
remove_from_callback('find_read_file', 'luatexko-touhc-findreadfile')
remove_from_callback('find_image_file', 'luatexko-touhc-findimagefile')
kpse.find_file = kpse_find_file
end
luatexkouhc2utf8.stop_uhc_filename = stop_uhc_filename
|