1if not modules then modules = { } end modules [ ' lpdf-aux ' ] = {
2 version = 1 . 001 ,
3 comment = " companion to lpdf-ini.mkiv " ,
4 author = " Hans Hagen, PRAGMA-ADE, Hasselt NL " ,
5 copyright = " PRAGMA ADE / ConTeXt Development Team " ,
6 license = " see context related readme files "
7}
8
9local tonumber = tonumber
10local format , concat = string . format , table . concat
11local utfchar , utfbyte , char = utf . char , utf . byte , string . char
12local lpegmatch , lpegpatterns = lpeg . match , lpeg . patterns
13local P , C , R , S , Cc , Cs , V = lpeg . P , lpeg . C , lpeg . R , lpeg . S , lpeg . Cc , lpeg . Cs , lpeg . V
14local rshift = bit32 . rshift
15
16lpdf = lpdf or { }
17
18
19
20local cache = table . setmetatableindex ( function ( t , k )
21 local v = utfbyte ( k )
22 if v < 0x10000 then
23 v = format ( " %04x " , v )
24 else
25 v = format ( " %04x%04x " , rshift ( v , 10 ) , v % 1024 + 0xDC00 )
26 end
27 t [ k ] = v
28 return v
29end )
30
31local unified = Cs ( Cc ( " <feff " ) * ( lpegpatterns . utf8character / cache ) ^ 1 * Cc ( " > " ) )
32
33function lpdf . tosixteen ( str )
34 if not str or str = = " " then
35 return " <feff> "
36 else
37 return lpegmatch ( unified , str )
38 end
39end
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
69local more = 0
70
71local pattern = C ( 4 ) / function ( s )
72 local now = tonumber ( s , 16 )
73 if more > 0 then
74 now = ( more -0xD800 ) * 0x400 + ( now -0xDC00 ) + 0x10000
75 more = 0
76 return utfchar ( now )
77 elseif now > = 0xD800 and now < = 0xDBFF then
78 more = now
79 return " "
80 else
81 return utfchar ( now )
82 end
83end
84
85local pattern = P ( true ) / function ( ) more = 0 end * Cs ( pattern ^ 0 )
86
87function lpdf . fromsixteen ( str )
88 if not str or str = = " " then
89 return " "
90 else
91 return lpegmatch ( pattern , str )
92 end
93end
94
95
96
97local b_pattern = Cs ( ( P ( " \\ " ) / " " * (
98 S ( " () " )
99 + S ( " nrtbf " ) / { n = " \n " , r = " \r " , t = " \t " , b = " \b " , f = " \f " }
100 + lpegpatterns . octdigit ^ -3 / function ( s ) return char ( tonumber ( s , 8 ) ) end )
101+ P ( 1 ) ) ^ 0 )
102
103local u_pattern = lpegpatterns . utfbom_16_be * lpegpatterns . utf16_to_utf8_be
104 + lpegpatterns . utfbom_16_le * lpegpatterns . utf16_to_utf8_le
105
106local h_pattern = lpegpatterns . hextobytes
107
108local zero = S ( " \n\r\t " ) + P ( " \\ " )
109local one = C ( 4 )
110local two = P ( " d " ) * R ( " 89 " , " af " ) * C ( 2 ) * C ( 4 )
111
112local x_pattern = P { " start " ,
113 start = V ( " wrapped " ) + V ( " unwrapped " ) + V ( " original " ) ,
114 original = Cs ( P ( 1 ) ^ 0 ) ,
115 wrapped = P ( " < " ) * V ( " unwrapped " ) * P ( " > " ) * P ( -1 ) ,
116 unwrapped = P ( " feff " )
117 * Cs ( (
118 zero / " "
119 + two / function ( a , b )
120 a = ( tonumber ( a , 16 ) - 0xD800 ) * 1024
121 b = ( tonumber ( b , 16 ) - 0xDC00 )
122 return utfchar ( a + b )
123 end
124 + one / function ( a )
125 return utfchar ( tonumber ( a , 16 ) )
126 end
127 ) ^ 1 ) * P ( -1 )
128}
129
130function lpdf . frombytes ( s , hex )
131 if not s or s = = " " then
132 return " "
133 end
134 if hex then
135 local x = lpegmatch ( x_pattern , s )
136 if x then
137 return x
138 end
139 local h = lpegmatch ( h_pattern , s )
140 if h then
141 return h
142 end
143 else
144 local u = lpegmatch ( u_pattern , s )
145 if u then
146 return u
147 end
148 end
149 return lpegmatch ( b_pattern , s )
150end
151
152
153 |