diff options
Diffstat (limited to 'arabluatex.lua')
-rw-r--r-- | arabluatex.lua | 125 |
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 @@ | |||
2 | This file is part of the `arabluatex' package | 2 | This file is part of the `arabluatex' package |
3 | 3 | ||
4 | ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX | 4 | ArabLuaTeX -- Processing ArabTeX notation under LuaLaTeX |
5 | Copyright (C) 2016--2020 Robert Alessi | 5 | Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 |
6 | Robert Alessi <alessi@robertalessi.net> | ||
6 | 7 | ||
7 | Please send error reports and suggestions for improvements to Robert | 8 | Permission to use, copy, modify, and distribute this software for any |
8 | Alessi <alessi@robertalessi.net> | 9 | purpose with or without fee is hereby granted, provided that the above |
10 | copyright notice and this permission notice appear in all copies. | ||
9 | 11 | ||
10 | This program is free software: you can redistribute it and/or modify | 12 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 | it under the terms of the GNU General Public License as published by | 13 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 | the Free Software Foundation, either version 3 of the License, or | 14 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 | (at your option) any later version. | 15 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
14 | 19 | ||
15 | This program is distributed in the hope that it will be useful, but | 20 | Please send error reports and suggestions for improvements to Robert |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of | 21 | Alessi <alessi@robertalessi.net> |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU General Public License | ||
21 | along with this program. If not, see | ||
22 | <http://www.gnu.org/licenses/>. | ||
23 | --]] | 22 | --]] |
24 | 23 | ||
25 | arabluatex = {} | 24 | arabluatex = {} |
@@ -54,11 +53,26 @@ local cmd = lpeg.Cs(dblbkslash * ascii^1 * cmdstar^-1) | |||
54 | local rawcmd = lpeg.Cs(dblbkslash * ascii^1) | 53 | local rawcmd = lpeg.Cs(dblbkslash * ascii^1) |
55 | local aftercmd = lpeg.Cs(lpeg.S("*[{,.?;:'`\"") + dblbkslash) | 54 | local aftercmd = lpeg.Cs(lpeg.S("*[{,.?;:'`\"") + dblbkslash) |
56 | local cmdargs = lpeg.Cs(spce^-1 * bsqbracketsii * bcbracesii * bsqbrackets^-1) | 55 | local cmdargs = lpeg.Cs(spce^-1 * bsqbracketsii * bcbracesii * bsqbrackets^-1) |
56 | local cmdargsnobs = lpeg.Cs(spce^-1 * bcbracesii) | ||
57 | local arbargs = lpeg.Cs(spce^-1 * bsqbrackets^-1 * bcbraces) | 57 | local arbargs = lpeg.Cs(spce^-1 * bsqbrackets^-1 * bcbraces) |
58 | local baytargs = lpeg.Cs(spce * bcbraces * bsqbrackets^-1 * bcbraces) | 58 | local baytargs = lpeg.Cs(spce * bcbraces * bsqbrackets^-1 * bcbraces) |
59 | local arind = lpeg.Cs(dblbkslash * lpeg.P("arind") * spce^-1 * bsqbracketsii) | 59 | local arind = lpeg.Cs(dblbkslash * lpeg.P("arind") * spce^-1 * bsqbracketsii) |
60 | 60 | ||
61 | local function protectarb(str) | 61 | local 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 = { | |||
90 | local albrkcmds = { | 104 | local 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 | } |
99 | local brkcmds = {} | 113 | local brkcmds = {} |
100 | 114 | ||
@@ -120,13 +134,15 @@ function arabluatex.mkarbbreak(str, opt) | |||
120 | end | 134 | end |
121 | 135 | ||
122 | local function breakcmd(str) | 136 | local 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 |
171 | end | 187 | end |
172 | 188 | ||
173 | local function arbnum(str) | 189 | local indorarbnum = "Indian" |
190 | |||
191 | function arabluatex.setnums(opt) | ||
192 | if opt == "Indian" | ||
193 | then | ||
194 | indorarbnum = "Indian" | ||
195 | else | ||
196 | indorarbnum = "Arabic" | ||
197 | end | ||
198 | end | ||
199 | |||
200 | local 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 |
178 | end | 205 | end |
179 | 206 | ||
180 | local function indnum(str) | 207 | local 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 |
188 | end | 223 | end |
@@ -590,11 +625,19 @@ local function novoceasy(str) | |||
590 | return str | 625 | return str |
591 | end | 626 | end |
592 | 627 | ||
593 | local function transdmg(str, rules) | 628 | local 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 | |||
1264 | function arabluatex.ayah(str) | 1307 | function 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 |