/* llanglib.c Copyright 2006-2008 Taco Hoekwater This file is part of LuaTeX. LuaTeX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. LuaTeX is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU General Public License along with LuaTeX; if not, see . */ #include "lua/luatex-api.h" #include "ptexlib.h" static const char _svn_version[] = "$Id: llanglib.c 3551 2010-03-26 14:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.70.1/source/texk/web2c/luatexdir/lua/llanglib.c $"; #define LANG_METATABLE "luatex.lang" #define check_islang(L,b) (struct tex_language **)luaL_checkudata(L,b,LANG_METATABLE) static int lang_new(lua_State * L) { struct tex_language **lang; if (lua_gettop(L) == 0) { lang = lua_newuserdata(L, sizeof(struct tex_language *)); *lang = new_language(-1); if (!*lang) { return luaL_error(L, "lang.new(): no room for a new language"); } } else { int lualang; lang = lua_newuserdata(L, sizeof(struct tex_language *)); lua_number2int(lualang, lua_tonumber(L, 1)); *lang = get_language(lualang); if (!*lang) { return luaL_error(L, "lang.new(%d): undefined language", lua_tonumber(L, 1)); } } luaL_getmetatable(L, LANG_METATABLE); lua_setmetatable(L, -2); return 1; } static int lang_id(lua_State * L) { struct tex_language **lang_ptr; lang_ptr = check_islang(L, 1); lua_pushnumber(L, (*lang_ptr)->id); return 1; } static int lang_patterns(lua_State * L) { struct tex_language **lang_ptr; lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (!lua_isstring(L, 2)) { return luaL_error(L, "lang.patterns(): argument should be a string"); } load_patterns(*lang_ptr, (const unsigned char *) lua_tostring(L, 2)); return 0; } else { if ((*lang_ptr)->patterns != NULL) { lua_pushstring(L, (char *) hnj_serialize((*lang_ptr)->patterns)); } else { lua_pushnil(L); } return 1; } } static int lang_clear_patterns(lua_State * L) { struct tex_language **lang_ptr; lang_ptr = check_islang(L, 1); clear_patterns(*lang_ptr); return 0; } static int lang_hyphenation(lua_State * L) { struct tex_language **lang_ptr; lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (!lua_isstring(L, 2)) { return luaL_error(L, "lang.hyphenation(): argument should be a string"); } load_hyphenation(*lang_ptr, (const unsigned char *) lua_tostring(L, 2)); return 0; } else { if ((*lang_ptr)->exceptions != 0) { lua_pushstring(L, exception_strings(*lang_ptr)); } else { lua_pushnil(L); } return 1; } } static int lang_pre_hyphen_char(lua_State * L) { struct tex_language **lang_ptr; lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (!lua_isnumber(L, 2)) { return luaL_error(L, "lang.prehyphenchar(): argument should be a character number"); } lua_number2int((*lang_ptr)->pre_hyphen_char, lua_tonumber(L, 2)); return 0; } else { lua_pushnumber(L, (*lang_ptr)->pre_hyphen_char); return 1; } } static int lang_post_hyphen_char(lua_State * L) { struct tex_language **lang_ptr; lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (!lua_isnumber(L, 2)) { return luaL_error(L, "lang.posthyphenchar(): argument should be a character number"); } lua_number2int((*lang_ptr)->post_hyphen_char, lua_tonumber(L, 2)); return 0; } else { lua_pushnumber(L, (*lang_ptr)->post_hyphen_char); return 1; } } static int lang_pre_exhyphen_char(lua_State * L) { struct tex_language **lang_ptr; lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (!lua_isnumber(L, 2)) { return luaL_error(L, "lang.preexhyphenchar(): argument should be a character number"); } lua_number2int((*lang_ptr)->pre_exhyphen_char, lua_tonumber(L, 2)); return 0; } else { lua_pushnumber(L, (*lang_ptr)->pre_exhyphen_char); return 1; } } static int lang_post_exhyphen_char(lua_State * L) { struct tex_language **lang_ptr; lang_ptr = check_islang(L, 1); if (lua_gettop(L) != 1) { if (!lua_isnumber(L, 2)) { return luaL_error(L, "lang.postexhyphenchar(): argument should be a character number"); } lua_number2int((*lang_ptr)->post_exhyphen_char, lua_tonumber(L, 2)); return 0; } else { lua_pushnumber(L, (*lang_ptr)->post_exhyphen_char); return 1; } } static int lang_clear_hyphenation(lua_State * L) { struct tex_language **lang_ptr; lang_ptr = check_islang(L, 1); clear_hyphenation(*lang_ptr); return 0; } static int do_lang_clean(lua_State * L) { char *cleaned; if (!lua_isstring(L, 1)) { return luaL_error(L, "lang.clean(): argument should be a string"); } (void) clean_hyphenation(lua_tostring(L, 1), &cleaned); lua_pushstring(L, cleaned); return 1; } static int do_lang_hyphenate(lua_State * L) { halfword *h, *t, tt; h = check_isnode(L, 1); if (lua_isuserdata(L, 2)) { t = check_isnode(L, 2); tt = *t; lua_pop(L, 1); } else { tt = *h; while (vlink(tt) != null) tt = vlink(tt); } hnj_hyphenation(*h, tt); lua_pushboolean(L, 1); return 1; } static const struct luaL_reg langlib_d[] = { /* *INDENT-OFF* */ {"clear_patterns", lang_clear_patterns}, {"clear_hyphenation", lang_clear_hyphenation}, {"patterns", lang_patterns}, {"hyphenation", lang_hyphenation}, {"prehyphenchar", lang_pre_hyphen_char}, {"posthyphenchar", lang_post_hyphen_char}, {"preexhyphenchar", lang_pre_exhyphen_char}, {"postexhyphenchar", lang_post_exhyphen_char}, {"id", lang_id}, /* *INDENT-ON* */ {NULL, NULL} /* sentinel */ }; static const struct luaL_reg langlib[] = { /* *INDENT-OFF* */ {"clear_patterns", lang_clear_patterns}, {"clear_hyphenation", lang_clear_hyphenation}, {"patterns", lang_patterns}, {"hyphenation", lang_hyphenation}, {"prehyphenchar", lang_pre_hyphen_char}, {"posthyphenchar", lang_post_hyphen_char}, {"preexhyphenchar", lang_pre_exhyphen_char}, {"postexhyphenchar", lang_post_exhyphen_char}, {"id", lang_id}, {"clean", do_lang_clean}, {"hyphenate", do_lang_hyphenate}, {"new", lang_new}, /* *INDENT-ON* */ {NULL, NULL} /* sentinel */ }; int luaopen_lang(lua_State * L) { luaL_newmetatable(L, LANG_METATABLE); lua_pushvalue(L, -1); /* push metatable */ lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ luaL_register(L, NULL, langlib_d); /* dict methods */ luaL_register(L, "lang", langlib); return 1; }