beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / lua / llanglib.c
blob3356e734189f793685a8d2128d12c0e7308c0643
1 /* llanglib.c
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/>. */
20 #include "ptexlib.h"
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);
34 if (!*lang) {
35 return luaL_error(L, "lang.new(): no room for a new language");
37 } else {
38 int lualang;
39 lang = lua_newuserdata(L, sizeof(struct tex_language *));
40 lualang = lua_tointeger(L, 1);
41 *lang = get_language(lualang);
42 if (!*lang) {
43 return luaL_error(L, "lang.new(%d): undefined language", lualang);
46 luaL_getmetatable(L, LANG_METATABLE);
47 lua_setmetatable(L, -2);
48 return 1;
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);
56 return 1;
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));
68 return 0;
69 } else {
70 if ((*lang_ptr)->patterns != NULL) {
71 lua_pushstring(L, (char *) hnj_serialize((*lang_ptr)->patterns));
72 } else {
73 lua_pushnil(L);
75 return 1;
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);
84 return 0;
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));
97 return 0;
98 } else {
99 if ((*lang_ptr)->exceptions != 0) {
100 lua_pushstring(L, exception_strings(*lang_ptr));
101 } else {
102 lua_pushnil(L);
104 return 1;
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);
117 return 0;
118 } else {
119 lua_pushinteger(L, (*lang_ptr)->pre_hyphen_char);
120 return 1;
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);
133 return 0;
134 } else {
135 lua_pushinteger(L, (*lang_ptr)->post_hyphen_char);
136 return 1;
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);
150 return 0;
151 } else {
152 lua_pushinteger(L, (*lang_ptr)->pre_exhyphen_char);
153 return 1;
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");
163 } else {
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);
167 } else {
168 set_hj_code((*lang_ptr)->id,i,i,-1);
171 return 0;
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");
180 } else {
181 lua_pushinteger(L, get_hj_code((*lang_ptr)->id,lua_tointeger(L, 2)));
183 return 1;
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);
195 return 0;
196 } else {
197 lua_pushinteger(L, (*lang_ptr)->post_exhyphen_char);
198 return 1;
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);
211 return 0;
212 } else {
213 lua_pushinteger(L, (*lang_ptr)->hyphenation_min);
214 return 1;
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);
223 return 0;
226 static int do_lang_clean(lua_State * L)
228 char *cleaned;
229 if (lua_type(L, 1) == LUA_TSTRING) {
230 (void) clean_hyphenation(int_par(cur_lang_code), lua_tostring(L, 1), &cleaned);
231 } else {
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");
238 } else {
239 (void) clean_hyphenation((*lang_ptr)->id,lua_tostring(L, 2), &cleaned);
242 lua_pushstring(L, cleaned);
243 return 1;
246 static int do_lang_hyphenate(lua_State * L)
248 halfword *h, *t, tt;
249 h = check_isnode(L, 1);
250 if (lua_isuserdata(L, 2)) {
251 t = check_isnode(L, 2);
252 tt = *t;
253 lua_pop(L, 1);
254 } else {
255 tt = *h;
256 while (vlink(tt) != null)
257 tt = vlink(tt);
259 hnj_hyphenation(*h, tt);
260 lua_pushboolean(L, 1);
261 return 1;
264 static const struct luaL_Reg langlib_d[] = {
265 /* *INDENT-OFF* */
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},
277 {"id", lang_id},
278 /* *INDENT-ON* */
279 {NULL, NULL} /* sentinel */
283 static const struct luaL_Reg langlib[] = {
284 /* *INDENT-OFF* */
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},
296 {"id", lang_id},
297 {"clean", do_lang_clean},
298 {"hyphenate", do_lang_hyphenate},
299 {"new", lang_new},
300 /* *INDENT-ON* */
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);
312 return 1;