3 Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
5 This file is part of LuaTeX.
7 LuaTeX is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
12 LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License along
18 with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
21 #include "lua/luatex-api.h"
24 #define LANG_METATABLE "luatex.lang"
26 #define check_islang(L,b) (struct tex_language **)luaL_checkudata(L,b,LANG_METATABLE)
28 static int lang_new(lua_State
* L
)
30 struct tex_language
**lang
;
31 if (lua_gettop(L
) == 0) {
32 lang
= lua_newuserdata(L
, sizeof(struct tex_language
*));
33 *lang
= new_language(-1);
35 return luaL_error(L
, "lang.new(): no room for a new language");
39 lang
= lua_newuserdata(L
, sizeof(struct tex_language
*));
40 lualang
= lua_tointeger(L
, 1);
41 *lang
= get_language(lualang
);
43 return luaL_error(L
, "lang.new(%d): undefined language", lualang
);
46 luaL_getmetatable(L
, LANG_METATABLE
);
47 lua_setmetatable(L
, -2);
51 static int lang_id(lua_State
* L
)
53 struct tex_language
**lang_ptr
;
54 lang_ptr
= check_islang(L
, 1);
55 lua_pushinteger(L
, (*lang_ptr
)->id
);
59 static int lang_patterns(lua_State
* L
)
61 struct tex_language
**lang_ptr
;
62 lang_ptr
= check_islang(L
, 1);
63 if (lua_gettop(L
) != 1) {
64 if (lua_type(L
, 2) != LUA_TSTRING
) {
65 return luaL_error(L
, "lang.patterns(): argument should be a string");
67 load_patterns(*lang_ptr
, (const unsigned char *) lua_tostring(L
, 2));
70 if ((*lang_ptr
)->patterns
!= NULL
) {
71 lua_pushstring(L
, (char *) hnj_serialize((*lang_ptr
)->patterns
));
79 static int lang_clear_patterns(lua_State
* L
)
81 struct tex_language
**lang_ptr
;
82 lang_ptr
= check_islang(L
, 1);
83 clear_patterns(*lang_ptr
);
88 static int lang_hyphenation(lua_State
* L
)
90 struct tex_language
**lang_ptr
;
91 lang_ptr
= check_islang(L
, 1);
92 if (lua_gettop(L
) != 1) {
93 if (lua_type(L
, 2) != LUA_TSTRING
) {
94 return luaL_error(L
, "lang.hyphenation(): argument should be a string");
96 load_hyphenation(*lang_ptr
, (const unsigned char *) lua_tostring(L
, 2));
99 if ((*lang_ptr
)->exceptions
!= 0) {
100 lua_pushstring(L
, exception_strings(*lang_ptr
));
108 static int lang_pre_hyphen_char(lua_State
* L
)
110 struct tex_language
**lang_ptr
;
111 lang_ptr
= check_islang(L
, 1);
112 if (lua_gettop(L
) != 1) {
113 if (lua_type(L
, 2) != LUA_TNUMBER
) {
114 return luaL_error(L
, "lang.prehyphenchar(): argument should be a character number");
116 (*lang_ptr
)->pre_hyphen_char
= (int) lua_tointeger(L
, 2);
119 lua_pushinteger(L
, (*lang_ptr
)->pre_hyphen_char
);
124 static int lang_post_hyphen_char(lua_State
* L
)
126 struct tex_language
**lang_ptr
;
127 lang_ptr
= check_islang(L
, 1);
128 if (lua_gettop(L
) != 1) {
129 if (lua_type(L
, 2) != LUA_TNUMBER
) {
130 return luaL_error(L
, "lang.posthyphenchar(): argument should be a character number");
132 (*lang_ptr
)->post_hyphen_char
= (int) lua_tointeger(L
, 2);
135 lua_pushinteger(L
, (*lang_ptr
)->post_hyphen_char
);
141 static int lang_pre_exhyphen_char(lua_State
* L
)
143 struct tex_language
**lang_ptr
;
144 lang_ptr
= check_islang(L
, 1);
145 if (lua_gettop(L
) != 1) {
146 if (lua_type(L
, 2) != LUA_TNUMBER
) {
147 return luaL_error(L
, "lang.preexhyphenchar(): argument should be a character number");
149 (*lang_ptr
)->pre_exhyphen_char
= (int) lua_tointeger(L
, 2);
152 lua_pushinteger(L
, (*lang_ptr
)->pre_exhyphen_char
);
157 static int lang_sethjcode(lua_State
* L
)
159 struct tex_language
**lang_ptr
;
160 lang_ptr
= check_islang(L
, 1);
161 if (lua_type(L
, 2) != LUA_TNUMBER
) {
162 return luaL_error(L
, "lang.sethjcode(): argument should be a character number");
164 int i
= (int) lua_tointeger(L
, 2) ;
165 if (lua_type(L
, 3) == LUA_TNUMBER
) {
166 set_hj_code((*lang_ptr
)->id
,i
,(int) lua_tointeger(L
, 3),-1);
168 set_hj_code((*lang_ptr
)->id
,i
,i
,-1);
174 static int lang_gethjcode(lua_State
* L
)
176 struct tex_language
**lang_ptr
;
177 lang_ptr
= check_islang(L
, 1);
178 if (lua_type(L
, 2) != LUA_TNUMBER
) {
179 return luaL_error(L
, "lang.gethjcode(): argument should be a character number");
181 lua_pushinteger(L
, get_hj_code((*lang_ptr
)->id
,lua_tointeger(L
, 2)));
186 static int lang_post_exhyphen_char(lua_State
* L
)
188 struct tex_language
**lang_ptr
;
189 lang_ptr
= check_islang(L
, 1);
190 if (lua_gettop(L
) != 1) {
191 if (lua_type(L
, 2) != LUA_TNUMBER
) {
192 return luaL_error(L
, "lang.postexhyphenchar(): argument should be a character number");
194 (*lang_ptr
)->post_exhyphen_char
= (int) lua_tointeger(L
, 2);
197 lua_pushinteger(L
, (*lang_ptr
)->post_exhyphen_char
);
202 static int lang_hyphenation_min(lua_State
* L
)
204 struct tex_language
**lang_ptr
;
205 lang_ptr
= check_islang(L
, 1);
206 if (lua_gettop(L
) != 1) {
207 if (lua_type(L
, 2) != LUA_TNUMBER
) {
208 return luaL_error(L
, "lang.hyphenationmin(): argument should be a number");
210 (*lang_ptr
)->hyphenation_min
= (int) lua_tointeger(L
, 2);
213 lua_pushinteger(L
, (*lang_ptr
)->hyphenation_min
);
218 static int lang_clear_hyphenation(lua_State
* L
)
220 struct tex_language
**lang_ptr
;
221 lang_ptr
= check_islang(L
, 1);
222 clear_hyphenation(*lang_ptr
);
226 static int do_lang_clean(lua_State
* L
)
229 if (lua_type(L
, 1) == LUA_TSTRING
) {
230 (void) clean_hyphenation(int_par(cur_lang_code
), lua_tostring(L
, 1), &cleaned
);
232 struct tex_language
**lang_ptr
;
233 lang_ptr
= check_islang(L
, 1);
234 if (lang_ptr
== NULL
) {
235 return luaL_error(L
, "lang.clean(): first argument should be a string or language");
236 } else if (lua_type(L
, 2) != LUA_TSTRING
) {
237 return luaL_error(L
, "lang.clean(): second argument should be a string");
239 (void) clean_hyphenation((*lang_ptr
)->id
,lua_tostring(L
, 2), &cleaned
);
242 lua_pushstring(L
, cleaned
);
246 static int do_lang_hyphenate(lua_State
* L
)
249 h
= check_isnode(L
, 1);
250 if (lua_isuserdata(L
, 2)) {
251 t
= check_isnode(L
, 2);
256 while (vlink(tt
) != null
)
259 hnj_hyphenation(*h
, tt
);
260 lua_pushboolean(L
, 1);
264 static const struct luaL_Reg langlib_d
[] = {
266 {"clear_patterns", lang_clear_patterns
},
267 {"clear_hyphenation", lang_clear_hyphenation
},
268 {"patterns", lang_patterns
},
269 {"hyphenation", lang_hyphenation
},
270 {"prehyphenchar", lang_pre_hyphen_char
},
271 {"posthyphenchar", lang_post_hyphen_char
},
272 {"preexhyphenchar", lang_pre_exhyphen_char
},
273 {"postexhyphenchar", lang_post_exhyphen_char
},
274 {"hyphenationmin", lang_hyphenation_min
},
275 {"sethjcode", lang_sethjcode
},
276 {"gethjcode", lang_gethjcode
},
279 {NULL
, NULL
} /* sentinel */
283 static const struct luaL_Reg langlib
[] = {
285 {"clear_patterns", lang_clear_patterns
},
286 {"clear_hyphenation", lang_clear_hyphenation
},
287 {"patterns", lang_patterns
},
288 {"hyphenation", lang_hyphenation
},
289 {"prehyphenchar", lang_pre_hyphen_char
},
290 {"posthyphenchar", lang_post_hyphen_char
},
291 {"preexhyphenchar", lang_pre_exhyphen_char
},
292 {"postexhyphenchar", lang_post_exhyphen_char
},
293 {"hyphenationmin", lang_hyphenation_min
},
294 {"sethjcode", lang_sethjcode
},
295 {"gethjcode", lang_gethjcode
},
297 {"clean", do_lang_clean
},
298 {"hyphenate", do_lang_hyphenate
},
301 {NULL
, NULL
} /* sentinel */
305 int luaopen_lang(lua_State
* L
)
307 luaL_newmetatable(L
, LANG_METATABLE
);
308 lua_pushvalue(L
, -1); /* push metatable */
309 lua_setfield(L
, -2, "__index"); /* metatable.__index = metatable */
310 luaL_register(L
, NULL
, langlib_d
); /* dict methods */
311 luaL_register(L
, "lang", langlib
);