summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/luatexko/luatexko-uhc2utf8.lua
blob: 95c29ac71bd96572e194d572eacb2775edb9e766 (plain)
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
-- luatexko-uhc2utf8.lua
--
-- Copyright (c) 2013-2014 Dohyun Kim  <nomos at ktug org>
--
-- 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.6,
  date        = "2014/06/17",
  author      = "Dohyun Kim",
  description = "UHC (CP949) input encoding",
  license     = "LPPL v1.3+",
})

luatexkouhc2utf8 = luatexkouhc2utf8 or {}
local luatexkouhc2utf8 = luatexkouhc2utf8

local match = string.match
local gsub = string.gsub
local byte = string.byte
local format = string.format
local utfvalues = string.utfvalues
require "unicode"
local ugsub = unicode.utf8.gsub
local ubyte = unicode.utf8.byte
local uchar = unicode.utf8.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 = match(line,"<(%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 uhc_to_utf8 = function(buffer)
  if not buffer then return end
  -- check if buffer is already utf-8; better solution?
  local ubuffer = buffer
  ubuffer = gsub(ubuffer,"[\000-\127]","")
  ubuffer = gsub(ubuffer,"[\194-\223][\128-\191]","")
  ubuffer = gsub(ubuffer,"\224[\160-\191][\128-\191]","")
  ubuffer = gsub(ubuffer,"[\225-\236\238\239][\128-\191][\128-\191]","")
  ubuffer = gsub(ubuffer,"\237[\128-\159][\128-\191]","")
  ubuffer = gsub(ubuffer,"\240[\144-\191][\128-\191][\128-\191]","")
  ubuffer = gsub(ubuffer,"[\241-\243][\128-\191][\128-\191][\128-\191]","")
  ubuffer = gsub(ubuffer,"\244[\128-\143][\128-\191][\128-\191]","")
  if ubuffer == "" then return buffer end
  -- now convert to utf8
  buffer = gsub(buffer, "([\129-\253])([\65-\254])",
  function(a, b)
    local utf = t_uhc2ucs[byte(a) * 256 + byte(b)]
    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