aboutsummaryrefslogtreecommitdiff
path: root/arabluatex.lua
diff options
context:
space:
mode:
Diffstat (limited to 'arabluatex.lua')
-rw-r--r--arabluatex.lua125
1 files changed, 85 insertions, 40 deletions
diff --git a/arabluatex.lua b/arabluatex.lua
index 72b1e38..114a569 100644
--- a/arabluatex.lua
+++ b/arabluatex.lua
@@ -2,24 +2,23 @@
2This file is part of the `arabluatex' package 2This file is part of the `arabluatex' package
3 3
4ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX 4ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX
5Copyright (C) 2016--2020 Robert Alessi 5Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023
6Robert Alessi <alessi@robertalessi.net>
6 7
7Please send error reports and suggestions for improvements to Robert 8Permission to use, copy, modify, and distribute this software for any
8Alessi <alessi@robertalessi.net> 9purpose with or without fee is hereby granted, provided that the above
10copyright notice and this permission notice appear in all copies.
9 11
10This program is free software: you can redistribute it and/or modify 12THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11it under the terms of the GNU General Public License as published by 13WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12the Free Software Foundation, either version 3 of the License, or 14MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13(at your option) any later version. 15ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 19
15This program is distributed in the hope that it will be useful, but 20Please send error reports and suggestions for improvements to Robert
16WITHOUT ANY WARRANTY; without even the implied warranty of 21Alessi <alessi@robertalessi.net>
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program. If not, see
22<http://www.gnu.org/licenses/>.
23--]] 22--]]
24 23
25arabluatex = {} 24arabluatex = {}
@@ -54,11 +53,26 @@ local cmd = lpeg.Cs(dblbkslash * ascii^1 * cmdstar^-1)
54local rawcmd = lpeg.Cs(dblbkslash * ascii^1) 53local rawcmd = lpeg.Cs(dblbkslash * ascii^1)
55local aftercmd = lpeg.Cs(lpeg.S("*[{,.?;:'`\"") + dblbkslash) 54local aftercmd = lpeg.Cs(lpeg.S("*[{,.?;:'`\"") + dblbkslash)
56local cmdargs = lpeg.Cs(spce^-1 * bsqbracketsii * bcbracesii * bsqbrackets^-1) 55local cmdargs = lpeg.Cs(spce^-1 * bsqbracketsii * bcbracesii * bsqbrackets^-1)
56local cmdargsnobs = lpeg.Cs(spce^-1 * bcbracesii)
57local arbargs = lpeg.Cs(spce^-1 * bsqbrackets^-1 * bcbraces) 57local arbargs = lpeg.Cs(spce^-1 * bsqbrackets^-1 * bcbraces)
58local baytargs = lpeg.Cs(spce * bcbraces * bsqbrackets^-1 * bcbraces) 58local baytargs = lpeg.Cs(spce * bcbraces * bsqbrackets^-1 * bcbraces)
59local arind = lpeg.Cs(dblbkslash * lpeg.P("arind") * spce^-1 * bsqbracketsii) 59local arind = lpeg.Cs(dblbkslash * lpeg.P("arind") * spce^-1 * bsqbracketsii)
60 60
61local function protectarb(str) 61local function protectarb(str)
62 -- \App[]{}{}
63 str = string.gsub(str, "(\\App%s?)(%b{})(%b{})", "%1[]%2%3")
64 str = gsub(str, lpeg.P("\\App") * spcenc^-1 * bsqbrackets * bcbraces * bcbraces,
65 function(opt, lem, rdg)
66 opt = string.sub(opt, 2, -2)
67 lem = string.sub(lem, 2, -2)
68 rdg = string.sub(rdg, 2, -2)
69 if opt == ""
70 then
71 return string.format("\\app{%s%s}", lem, rdg)
72 else
73 return string.format("\\app[%s]{%s%s}", opt, lem, rdg)
74 end
75 end)
62 str = string.gsub(str, "(\\arb%s?)(%[.-%])(%b{})", "\\al@brk{\\arb%2%3}") 76 str = string.gsub(str, "(\\arb%s?)(%[.-%])(%b{})", "\\al@brk{\\arb%2%3}")
63 str = string.gsub(str, "(\\LR%s?)(%b{})", "\\@LR%2") 77 str = string.gsub(str, "(\\LR%s?)(%b{})", "\\@LR%2")
64 str = string.gsub(str, "(\\RL%s?)(%b{})", "\\@RL%2") 78 str = string.gsub(str, "(\\RL%s?)(%b{})", "\\@RL%2")
@@ -90,11 +104,11 @@ local outofarb = {
90local albrkcmds = { 104local albrkcmds = {
91 "begin", 105 "begin",
92 "end", 106 "end",
93 "par",
94 "LRmarginpar", 107 "LRmarginpar",
95 "arbmark", 108 "arbmark",
96 "abjad", 109 "abjad",
97 "ayah" 110 "ayah",
111 "SetArbNumbers"
98} 112}
99local brkcmds = {} 113local brkcmds = {}
100 114
@@ -120,13 +134,15 @@ function arabluatex.mkarbbreak(str, opt)
120end 134end
121 135
122local function breakcmd(str) 136local function breakcmd(str)
137 -- \par
138 str = gsub(str, dblbkslash * lpeg.Cs("par") * cmdargsnobs, "\\al@brk{%1%2%3}")
123 -- process \item[], then \item[] 139 -- process \item[], then \item[]
124 str = string.gsub(str, "\\(item.?)(%b[])", 140 str = string.gsub(str, "\\(item.?)(%b[])",
125 function(tag, body) 141 function(tag, body)
126 body = string.sub(body, 2, -2) 142 body = string.sub(body, 2, -2)
127 return string.format("\\al@brk{\\item[\\arb{%s}] }", body) 143 return string.format("\\al@brk{\\item[\\arb{%s}] }", body)
128 end) 144 end)
129 str = string.gsub(str, "(\\item)(%s+)", "%1{}%2") 145 str = string.gsub(str, "(\\item)(%s+)", "%1{}%2")
130 -- \textcolor 146 -- \textcolor
131 str = string.gsub(str, "\\(textcolor%s?)(%b{})(%b{})", 147 str = string.gsub(str, "\\(textcolor%s?)(%b{})(%b{})",
132 function(tag, bodycolor, bodytext) 148 function(tag, bodycolor, bodytext)
@@ -170,19 +186,38 @@ local function holdcmd(str)
170 return str 186 return str
171end 187end
172 188
173local function arbnum(str) 189local indorarbnum = "Indian"
190
191function arabluatex.setnums(opt)
192 if opt == "Indian"
193 then
194 indorarbnum = "Indian"
195 else
196 indorarbnum = "Arabic"
197 end
198end
199
200local function arbnum(str) -- not used, see below
174 str = string.gsub(str, "([0-9%,%-%/]+)", function(num) 201 str = string.gsub(str, "([0-9%,%-%/]+)", function(num)
175 return string.reverse(num) 202 return string.reverse(num)
176 end) 203 end)
177 return str 204 return str
178end 205end
179 206
180local function indnum(str) 207local function indnum(str, dir)
181 str = string.gsub(str, "([0-9%,%-%/]+)", function(num) 208 if dir == "ltr"
182 return string.reverse(num) 209 then
183 end) 210 -- do nothing
184 for i = 1,#numbers do 211 else
185 str = string.gsub(str, numbers[i].a, numbers[i].b) 212 str = string.gsub(str, "([0-9%,%-%/]+)", function(num)
213 return string.reverse(num)
214 end)
215 end
216 if indorarbnum == "Indian"
217 then
218 for i = 1,#numbers do
219 str = string.gsub(str, numbers[i].a, numbers[i].b)
220 end
186 end 221 end
187 return str 222 return str
188end 223end
@@ -590,11 +625,19 @@ local function novoceasy(str)
590 return str 625 return str
591end 626end
592 627
593local function transdmg(str, rules) 628local function transdmg(str, mode, rules)
594 str = string.gsub(str, "\\arb(%b{})", function(inside) 629 str = string.gsub(str, "\\arb(%b{})", function(inside)
595 inside = string.sub(inside, 2, -2) 630 inside = string.sub(inside, 2, -2)
596 for i = 1,#hamzatrdmg do 631 if mode == "dmg"
597 inside = string.gsub(inside, hamzatrdmg[i].a, hamzatrdmg[i].b) 632 then
633 for i = 1,#hamzatrnoinitialdmg do
634 inside = string.gsub(inside, hamzatrnoinitialdmg[i].a, hamzatrnoinitialdmg[i].b)
635 end
636 elseif mode == "dmg+"
637 then
638 for i = 1,#hamzatrdmg do
639 inside = string.gsub(inside, hamzatrdmg[i].a, hamzatrdmg[i].b)
640 end
598 end 641 end
599 for i = 1,#tanwintrdmg do 642 for i = 1,#tanwintrdmg do
600 inside = string.gsub(inside, tanwintrdmg[i].a, tanwintrdmg[i].b) 643 inside = string.gsub(inside, tanwintrdmg[i].a, tanwintrdmg[i].b)
@@ -797,16 +840,16 @@ local function processarbtoutf(str)
797 end) 840 end)
798 return string.format("%s{%s}", tag, body) 841 return string.format("%s{%s}", tag, body)
799 end) 842 end)
800 str = string.gsub(str, "(\\bayt)%s?(%b{})(%b[])(%b{})", function(tag, argi, argii, argiii) 843 str = string.gsub(str, "(\\bayt)%s?(%+?)(%b{})(%b[])(%b{})", function(tag, plus, argi, argii, argiii)
801 argi = string.sub(argi, 2, -2) 844 argi = string.sub(argi, 2, -2)
802 argii = string.sub(argii, 2, -2) 845 argii = string.sub(argii, 2, -2)
803 argiii = string.sub(argiii, 2, -2) 846 argiii = string.sub(argiii, 2, -2)
804 return string.format("%s*{\\arb{%s}}[\\arb{%s}]{\\arb{%s}}", tag, argi, argii, argiii) 847 return string.format("%s%s*{\\arb{%s}}[\\arb{%s}]{\\arb{%s}}", tag, argi, argii, argiii)
805 end) 848 end)
806 str = string.gsub(str, "(\\bayt)%s?(%b{})(%b{})", function(tag, argi, argii) 849 str = string.gsub(str, "(\\bayt)%s?(%+?)(%b{})(%b{})", function(tag, plus, argi, argii)
807 argi = string.sub(argi, 2, -2) 850 argi = string.sub(argi, 2, -2)
808 argii = string.sub(argii, 2, -2) 851 argii = string.sub(argii, 2, -2)
809 return string.format("%s*{\\arb{%s}}{\\arb{%s}}", tag, argi, argii) 852 return string.format("%s%s*{\\arb{%s}}{\\arb{%s}}", tag, plus, argi, argii)
810 end) 853 end)
811 str = string.gsub(str, "(\\prname)%s?(%b{})", function(tag, body) 854 str = string.gsub(str, "(\\prname)%s?(%b{})", function(tag, body)
812 body = string.sub(body, 2, -2) 855 body = string.sub(body, 2, -2)
@@ -1062,8 +1105,8 @@ function arabluatex.processtrans(str, mode, rules, scheme)
1062 if scheme == "buckwalter" then 1105 if scheme == "buckwalter" then
1063 str = processbuckw(str) 1106 str = processbuckw(str)
1064 end 1107 end
1065 if mode == "dmg" then 1108 if mode == "dmg" or mode == "dmg+" then
1066 str = transdmg(str, rules) 1109 str = transdmg(str, mode, rules)
1067 elseif mode == "loc" then 1110 elseif mode == "loc" then
1068 str = transloc(str) 1111 str = transloc(str)
1069 elseif mode == "arabica" then 1112 elseif mode == "arabica" then
@@ -1264,7 +1307,9 @@ end
1264function arabluatex.ayah(str) 1307function arabluatex.ayah(str)
1265 if tonumber(str) ~= nil and str.len(str) < 4 then 1308 if tonumber(str) ~= nil and str.len(str) < 4 then
1266 if tex.textdir == "TRT" then 1309 if tex.textdir == "TRT" then
1267 str = indnum(str).."^^^^06dd" 1310 -- end of ayah is typeset LTR and the number comes after the
1311 -- sign (see https://github.com/aliftype/amiri/issues/263#issuecomment-1872979252)
1312 str = "{\\textdir TLT ".."^^^^06dd"..indnum(str, "ltr").."}"
1268 elseif tex.textdir == "TLT" then 1313 elseif tex.textdir == "TLT" then
1269 str = "\\arb[trans]{("..str..")}" 1314 str = "\\arb[trans]{("..str..")}"
1270 end 1315 end