From 0a964418bc66e27bdc4733bd834819c2dd10d52d Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 31 May 2018 21:52:21 +0000 Subject: luavlna (31may18) git-svn-id: svn://tug.org/texlive/trunk@47892 c570f23f-e606-0410-a88d-b1316a301751 --- .../tex/luatex/luavlna/luavlna-csplain-langs.lua | 59 ++++ .../tex/luatex/luavlna/luavlna-langno.lua | 120 ++++++++ .../tex/luatex/luavlna/luavlna-predegrees.lua | 65 +++++ .../tex/luatex/luavlna/luavlna-presi.lua | 30 ++ .../texmf-dist/tex/luatex/luavlna/luavlna-si.lua | 38 +++ .../tex/luatex/luavlna/luavlna-sufdegrees.lua | 21 ++ Master/texmf-dist/tex/luatex/luavlna/luavlna.4ht | 5 + Master/texmf-dist/tex/luatex/luavlna/luavlna.lua | 316 +++++++++++++++++++++ Master/texmf-dist/tex/luatex/luavlna/luavlna.sty | 24 ++ 9 files changed, 678 insertions(+) create mode 100644 Master/texmf-dist/tex/luatex/luavlna/luavlna-csplain-langs.lua create mode 100644 Master/texmf-dist/tex/luatex/luavlna/luavlna-langno.lua create mode 100644 Master/texmf-dist/tex/luatex/luavlna/luavlna-predegrees.lua create mode 100644 Master/texmf-dist/tex/luatex/luavlna/luavlna-presi.lua create mode 100644 Master/texmf-dist/tex/luatex/luavlna/luavlna-si.lua create mode 100644 Master/texmf-dist/tex/luatex/luavlna/luavlna-sufdegrees.lua create mode 100644 Master/texmf-dist/tex/luatex/luavlna/luavlna.4ht create mode 100644 Master/texmf-dist/tex/luatex/luavlna/luavlna.lua create mode 100644 Master/texmf-dist/tex/luatex/luavlna/luavlna.sty (limited to 'Master/texmf-dist/tex/luatex') diff --git a/Master/texmf-dist/tex/luatex/luavlna/luavlna-csplain-langs.lua b/Master/texmf-dist/tex/luatex/luavlna/luavlna-csplain-langs.lua new file mode 100644 index 00000000000..b061bee4297 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luavlna/luavlna-csplain-langs.lua @@ -0,0 +1,59 @@ +return { +["spanish; castilian"]={26, 126}, +["magyar; hungarian"]={30, 130}, +["english; usenglish; american"]={100}, +["icelandic"]={42, 142}, +["basque"]={33, 133}, +["coptic"]={205}, +["catalan; valencian"]={204}, +["welsh"]={24, 124}, +["irish"]={34, 134}, +["armenian"]={210}, +["chinese"]={41, 141}, +["danish"]={25, 125}, +["turkish"]={31, 131}, +["interlingua "]={103}, +["slovak"]={6, 16, 116}, +["english; ukenglish; british"]={101}, +["ukrainian"]={209}, +["turkmen"]={47, 147}, +["sanskrit"]={207}, +["hindi"]={212}, +["lao"]={214}, +["finnish"]={29, 129}, +["assamese"]={211}, +["greek; polutonikogreek"]={203}, +["czech"]={5, 15, 115}, +["tamil"]={221}, +["italian"]={102}, +["french; francais; canadien; acadian"]={22, 122}, +["telugu"]={222}, +["croatian"]={40, 140}, +["panjabi; punjabi"]={220}, +["oriya"]={219}, +["russian"]={208}, +["malayalam"]={217}, +["marathi"]={218}, +["uppersorbian"]={43, 143}, +["portuges; portuguese; brazilian; brazil"]={38, 138}, +["galician"]={45, 145}, +["latvian"]={215}, +["afrikaans"]={44, 144}, +["lithuanian"]={216}, +["slovenian;slovene"]={28, 128}, +["mongolian"]={206}, +["greek; polutonikogreek"]={202}, +["latin"]={48, 148}, +["indonesian; indon; bahasai; bahasam; malay; meyalu"]={104}, +["polish"]={23, 123}, +["bokmål"]={35, 135}, +["dutch; flemish"]={37, 137}, +["greek; polutonikogreek"]={201}, +["norsk; nynorsk; norwegian"]={36, 136}, +["kannada"]={213}, +["estonian"]={32, 132}, +["english; usenglish; american; ukenglish; british; canadian; australian; newzealand"]={0}, +["romanian; moldavian; moldovan"]={39, 139}, +["german; germanb; ngerman; naustrian"]={21, 121}, +["kurdish"]={46, 146}, +} diff --git a/Master/texmf-dist/tex/luatex/luavlna/luavlna-langno.lua b/Master/texmf-dist/tex/luatex/luavlna/luavlna-langno.lua new file mode 100644 index 00000000000..f4c654ff5fa --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luavlna/luavlna-langno.lua @@ -0,0 +1,120 @@ +-- langno.lua +-- library for working with luatex's language numbers +-- glyph nodes have numerical lang field, but the language names for +-- these numbers aren't saved. +-- +-- this library tries to find language names by parsing `language.dat` file +-- + +local M = {} + +local tex = tex or {} + +local format = tex.formatname -- or "luatex" + +-- languages object +local lang_obj = function(names, numbers) + local obj = {} + obj.__index = obj + local self = setmetatable({},obj) + self.names = names + self.numbers = numbers + -- get language name by number + self.get_name = function(self, number) + return self.numbers[number] + end + -- get language number by name + self.get_number = function(self, name) + return self.names[name] + end + return self +end + + +-- default language loader, language.dat file is parsed +local load_lang_dat = function(start) + -- languages are saved in the file language.dat + local lang_dat = kpse.find_file("language.dat") + if not lang_dat then + return nil, "Cannot load file language.dat" + end + local f = io.open(lang_dat, "r") + local i = start or 0 + local numlang = {} -- return language name + local langnum = {} -- return language number + for line in f:lines() do + -- match comment, equal sign and first word on a line + local first, language = line:match("%s*([%%%=]?)([%a]*)") + if first ~="%" then -- ignore comments + langnum[language] = i + if first ~="=" then -- on lines starting with eq are language synonyms + --print(i, language) + numlang[i] = language + i = i + 1 + end + end + end + return lang_obj(langnum, numlang)--{numbers = numlang, names = langnum} +end + +local load_lang_dat_lualatex = function() + return load_lang_dat(1) +end + +local load_csplain= function() + local l = require "luavlna-csplain-langs" + local langnum = {} + local numlang = {} + for k, v in pairs(l) do + local first = k:gsub(" *;.*","") + --print(first) + langnum[first] = v + for _,i in ipairs(v) do + numlang[i] = first + end + end + return lang_obj(langnum, numlang) +end + + +-- because different formats may use different ways to load languages +-- driver mechanism is provided. +local drivers = {} +drivers["lualatex"] = load_lang_dat_lualatex +drivers["luatex"] = load_lang_dat +drivers["default"] = load_lang_dat +drivers["csplain"] = load_csplain +drivers["pdfcsplain"] = load_csplain +drivers["luaplain"] = load_csplain + +local load_languages = function(name) + local name = name or format + print ("Load driver: "..name) + local func = drivers[name] or drivers["default"] + if not func then return nil, "Cannot find driver function "..name end + return func() +end + +-- only load_languages function is provided to the outside world +M.load_languages = load_languages + +return M +--[[ + +-- sample usage: +local j = load_languages() +print(j:get_name(16)) +print(j:get_number("slovak")) +for k, v in pairs(j.numbers) do + print(k,v) +end +--]] + +-- this may be used in future, if I find a way how does local language.dat +-- affect language loading +-- load local language.dat +--[[ +local loc = kpse.var_value('TEXMFLOCAL') .. "tex/generic/config/language.dat" +local f, msg = io.open(loc, "r") +f:read("*all") +--]] diff --git a/Master/texmf-dist/tex/luatex/luavlna/luavlna-predegrees.lua b/Master/texmf-dist/tex/luatex/luavlna/luavlna-predegrees.lua new file mode 100644 index 00000000000..995b00558f4 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luavlna/luavlna-predegrees.lua @@ -0,0 +1,65 @@ +return { + "ak.", + "akad.", + "arch.", + "arm.", + "art.", + "Bc.", + "BcA.", + "brig.", + "čet.", + "des.", + "Dipl.-Ing.", + "doc.", + "dr.", + "Dr.", + "Dr.-Ing.", + "gen.", + "genmjr.", + "genplk.", + "genpor.", + "ICDr.", + "ing.", + "Ing.", + "JUDr.", + "kpt.", + "mal.", + "MDDr.", + "MgA.", + "Mgr.", + "mjr.", + "MSDr.", + "MUDr.", + "MVDr.", + "npor.", + "nprap.", + "nrtm.", + "nstržm.", + "PaedDr.", + "PharmDr.", + "PhDr.", + "PhMr.", + "plk.", + "por.", + "pplk.", + "ppor.", + "pprap.", + "prap.", + "prof.", + "RCDr.", + "RNDr.", + "RSDr.", + "RTDr.", + "rtm.", + "rtn.", + "soch.", + "stržm.", + "sv.", + "svob.", + "šprap.", + "št.", + "ThDr.", + "ThLic.", + "ThMgr.", + "voj.", +} diff --git a/Master/texmf-dist/tex/luatex/luavlna/luavlna-presi.lua b/Master/texmf-dist/tex/luatex/luavlna/luavlna-presi.lua new file mode 100644 index 00000000000..99ff5285b69 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luavlna/luavlna-presi.lua @@ -0,0 +1,30 @@ +return { + "Y", + "Yi", + "Z", + "Zi", + "E", + "Ei", + "P", + "Pi", + "T", + "Ti", + "G", + "Gi", + "M", + "Mi", + "k", + "Ki", + "h", + "da", + "d", + "c", + "m", + "µ", + "n", + "p", + "f", + "a", + "z", + "y", +} diff --git a/Master/texmf-dist/tex/luatex/luavlna/luavlna-si.lua b/Master/texmf-dist/tex/luatex/luavlna/luavlna-si.lua new file mode 100644 index 00000000000..166eb7a1d25 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luavlna/luavlna-si.lua @@ -0,0 +1,38 @@ +return { + "A", + "b", + "B", + "Bq", + "C", + "°C", + "cd", + "dag", + "eV", + "F", + "°F", + "g", + "Gy", + "H", + "Hz", + "J", + "K", + "kat", + "kg", + "lm", + "lx", + "m", + "mg", + "mol", + "N", + "Pa", + "rad", + "s", + "S", + "sr", + "Sv", + "T", + "V", + "W", + "Wb", + "Ω", +} diff --git a/Master/texmf-dist/tex/luatex/luavlna/luavlna-sufdegrees.lua b/Master/texmf-dist/tex/luatex/luavlna/luavlna-sufdegrees.lua new file mode 100644 index 00000000000..0c326cc180c --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luavlna/luavlna-sufdegrees.lua @@ -0,0 +1,21 @@ +return { + "BBA", + "BLaw", + "BPA", + "BSc.", + "B.Th.", + "CSc.", + "DiS.", + "DSc.", + "LL.B.", + "LL.M.", + "MBA", + "MLaw", + "MMed.", + "MPA", + "MSc.", + "M.Th.", + "PhD.", + "Ph.D.", + "Th.D.", +} diff --git a/Master/texmf-dist/tex/luatex/luavlna/luavlna.4ht b/Master/texmf-dist/tex/luatex/luavlna/luavlna.4ht new file mode 100644 index 00000000000..960e9e4de8a --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luavlna/luavlna.4ht @@ -0,0 +1,5 @@ +\directlua{ +luavlna.set_tex4ht() +} + +\endinput diff --git a/Master/texmf-dist/tex/luatex/luavlna/luavlna.lua b/Master/texmf-dist/tex/luatex/luavlna/luavlna.lua new file mode 100644 index 00000000000..ce596bc2588 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luavlna/luavlna.lua @@ -0,0 +1,316 @@ +-- Module luavlna +-- code originally created by Patrick Gundlach +-- http://tex.stackexchange.com/q/27780/2891 +-- The code was adapted for plain TeX and added some more features +-- 1. It is possible to turn this functionality only for some letters +-- 2. Code now works even for single letters after brackets etc. +-- +local M = {} +local utf_match = unicode.utf8.match +local utf_char = unicode.utf8.char +local utf_len = unicode.utf8.len + +local glue_id = node.id "glue" +local glyph_id = node.id "glyph" +local hlist_id = node.id "hlist" +local vlist_id = node.id "vlist" +local math_id = node.id "math" +local period_char = string.byte(".") + +local alpha = string.char(37).."a" -- alpha class, entering +-- percent char directly caused error +local alphas = {} +local match_char = function(x) return utf_match(x,alpha) end +local match_table = function(x, chars) + local chars=chars or {} + return chars[x] +end +local singlechars = {} -- {a=true,i=true,z=true, v=true, u=true, o = true} + +local initials = {} + +local main_language = nil + +-- when main_language is set, we will not use lang info in the nodes, but +-- main language instead +local get_language = function(lang) + return main_language or lang +end + +local set_main_language = function(lang) + main_language = lang +end + +local debug = false +local tex4ht = false +-- Enable processing only for certain letters +-- must be table in the {char = true, char2=true} form +local set_singlechars= function(lang,c) + --print("Set single chars lua") + print(type(lang), lang) + if type(lang) == "table" then + for _,l in pairs(lang) do + print("language: ",l) + singlechars[l] = c + end + else + local lang = tonumber(lang) + print("language: ",lang) + -- for k,_ in pairs(c) do print(k) end + singlechars[lang] = c + end +end + +local set_initials = function(lang,c) + if type(lang) == "table" then + for _,l in pairs(lang) do + initials[l] = c + end + else + local lang = tonumber(lang) + initials[lang]=c + end +end + + +local debug_tex4ht = function(head,p) + --[[ local w = node.new("glyph") + w.lang = tex.lang + w.font = font.current() + w.char = 64 + ]] + --node.remove(head,node.prev(p)) + local w = node.new("whatsit", "special") + w.data = "t4ht= " + return w, head +end + +local debug_node = function(head,p) + local w + if tex4ht then + w, head = debug_tex4ht(head,p) + else + w = node.new("whatsit","pdf_literal") + w.data = "q 1 0 1 RG 1 0 1 rg 0 0 m 0 5 l 2 5 l 2 0 l b Q" + end + node.insert_after(head,head,w) + node.insert_after(head,w,p) + -- return w +end + + +local set_debug= function(x) + debug = x +end + +local set_tex4ht = function() + tex4ht = true +end + +local insert_penalty = function(head) + local p = node.new("penalty") + p.penalty = 10000 + local debug = debug or false + if debug then + local w = debug_node(head,p) + else + node.insert_after(head,head,p) + end + return head +end + +local replace_with_thin_space = function(head) + local gluenode = node.new(node.id("glue")) + local gluespec = node.new(node.id("glue_spec")) + gluenode.width = tex.sp("0.2em") + -- gluenode.spec = gluespec + gluenode.next = head.next + gluenode.prev = head.prev + gluenode.next.prev = gluenode + gluenode.prev.next = gluenode + return gluenode +end + +local is_alpha = function(c) + local status = alphas[c] + if not status then + status = utf_match(c, alpha) + alphas[c] = status + end + return status +end + +-- find whether letter is uppercase +local up_table = {} +local is_uppercase= function(c) + if not is_alpha(c) then return false end + local status = up_table[c] + if status ~= nil then + return status + end + status = unicode.utf8.upper(c) == c + up_table[c] = status + return status +end + +local is_number = function(word) + return tonumber(string.sub(word, -1)) ~= nil +end + +local init_buffer = "" +local is_initial = function(c, lang) + return is_uppercase(c) +end + +local cut_off_end_chars = function(word, dot) + local last = string.sub(word, -1) + while word ~= "" and (not dot or last ~= ".") and not is_alpha(last) do + word = string.sub(word, 1, -2) -- remove last char + last = string.sub(word, -1) + end + return word +end + +local part_until_non_alpha = function(word) + for i = 1, #word do + local c = word:sub(i,i) + if not is_alpha(c) then + word = string.sub(word, 1, i-1) + break + end + end + return word +end + + +function Set (list) + local set = {} + for _, l in ipairs(list) do set[l] = true end + return set +end + + +local presi = (require "luavlna-presi") +local si = Set(require "luavlna-si") + +local is_unit = function(word) + if M.no_unit==true then return false end + word = part_until_non_alpha(word) + if si[word] then + return true + end + for _, prefix in pairs(presi) do + s, e = string.find(word, prefix) + if s == 1 then + local unit = string.sub(word, e+1) + if si[unit] then + return true + end + end + end + return false +end + +local predegrees = Set (require "luavlna-predegrees") +local sufdegrees = Set (require "luavlna-sufdegrees") + +local function prevent_single_letter (head) + local singlechars = singlechars -- or {} + -- match_char matches all single letters, but this method is abbandoned + -- in favor of using table with enabled letters. With this method, multiple + -- languages are supported + local test_fn = match_table -- singlechars and match_table or match_char + local space = true + local init = false + local anchor = head + local wasnumber = false + local word = "" + local no_predegrees = M.no_predegrees + local no_sufdegrees = M.no_sufdegrees + local in_math = false + while head do + local id = head.id + local nextn = head.next + local skip = node.has_attribute(head, luatexbase.attributes.preventsinglestatus) + if id == math_id then + if head.subtype == 0 then + word = "" + in_math = true + else + in_math = false + if is_number(word) then wasnumber = true end + word = "" + end + end + if skip ~= 1 and not in_math then + if id == glue_id then + if wasnumber then + if word ~= "" then + wasnumber = false + word = cut_off_end_chars(word, false) + if is_unit(word) then + anchor = replace_with_thin_space(anchor) + insert_penalty(anchor.prev) + end + end + elseif is_number(word) then + wasnumber = true + else + word = cut_off_end_chars(word, true) + if no_predegrees ~= true and predegrees[word] then + insert_penalty(head.prev) + elseif no_sufdegrees ~= true and sufdegrees[word] then + insert_penalty(anchor.prev) + end + end + space=true + anchor = head + word = "" + init = is_initial " " -- reset initials + elseif space==true and id == glyph_id and is_alpha(utf_char(head.char)) then -- a letter + local lang = get_language(head.lang) + local char = utf_char(head.char) + word = char + init = is_initial(char,lang) + local s = singlechars[lang] or {} -- load singlechars for node's lang + --[[ + for k, n in pairs(singlechars) do + for c,_ in pairs(n) do + --print(type(k), c) + end + end + --]] + if test_fn(char, s) and nextn ~= nil and nextn.id == glue_id then -- only if we are at a one letter word + head = insert_penalty(head) + end + space = false + -- handle initials + -- uppercase letter followed by period (code 46) + elseif init and head.id == glyph_id and head.char == period_char and nextn.id == glue_id and utf_len(word) == 1 then + head = insert_penalty(head) + elseif head.id == glyph_id then + local char = utf_char(head.char) + word = word .. char + init = is_initial(char, head.lang) + -- hlist support + elseif head.id == hlist_id then + prevent_single_letter(head.head) + -- vlist support + elseif head.id == vlist_id then + prevent_single_letter(head.head) + end + elseif id == glyph_id and in_math then + word = word .. utf_char(head.char) + end + head = head.next + end + return true +end + +M.preventsingle = prevent_single_letter +M.singlechars = set_singlechars +M.initials = set_initials +M.set_tex4ht = set_tex4ht +M.debug = set_debug +M.set_main_language = set_main_language +return M diff --git a/Master/texmf-dist/tex/luatex/luavlna/luavlna.sty b/Master/texmf-dist/tex/luatex/luavlna/luavlna.sty new file mode 100644 index 00000000000..059c260ea11 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luavlna/luavlna.sty @@ -0,0 +1,24 @@ +\ProvidesPackage{luavlna}[2017/09/30 luavlna] + +\def\nosingledefaults{\relax} +\input luavlna + +\def\singlechars#1#2{% + \ifcsname l@#1\endcsname% + \expandafter\directlua\expandafter{set_singlechars("\the\csname l@#1\endcsname","#2")}% + \fi% +} + +% Define compound initials +\def\compoundinitials#1#2{% + \ifcsname l@#1\endcsname% + \expandafter\directlua\expandafter{set_compounds("\the\csname l@#1\endcsname","#2")}% + \fi% +} + +\AtBeginDocument{% + \singlechars{czech}{AIiVvOoUuSsZzKk} + \singlechars{slovak}{AIiVvOoUuSsZzKk} + \compoundinitials{czech}{Ch,CH} +} +\endinput -- cgit v1.2.3