diff options
author | Norbert Preining <norbert@preining.info> | 2022-06-10 03:02:43 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2022-06-10 03:02:43 +0000 |
commit | fb4909f4112d8b778570cf1c2e25ca18c63bc1ca (patch) | |
tree | 92ffbc5b652338ec52811278f6f700718b359c93 /macros | |
parent | 16559ce13a74c7a182875559b379cac00b07efda (diff) |
CTAN sync 202206100302
Diffstat (limited to 'macros')
27 files changed, 2837 insertions, 1047 deletions
diff --git a/macros/latex/contrib/coollist/README b/macros/latex/contrib/coollist/README index a0cd606cdf..238e65a8d9 100644 --- a/macros/latex/contrib/coollist/README +++ b/macros/latex/contrib/coollist/README @@ -1,3 +1,17 @@ -This is the coollist package: a LaTeX package intended for the manipulation of lists (defined as sequences of tokens delimited by commas). +This is the coollist package: a LaTeX package intended for the +manipulation of lists (defined as sequences of tokens delimited by commas). -It is released under the Limited General Product License.
\ No newline at end of file +License +------- + +This package is released under the GNU Lesser General Public License. +See https://www.gnu.org/licenses/licenses.html#LGPL for more details. + +Contact +------- + +Any bugs may be reported to the author by sending an email to the +address with the first part being "latex", a dash, then "inquiries", +then an at sign, the next part is nsetzer, and finally it ends in dot com. + +(This README updated 2022-06-09.) diff --git a/macros/latex/contrib/coollist/coollist.dtx b/macros/latex/contrib/coollist/coollist.dtx index 2e6b0e3a84..9fa4ea70a8 100644 --- a/macros/latex/contrib/coollist/coollist.dtx +++ b/macros/latex/contrib/coollist/coollist.dtx @@ -2,13 +2,15 @@ % %<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01] %<package>\ProvidesPackage{coollist} -%<package> [2009/09/20 v1.4 COntent Oriented LaTeX Lists] +%<package> [2022/06/09 v1.4 COntent Oriented LaTeX Lists] %<package>\RequirePackage{ifthen} %<package>\RequirePackage{amsmath} %<package>\RequirePackage{amssymb} %<package>\RequirePackage{coolstr} %<package>\RequirePackage{forloop} % +% Update on 2022/06/09 purely to clarify the license; no code changes. +% This package is released under the GNU LGPL. % %<*driver> \documentclass{ltxdoc} @@ -767,4 +769,4 @@ % % % \Finale -\endinput
\ No newline at end of file +\endinput diff --git a/macros/luatex/generic/luakeys/README.md b/macros/luatex/generic/luakeys/README.md index 10793d353e..ca73100b64 100644 --- a/macros/luatex/generic/luakeys/README.md +++ b/macros/luatex/generic/luakeys/README.md @@ -30,6 +30,120 @@ This work has the LPPL maintenance status `maintained`. The Current Maintainer of this work is Josef Friedrich. +## Documentation + +### Key-value pair definitions + +```lua +local defs = { + key = { + -- Allow different key names. + -- or a single string: alias = 'k' + alias = { 'k', 'ke' }, + + -- The key is always included in the result. If no default value is + -- definied, true is taken as the value. + always_present = false, + + -- Only values listed in the array table are allowed. + choices = { 'one', 'two', 'three' }, + + -- Possible data types: boolean, dimension, integer, number, string + data_type = 'string', + + default = true, + + -- The key belongs to a mutually exclusive group of keys. + exclusive_group = 'name', + + -- > \MacroName + macro = 'MacroName', -- > \MacroName + + -- See http://www.lua.org/manual/5.3/manual.html#6.4.1 + match = '^%d%d%d%d%-%d%d%-%d%d$', + + -- The name of the key, can be omitted + name = 'key', + opposite_keys = { [true] = 'show', [false] = 'hide' }, + process = function(value, input, result, unknown) + return value + end, + required = true, + sub_keys = { key_level_2 = { } }, + } +} +``` + +### Parser options (opts) + +```lua +local opts = { + -- Automatically convert dimensions into scaled points (1cm -> 1864679). + convert_dimensions = false, + + -- Print the result table to the console. + debug = false, + + -- The default value for naked keys (keys without a value). + default = true, + + -- A table with some default values. The result table is merged with + -- this table. + defaults = { key = 'value' }, + + -- Key-value pair definitions. + defs = { key = { default = 'value' } }, + + -- lower, snake, upper + format_keys = { 'snake' }, + + -- Listed in the order of execution + hooks = { + kv_string = function(kv_string) + return kv_string + end, + + -- Visit all key-value pairs recursively. + keys_before_opts = function(key, value, depth, current, result) + return key, value + end, + + -- Visit the result table. + result_before_opts = function(result) + end, + + -- Visit all key-value pairs recursively. + keys_before_def = function(key, value, depth, current, result) + return key, value + end, + + -- Visit the result table. + result_before_def = function(result) + end, + + -- Visit all key-value pairs recursively. + keys = function(key, value, depth, current, result) + return key, value + end, + + -- Visit the result table. + result = function(result) + end, + }, + + -- If true, naked keys are converted to values: + -- { one = true, two = true, three = true } -> { 'one', 'two', 'three' } + naked_as_value = false, + + -- Throw no error if there are unknown keys. + no_error = false, + + -- { key = { 'value' } } -> { key = 'value' } + unpack = false, +} +local result = luakeys.parse('one,two,three', opts) +``` + ## Tasks ### Installing diff --git a/macros/luatex/generic/luakeys/luakeys-debug.sty b/macros/luatex/generic/luakeys/luakeys-debug.sty index 83ae86b08b..7fcb483741 100644 --- a/macros/luatex/generic/luakeys/luakeys-debug.sty +++ b/macros/luatex/generic/luakeys/luakeys-debug.sty @@ -17,6 +17,6 @@ % luakeys-debug.sty and luakeys-debug.tex. \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{luakeys-debug}[2022/04/04 v0.5 Debug package for luakeys.] +\ProvidesPackage{luakeys-debug}[2022/06/09 v0.6 Debug package for luakeys.] \input luakeys-debug.tex diff --git a/macros/luatex/generic/luakeys/luakeys-debug.tex b/macros/luatex/generic/luakeys/luakeys-debug.tex index ffc449ac9b..e7758cce0a 100644 --- a/macros/luatex/generic/luakeys/luakeys-debug.tex +++ b/macros/luatex/generic/luakeys/luakeys-debug.tex @@ -37,7 +37,10 @@ }% \def\luakeysdebug@parse@options#1{ \directlua{ - luakeys.save('debug_options', luakeys.parse('#1')) + luakeys.save( + 'debug_options', + luakeys.parse('#1', { format_keys = { 'snake', 'lower' } }) + ) } }% \def\luakeysdebug@output#1{ @@ -47,7 +50,7 @@ \directlua{ local result = luakeys.parse('\luaescapestring{\unexpanded{#1}}', luakeys.get('debug_options')) tex.print(luakeys.stringify(result, true)) - luakeys.print(result) + luakeys.debug(result) } } }% diff --git a/macros/luatex/generic/luakeys/luakeys-doc.pdf b/macros/luatex/generic/luakeys/luakeys-doc.pdf Binary files differindex 07f14d206b..6fe42295c4 100644 --- a/macros/luatex/generic/luakeys/luakeys-doc.pdf +++ b/macros/luatex/generic/luakeys/luakeys-doc.pdf diff --git a/macros/luatex/generic/luakeys/luakeys-doc.tex b/macros/luatex/generic/luakeys/luakeys-doc.tex index 3f7d1b0ea1..bc9a55f632 100644 --- a/macros/luatex/generic/luakeys/luakeys-doc.tex +++ b/macros/luatex/generic/luakeys/luakeys-doc.tex @@ -1,6 +1,6 @@ \documentclass{ltxdoc} -\usepackage{hyperref} +\usepackage[hidelinks]{hyperref} \EnableCrossrefs \CodelineIndex \RecordChanges @@ -17,8 +17,24 @@ \setminted{ breaklines=true, fontsize=\footnotesize, + style=manni, } \def\lua#1{\mintinline{lua}|#1|} +\def\latex#1{\mintinline{latex}|#1|} + +\NewDocumentCommand { \InputLatexExample } { O{} m } { + \begin{mdframed} + \inputminted[linenos=false,#1]{latex}{examples/#2} + \end{mdframed} +} + +\NewDocumentCommand { \InputLuaExample } { O{} m } { + \begin{mdframed} + \inputminted[linenos=false,#1]{lua}{examples/#2} + \end{mdframed} +} + +\catcode`_=12 \begin{document} @@ -30,19 +46,13 @@ \url{josef@friedrich.rocks}\\% \href{https://github.com/Josef-Friedrich/luakeys}{github.com/Josef-Friedrich/luakeys}% } -\date{v0.5 from 2022/04/04} +\date{v0.6 from 2022/06/09} \maketitle \vfill -%level1={level2={level3={dim=1cm,bool=true,num=-0.001,str=lua}}} - -\begin{minted}{lua} -local luakeys = require('luakeys') -local kv = luakeys.parse('level1={level2={level3={dim=1cm,bool=true,num=-0.001,str=lua}}}') -luakeys.print(kv) -\end{minted} +\InputLuaExample[firstline=4,lastline=7]{first-page.lua} \noindent Result: @@ -52,12 +62,11 @@ Result: { ['level1'] = { ['level2'] = { - ['level3'] = { - ['dim'] = 1864679, - ['bool'] = true, - ['num'] = -0.001 - ['str'] = 'lua', - } + ['naked'] = true, + ['dim'] = 1864679, + ['bool'] = false, + ['num'] = -0.001, + ['str'] = 'lua,{}', } } } @@ -77,35 +86,47 @@ Result: \section{Introduction} \noindent -|luakeys| is a Lua module that can parse key-value options like the -\TeX{} packages \href{https://www.ctan.org/pkg/keyval}{keyval}, +% |luakeys| ist ein Lua-Modul / Lua\TeX package, das wie die Pakete ... +% Schlüssel-Wert-Optionen analysieren kann. +|luakeys| is a Lua module / Lua\TeX package that can parse key-value +options like the \TeX{} packages +\href{https://www.ctan.org/pkg/keyval}{keyval}, \href{https://www.ctan.org/pkg/kvsetkeys}{kvsetkeys}, \href{https://www.ctan.org/pkg/kvoptions}{kvoptions}, \href{https://www.ctan.org/pkg/xkeyval}{xkeyval}, -\href{https://www.ctan.org/pkg/pgfkeys}{pgfkeys} etc. do. |luakeys|, -however, accompilshes this task entirely, by using the Lua language and -doesn’t rely on \TeX{}. Therefore this package can only be used with the -\TeX{} engine Lua\TeX{}. Since |luakeys| uses +\href{https://www.ctan.org/pkg/pgfkeys}{pgfkeys} etc. +% +% |luakeys|, erfüllt diese Aufgabe jedoch, indem es die Sprache Lua +% verwendet und nicht auf \TeX{} angewiesen ist. +|luakeys|, however, accomplishes this task by using the Lua language and +doesn’t rely on \TeX{}. +% +% Deshalb kann dieses Paket nur mit der \TeX{}-Engine Lua\TeX{} +% verwendet werden. +Therefore this package can only be used with the +\TeX{} engine Lua\TeX{}. +% +% Da |luakeys| \href{http://www.inf.puc-rio.br/~roberto/lpeg/}{LPeg} +% verwendet, sollte der Parsing-Mechanismus ziemlich robust sein. +Since |luakeys| uses \href{http://www.inf.puc-rio.br/~roberto/lpeg/}{LPeg}, the parsing mechanism should be pretty robust. The TUGboat article \href{http://www.tug.org/tugboat/tb30-1/tb94wright-keyval.pdf} {“Implementing key–value input: An introduction” (Volume 30 (2009), No. 1)} -by Joseph Wright and Christian Feuersänger gives a good overview of the -available key-value packages. +by \emph{Joseph Wright} and \emph{Christian Feuersänger} gives a good +overview of the available key-value packages. This package would not be possible without the article \href{https://tug.org/TUGboat/tb40-2/tb125menke-lpeg.pdf} -{Parsing complex data formats in LuaTEX with LPEG (Volume 40 (2019), No. 2)}. +{“Parsing complex data formats in LuaTEX with LPEG” (Volume 40 (2019), No. 2)}. %----------------------------------------------------------------------- % %----------------------------------------------------------------------- -\clearpage - -\section{Usage} +\section{How the package is loaded} %% % @@ -113,28 +134,15 @@ This package would not be possible without the article \subsection{Using the Lua module \texttt{luakeys.lua}} -The core functionality of this package is realized in Lua. So you can -use \texttt{luakeys} without using the wrapper \TeX{} files -\texttt{luakeys.sty} and \texttt{luakeys.tex}. +% Die Kernfunktionalität dieses Pakets ist in Lua realisiert. +The core functionality of this package is realized in Lua. +% +% Sie können also |luakeys| auch ohne die Wrapper-Dateien +% \texttt{luakeys.sty} und \texttt{luakeys.tex} verwenden. +So you can use |luakeys| even without using the wrapper files +|luakeys.sty| and |luakeys.tex|. -\begin{minted}{latex} -\documentclass{article} -\directlua{ - luakeys = require('luakeys') -} - -\newcommand{\helloworld}[2][]{ - \directlua{ - local keys = luakeys.parse('\luaescapestring{\unexpanded{#1}}') - luakeys.print(keys) - local marg = '#2' - tex.print(keys.greeting .. ', ' .. marg .. keys.punctuation) - } -} -\begin{document} -\helloworld[greeting=hello,punctuation=!]{world} -\end{document} -\end{minted} +\InputLatexExample{loading/lua.tex} %% % @@ -142,6 +150,22 @@ use \texttt{luakeys} without using the wrapper \TeX{} files \subsection{Using the Lua\LaTeX{} wrapper \texttt{luakeys.sty}} +% Der Paketmanager MikTeX lädt beispielsweise Pakete erst bei Bedarf +% herunter. +For example, the MiK\TeX{} package manager downloads packages only when +needed. +% +% Es wurde berichtet, dass dieser automatische Download nur mit Hilfe der +% Hüll-Dateien funktioniert. +It has been reported that this automatic download only works with this +wrapper files. +% +% Wahrscheinlich hält MiK\TeX nach einem Auftreten des LaTeX macros +% “\latex{\usepackage{luakeys}} ”Ausschau. +Probably MiK\TeX{} is searching for an occurrence of the \LaTeX{} macro +“\latex{\usepackage{luakeys}}”. + +% Die mitgelieferte Lua\LaTeX{}-Datei ist recht klein: The supplied Lua\LaTeX{} file is quite small: \begin{minted}{latex} @@ -153,19 +177,7 @@ The supplied Lua\LaTeX{} file is quite small: \noindent It loads the Lua module into the global variable \texttt{luakeys}. -\begin{minted}{latex} -\documentclass{article} -\usepackage{luakeys} - -\begin{document} - \directlua{ - local keys = luakeys.parse('one,two,three') - tex.print(keys[1]) - tex.print(keys[2]) - tex.print(keys[3]) - } -\end{document} -\end{minted} +\InputLatexExample{loading/latex.tex} %% % @@ -184,31 +196,896 @@ line: It does the same as the Lua\LaTeX{} wrapper and loads the Lua module \texttt{luakeys.lua} into the global variable \texttt{luakeys}. +\InputLatexExample{loading/tex.tex} + +\section{Lua interface / API} + +To learn more about the individual functions (local functions), please +read the \href{https://josef-friedrich.github.io/luakeys/}{source code +documentation}, which was created with +\href{http://stevedonovan.github.io/ldoc/}{LDoc}. The Lua module exports +this functions and tables: + +\InputLuaExample[firstline=3,lastline=12]{export.lua} + +\subsection{Lua indentifier names} + +% Das Projekt verwendet einige wenige Abkürzungen für Variablennamen, +% die hoffentlich für externe Leser eindeutig und bekannt sind. +The project uses a few abbreviations for variable names that are +hopefully unambiguous and familiar to external readers. + +\begin{center} +\begin{tabular}{lll} +Abbreviation & spelled out & Example \\\hline +\lua{kv_string} & Key-value string & \lua{'key=value'} \\ +\lua{opts} & Options (for the parse function) & \lua{ { no_error = false } } \\ +\lua{defs} & Definitions \\ +\lua{def} & Definition \\ +\lua{attr} & Attributes (of a definition) \\ +\end{tabular} +\end{center} + +\noindent +% Diese nicht abgekürzten Variablennamen werden häufig verwendet. +These unabbreviated variable names are commonly used. +\begin{center} +\begin{tabular}{ll} + +\lua{result} & +% Das Endergebnis aller einzelnen Übersetzungs- und Normalisierungsschritte +The final result of all individual parsing and normalization steps. \\ + +\lua{unknown} & +% Ein Tabelle mit unbekannten, nicht definierten Schlüssel-Wert-Paaren +A table with unknown, undefinied key-value pairs. \\ + +\lua{raw} & +% Das unbearbeitete, rohe Ergebnis der LPeg-Syntaxanalyse. +The raw result of the Lpeg grammar parser. \\ +\end{tabular} +\end{center} + +%% +% +%% + +\subsection{Function \texttt{parse(kv_string, opts): result, unknown, raw}} +\label{parse} + +% Die Function parse ist die wichtigste Funktion des Pakets. +The function \lua{parse(kv_string, opts)} is the most important function +of the package. +% Sie konvertiert eine Schlüssel-Wert-Zeichenkette in eine Lua Tabelle. +It converts a key-value string into a Lua table. + \begin{minted}{latex} -\input luakeys.tex +\newcommand{\mykeyvalcmd}[2][]{ + \directlua{ + result = luakeys.parse('#1') + luakeys.debug(result) + } + #2 +} +\mykeyvalcmd[one=1]{test} +\end{minted} +\noindent +In plain \TeX: + +\begin{minted}{latex} +\def\mykeyvalcommand#1{ + \directlua{ + result = luakeys.parse('#1') + luakeys.debug(result) + } +} +\mykeyvalcmd{one=1} +\end{minted} + +\subsection{Options to configure the \texttt{parse} function} + +\noindent +The \lua{parse} function can be called with an options table. This +options are supported: + +\InputLuaExample[firstline=5,lastline=69]{opts/all-opts.lua} + +\noindent +The options can also be set globally using the exported table +|opts|: + +\InputLuaExample[firstline=4,lastline=4]{opts/exported-default-opts.lua} + +\InputLuaExample[firstline=10,lastline=11]{opts/exported-default-opts.lua} + +%% +% +%% + +\subsubsection{Option “\texttt{convert_dimensions}”} + +If you set the option \lua{convert_dimensions} to \lua{true}, |luakeys| +detects the \TeX{} dimensions and converts them into scaled points using +the function \lua{tex.sp(dim)}. + +\InputLuaExample[firstline=4,lastline=7]{opts/convert-dimensions.lua} + +\noindent +By default the dimensions are not converted into scaled points. + +\InputLuaExample[firstline=13,lastline=18]{opts/convert-dimensions.lua} + +\noindent +If you want to convert a scale point into a unit string you can use the module +\href{https://raw.githubusercontent.com/latex3/lualibs/master/lualibs-util-dim.lua}{lualibs-util-dim.lua}. + +\begin{minted}{lua} +require('lualibs') +tex.print(number.todimen(tex.sp('1cm'), 'cm', '%0.0F%s')) +\end{minted} + +%% +% +%% + +\subsubsection{Option “\texttt{debug}”} + +If the option “debug” is set to ture, the result table is printed to the +console. + +\begin{minted}{latex} +\documentclass{article} +\usepackage{luakeys} +\begin{document} \directlua{ - local keys = luakeys.parse('one,two,three') - tex.print(keys[1]) - tex.print(keys[2]) - tex.print(keys[3]) + luakeys.parse('one,two,three', { debug = true }) } -\bye +debug +\end{document} \end{minted} +\begin{verbatim} +This is LuaHBTeX, Version 1.15.0 (TeX Live 2022) +... +(./debug.aux) (/usr/local/texlive/texmf-dist/tex/latex/base/ts1cmr.fd) +{ + ['three'] = true, + ['two'] = true, + ['one'] = true, +} + [1{/usr/ +local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map}] (./debug.aux) +) +... +Transcript written on debug.log. +\end{verbatim} + +%% +% +%% + +\subsubsection{Option “\texttt{default}”} +\label{option-default} + +% Mit der Option \lua{default} kann angegeben werden, welchen Wert +% nackte Schlüssel (Schlüssel ohne Wert) erhalten. Diese Option hat +% keinen Einfluss auf Schlüssel mit Werten. +The option \lua{default} can be used to specify which value naked keys +(keys without a value) get. This option has no influence on keys with +values. + +\InputLuaExample[firstline=4,lastline=5]{opts/default.lua} + +\noindent +% Standardmäßig erhalten nackte Schlüssel den Wert \lua{true}. +By default, naked keys get the value \lua{true}. + +\InputLuaExample[firstline=11,lastline=12]{opts/default.lua} + +%% +% +%% + +\subsubsection{Option “\texttt{defaults}”} +\label{options-defaults} + +% Mit der Attribut „defaults“ kann nicht nur ein einiger Standardwert +% angegeben werden, sondern eine ganze Tabelle mit Standardwerten. +The option “defaults” can be used to specify not only one default value, +but a whole table of default values. +% Die Ergebnistabelle wird mit der Tabelle bestehend aus Standardwerten +% vereinigt. +The result table is merged into the defaults table. +% Werte aus der Tabelle mit Standardwerten werden von Werten der +% Ergebnistabelle überschrieben. +Values in the defaults table are +overwritten by values in the result table. + +\InputLuaExample[firstline=4,lastline=7]{opts/defaults.lua} + +%% +% +%% + +\subsubsection{Option “\texttt{defs}”} + +% Für mehr Information wie Schlüssel definiert werden, lesen sie das +% kapitel 3.2 +For more informations on how keys are defined, see section \ref{define}. +% Wenn sie die Option \lua{defs} verwenden, können sie auf den +% Aufruf der Funktion \lua{define} verzichten. +If you use the \lua{defs} option, you don't need to call the +\lua{define} function. +% +% Anstatt +Instead of ... + +\InputLuaExample[firstline=4,lastline=5]{opts/defs.lua} + +\noindent +% können wir schreiben .. +we can write ... + +\InputLuaExample[firstline=11,lastline=13]{opts/defs.lua} + +%% +% +%% + +\subsubsection{Option “\texttt{format_keys}”} + +\begin{description} +\item[lower] \strut + +\InputLuaExample[firstline=4,lastline=5]{opts/format-keys.lua} + +\item[snake] \strut + +\InputLuaExample[firstline=11,lastline=12]{opts/format-keys.lua} + +\item[upper] \strut + +\InputLuaExample[firstline=18,lastline=19]{opts/format-keys.lua} +\end{description} + +%% +% +%% + +\subsubsection{Option “\texttt{hooks}”} + +% Die folgenden Hooks bzw. Callback-Funktionen ermöglichen es in den +% Verarbeitungsprozess der \lua{parse}-Function einzugreifen. +The following hooks or callback functions allow to intervene in the +processing of the \lua{parse} function. +% +% Die Funktionen sind in der Verarbeitungsreihenfolge aufgelistet. +The functions are listed in processing order. +% +% \lua{*_before_opts} bedeutet, dass die Hooks nach der LPeg Syntaxanalyse +% und vor dem Anwenden der Optionen ausgeführt +\lua{*_before_opts} means that the hooks are executed after the LPeg +syntax analysis and before the options are applied. +% +% Die Hooks \lua{*_before_defs} werden vor dem Anwenden der +% Schlüssel-Wert-Definitionen ausgeführt +The \lua{*_before_defs} hooks are executed before applying the key value +definitions. + +\def\TmpSignature#1{ + { + \scriptsize\texttt{ = #1} + } +} + +\def\TmpKeySignature{ + \TmpSignature{function(key, value, depth, current, result): key, value} +} +\def\TmpResultSignature{ + \TmpSignature{function(result): void} +} + +\begin{enumerate} +\item \lua{kv_string} \TmpSignature{function(kv_string): kv_string} +\item \lua{keys_before_opts} \TmpKeySignature +\item \lua{result_before_opts} \TmpResultSignature +\item \lua{keys_before_def} \TmpKeySignature +\item \lua{result_before_def} \TmpResultSignature +\item (\lua{process}) (has to be definied using defs, see \ref{attr-process}) +\item \lua{keys} \TmpKeySignature +\item \lua{result} \TmpResultSignature +\end{enumerate} + +\paragraph{\texttt{kv_string}} + +% Der Hook \lua{kv_string} wird als erste +% der Hook-Funktionen noch vor der LPeg-Syntax-Analyse aufgerufen. +The \lua{kv_string} hook is called as the first of the hook functions +before the LPeg syntax parser is executed. + +\InputLuaExample[firstline=4,lastline=11]{hooks/kv-string.lua} + +\paragraph{\texttt{keys_*}} + +% Die Hooks \lua{keys_*} werden rekursiv auf jeden Schlüssel in der +% aktuellen Ergebnistabelle aufgerufen. +The hooks \lua{keys_*} are called recursively on each key in the current +result table. +% Die Hook-Funktion muss zwei Werte zurückgeben: \lua{key, value} +The hook function must return two values: \lua{key, value}. +% +% Das folgende Beispiel gibt \lua{key} und \lua{value} unverändert zurück, +% sodass die Ergebnistabelle nicht verändert wird. +The following example returns \lua{key} and \lua{value} unchanged, so +the result table is not changed. + +\InputLuaExample[firstline=4,lastline=11]{hooks/keys-unchanged.lua} + +\noindent +% Das nächste Beispiel demonstriert den dritten Parameter \lua{depth} +% der Hook-Funktion. +The next example demonstrates the third parameter \lua{depth} of the +hook function. + +\InputLuaExample[firstline=4,lastline=16]{hooks/keys-depth.lua} + +\paragraph{\texttt{result_*}} + +% Die Hooks \lua{result_*} werden einmal mit der aktuellen +% Ergebnistabelle als Parameter aufgerufen. +The hooks \lua{result_*} are called once with the current result table +as a parameter. + +%% +% +%% + +\subsubsection{Option “\texttt{naked_as_value}”} + +% Mit Hilfe der Option \lua{naked_as_value} werden nackte Schlüssel +% nicht mit einem Standardwert versehen, sondern als Werte in die +% Lua-Tabelle abgelegt. +With the help of the option \lua{naked_as_value}, naked keys are not +given a default value, but are stored as values in a Lua table. + +\InputLuaExample[firstline=4,lastline=5]{opts/naked-as-value.lua} + +\noindent +If we set the option \lua{naked_as_value} to \lua{true}: + +\InputLuaExample[firstline=11,lastline=14]{opts/naked-as-value.lua} + +%% +% +%% + +\subsubsection{Option “\texttt{no_error}”} + +% Standardmaßig wirft parse-Funktion einen Fehler, wenn es unbekannte +% Schlüssel gibt. +By default the parse function throws an error if there are unknown keys. +% Mit Hilfe der Option \lua{no_error} kann dies unterbunden werden. +This can be prevented with the help of the \lua{no_error} option. + +\InputLuaExample[firstline=5,lastline=6]{opts/no-error.lua} + +\noindent +If we set the option \lua{no_error} to \lua{true}: + +\InputLuaExample[firstline=9,lastline=10]{opts/no-error.lua} + +%% +% +%% + +\subsubsection{Option “\texttt{unpack}”} + +% Mit Hilfe der Option \lua{unpack} werden alle Tabellen, die nur aus +% einem einzigen nackten Schlüssel bzw. einen einzigen alleinstehenden +% Wert bestehen, aufgelöst. +With the help of the option \lua{unpack}, all tables that consist of +only one a single naked key or a single standalone value are unpacked. + +\InputLuaExample[firstline=4,lastline=5]{opts/unpack.lua} + +\InputLuaExample[firstline=11,lastline=12]{opts/unpack.lua} + +%% +% +%% + +\subsection{Function \texttt{define(defs, opts): parse}} +\label{define} + +The \lua{define} function returns a \lua{parse} function (see +\ref{parse}). +The name of a key can be specified in three ways: + +\begin{enumerate} +\item as a string. +\item as a key in a Lua table. The definition of the corresponding +key-value pair is then stored under this key. +\item by the “name” attribute. +\end{enumerate} + +\InputLuaExample[firstline=4,lastline=16]{functions/define.lua} + +\noindent +For nested definitions, only the last two ways of specifying the key +names can be used. + +\InputLuaExample[firstline=26,lastline=33]{functions/define.lua} + +%----------------------------------------------------------------------- +% +%----------------------------------------------------------------------- + +\subsection{Attributes to define a key-value pair} + +% Die Definition eines Schlüssel-Wert-Paares kann mit Hilfe von +% verschiedenen Attributen vorgenommen werden. +The definition of a key-value pair can be made with the help of various +attributes. +% +% Der Name „Attribut“ für eine Option, einen Schlüssel, eine Eigenschaft +% (um nur einige Benennungsmöglichkeiten aufzuzählen) zur +% Schlüssel-Definition, wurde bewusst gewählt, um sie von den Optionen +% der Funktion \lua{parse} zu unterscheiden. +The name \emph{“attribute”} for an option, a key, a property ... (to +list just a few naming possibilities) to define keys, was deliberately +chosen to distinguish them from the options of the \lua{parse} function. +% +% Das folgende Codebeispiel listet alle Attribute auf, die verwendet +% werden können, um Schlüssel-Wert-Paare zu definieren. +The code example below lists all the attributes that can be used to +define key-value pairs. + +\InputLuaExample[firstline=5,lastline=41]{defs/all-attrs.lua} + +%% +% +%% + +\subsubsection{Attribute “\texttt{alias}”} + +With the help of the \lua{alias} attribute, other key names can be used. +The value is always stored under the original key name. A single alias +name can be specified by a string ... + +\InputLuaExample[firstline=4,lastline=7]{defs/attrs/alias.lua} + +\noindent +multiple aliases by a list of strings. + +\InputLuaExample[firstline=13,lastline=16]{defs/attrs/alias.lua} + +%% +% +%% + +\subsubsection{Attribute “\texttt{always_present}”} + +% Die Option \lua{default} wird nur bei nackten Schlüsseln verwendet. +The \lua{default} attribute is used only for naked keys. + +\InputLuaExample[firstline=4,lastline=5]{defs/attrs/always-present.lua} + +\noindent +% Wird die Option \lua{always_present} auf wahr gesetzt, wird der +% Schlüssel immer ins Ergebnis mit übernommen. +If the attribute \lua{always_present} is set to true, the key is always +included in the result. If no default value is definied, true is taken +as the value. + +\InputLuaExample[firstline=11,lastline=12]{defs/attrs/always-present.lua} + +%% +% +%% + +\subsubsection{Attribute “\texttt{choices}”} + +% source: Python argparse documentation. +Some key values should be selected from a restricted set of choices. +These can be handled by passing an array table containing choices. + +\InputLuaExample[firstline=4,lastline=5]{defs/attrs/choices.lua} + +\noindent +When the key-value pair is parsed, values will be checked, and an error +message will be displayed if the value was not one of the acceptable +choices: + +\InputLuaExample[firstline=13,lastline=15]{defs/attrs/choices.lua} + +%% +% +%% + +\subsubsection{Attribute “\texttt{data_type}”} + +% source: Python argparse documentation. +The \lua{data_type} attribute allows type-checking and type conversions to +be performed. +% +% Folgende Datentypen werden unterstützt: +The following data types are supported: +\lua{'boolean'}, +\lua{'dimension'}, +\lua{'integer'}, +\lua{'number'}, +\lua{'string'}. +% +% Bei den drei Datentypen integer, number, dimension kann eine +% Typenumwandlung scheitern. +A type conversion can fail with the three data types +\lua{'dimension'}, +\lua{'integer'}, +\lua{'number'}. +% +% Dann wird eine Fehlermeldung ausgegeben. +Then an error message is displayed. + +\InputLuaExample[firstline=4,lastline=8]{defs/attrs/data-type.lua} +\InputLuaExample[firstline=11,lastline=15]{defs/attrs/data-type.lua} + +%% +% +%% + +\subsubsection{Attribute “\texttt{default}”} + +% Verwenden Sie das Attribut „\lua{default}“, um für jeden nackten Schlüssel +% einzeln einen Standardwert bereit zu stellen. +Use the \lua{default} attribute to provide a default value for each naked +key individually. +% +% Mit der globalen \lua{default} Option kann für alle nackten Schlüssel ein +% Standardwert vorgegeben werden. +With the global \lua{default} attribute (\ref{option-default}) a default +value can be specified for all naked keys. + +\InputLuaExample[firstline=4,lastline=9]{defs/attrs/default.lua} + +%% +% +%% + +\subsubsection{Attribute “\texttt{exclusive_group}”} + +% Alle Schlüssel, die der gleichen ausschließenden Gruppe angehören, +% dürfen nicht gemeinsam angegeben werden. +All keys belonging to the same exclusive group must not be specified +together. +% +% Nur ein Schlüssel aus dieser Gruppe ist erlaubt. +Only one key from this group is allowed. +% +% Als Name für diese ausschließende Gruppe kann irgend ein beliebiger +% Wert verwendet werden. +Any value can be used as a name for this exclusive group. + +\InputLuaExample[firstline=4,lastline=9]{defs/attrs/exclusive-group.lua} + +% Werden mehrer Schlüssel der Gruppe angegeben, so wird eine +% Fehlermeldung geworfen. +If more than one key of the group is specified, an error message is +thrown. + +\InputLuaExample[firstline=21,lastline=23]{defs/attrs/exclusive-group.lua} + +%% +% +%% + +\subsubsection{Attribute “\texttt{opposite_keys}”} + +% Die Option \lua{opposite_keys} ermöglicht es, gegensätzliche (nackte) +% Schlüssel in Wahrheitswerte umzuwandeln und diesen Wahrheitswert unter +% einem Zielschlüssel zu speichern. +The \lua{opposite_keys} attribute allows to convert opposite (naked) keys +into a boolean value and store this boolean under a target key. +% +% Lua erlaubt es in Tabellen Wahrheitswerte als Schlüssel zu verwenden. +% Es müssen jedoch eckige Klammern verwendet werden. +Lua allows boolean values to be used as keys in tables. +% +% Die Wahrheitswerte müssen jedoch in eckige Klammern geschrieben werden. +However, the boolean values must be written in square brackets, e. g. +\lua{{ opposite_keys = { [true] = 'show', [false] = 'hide' } }}. +% +% Beispiele für gegensätzliche Schlüssel sind: +Examples of opposing keys are: \lua{show} and \lua{hide}, \lua{dark} and +\lua{light}, \lua{question} and \lua{solution}. +% +% Das untenstehende Beispiel verwendet als gegensätzliches Schlüsselpaar +% die Schlüssel \lua{show} und \lua{hide}. +The example below uses the \lua{show} and \lua{hide} keys as the +opposite key pair. +% +% Wird der Schlüssel \lua{show} von der Funktion \lua{parse} gelesen, +% dann erhält der Zielschlüssel \lua{visibility} den Wert \lua{true}. +If the key \lua{show} is parsed by the \lua{parse} function, then the +target key \lua{visibility} receives the value \lua{true}. + +\InputLuaExample[firstline=4,lastline=7]{defs/attrs/opposite-keys.lua} + +% Wird der Schlüssel \lua{hide} gelesen, dann \lua{falsch}. +\noindent +If the key \lua{hide} is parsed, then \lua{false}. + +\InputLuaExample[firstline=13,lastline=13]{defs/attrs/opposite-keys.lua} + +%% +% +%% + +\subsubsection{Attribute “\texttt{macro}”} + +The attribute \texttt{macro} stores the value in a \TeX{} macro. + +\begin{minted}{lua} +local parse = luakeys.define({ + key = { + macro = 'MyMacro' + } +}) +parse('key=value') +\end{minted} + +\begin{minted}{latex} +\MyMacro % expands to “value” +\end{minted} + +%% +% +%% + +\subsubsection{Attribute “\texttt{match}”} + +% Der Wert des Schlüssel wird der Lua Funktion übergeben +The value of the key is passed to the Lua function +\lua{string.match(value, match)} ((\url{http://www.lua.org/manual/5.3/manual.html#pdf-string.match})). +% Werfe einen Blick in das Lua-Handbuch, wie man Patterns schreibt. +Take a look at the Lua manual on how to write patterns +(\url{http://www.lua.org/manual/5.3/manual.html#6.4.1}) + +\InputLuaExample[firstline=4,lastline=6]{defs/attrs/match.lua} + +\noindent +% Kann das Pattern im Wert nicht gefunden werden, wird eine +% Fehlermeldung ausgegeben. +If the pattern cannot be found in the value, an error message is issued. + +\InputLuaExample[firstline=14,lastline=17]{defs/attrs/match.lua} + +\noindent +% Der Schlüssel erhält das Ergebnis der Funktion \lua{string.match(value, +% match)}, dass bedeutet, dass der ursprüngliche Wert unter +% Umständen nicht vollständig in den Schlüssel gespeichert wird. +The key receives the result of the function \lua{string.match(value, +match)}, which means that the original value may not be stored +completely in the key. + +\InputLuaExample[firstline=22,lastline=23]{defs/attrs/match.lua} + +\noindent +% Das Präfix “waste ” und das Suffix “ rubbisch” der Zeichenketten wird +% verworfen. +The prefix “waste ” and the suffix “ rubbisch” of the string are +discarded. + +\InputLuaExample[firstline=29,lastline=29]{defs/attrs/match.lua} + +\noindent +% Da Funktion \lua{string.match(value, match)} immer eine Zeichenkette +% zurückgibt, ist der Wert des Schlüssel auch immer eine Zeichenkette. +Since function \lua{string.match(value, match)} always returns a string, +the value of the key is also always a string. + +%% +% +%% + +\subsubsection{Attribute “\texttt{name}”} + +% Die Option \lua{name} ermöglicht eine alternative Notation von +% Schlüsselnamen. +The \lua{name} attribute allows an alternative notation of key names. +% +% Anstatt ... +Instead of ... + +\InputLuaExample[firstline=4,lastline=5]{defs/attrs/name.lua} + +\noindent +% ... können wir schreiben: +... we can write: + +\InputLuaExample[firstline=11,lastline=15]{defs/attrs/name.lua} + +%% +% +%% + +\subsubsection{Attribute “\texttt{process}”} +\label{attr-process} + +The \lua{process} attribute can be used to define a function whose return +value is passed to the key. Four parameters are passed when the +function is called: + +\begin{enumerate} +\item \lua{value}: +% Der zum schlüssel gehörende aktuelle Wert. +The current value asssociated with the key. + +\item \lua{input}: +% Die Ergebnis-Tabelle, die vor dem Zeitpunkt geklont wurde, als mit dem +% Anwenden der Definitionen begonnen wurde. +The result table cloned before the time the definitions started to be applied. + +\item \lua{result}: The table in which the final result will be saved. + +\item \lua{unknown}: The table in which the unknown key-value pairs +are stored. +\end{enumerate} + +% Das folgende Beispiel demonstriert den Parameter \lua{value}. +\noindent +The following example demonstrates the \lua{value} parameter: +\InputLuaExample[firstline=4,lastline=14]{defs/attrs/process.lua} + +\noindent +The following example demonstrates the \lua{input} parameter: + +\InputLuaExample[firstline=22,lastline=34]{defs/attrs/process.lua} + +\noindent +The following example demonstrates the \lua{result} parameter: + +\InputLuaExample[firstline=42,lastline=50]{defs/attrs/process.lua} + +\noindent +The following example demonstrates the \lua{unknown} parameter: + +\InputLuaExample[firstline=58,lastline=65]{defs/attrs/process.lua} +\InputLuaExample[firstline=69,lastline=69]{defs/attrs/process.lua} + +%% +% +%% + +\subsubsection{Attribute “\texttt{required}”} + +\InputLuaExample[firstline=4,lastline=5]{defs/attrs/required.lua} + +\InputLuaExample[firstline=13,lastline=14]{defs/attrs/required.lua} + +\noindent +A recursive example: + +\InputLuaExample[firstline=18,lastline=23]{defs/attrs/required.lua} +\InputLuaExample[firstline=29,lastline=30]{defs/attrs/required.lua} +\InputLuaExample[firstline=38,lastline=39]{defs/attrs/required.lua} + +%% +% +%% + +\subsubsection{Attribute “\texttt{sub_keys}”} + +% Mit dem Attribut \lua{sub_keys} können ineinander verschachtelte +% Schlüssel-Wert-Paar-Definitionen aufgebaut werden. +The \lua{sub_keys} attribute can be used to build nested key-value pair +definitions. + +\InputLuaExample[firstline=4,lastline=16]{defs/attrs/sub-keys.lua} + +%----------------------------------------------------------------------- +% +%----------------------------------------------------------------------- + +\subsection{Function \texttt{render(result): string}} + +The function \lua{render(result)} reverses the function +\lua{parse(kv_string)}. It takes a Lua table and converts this table +into a key-value string. The resulting string usually has a different +order as the input table. + +\InputLuaExample[firstline=4,lastline=10]{functions/render.lua} + +\noindent +In Lua only tables with 1-based consecutive integer keys (a.k.a. array +tables) can be parsed in order. + +\InputLuaExample[firstline=16,lastline=17]{functions/render.lua} + +%% +% +%% + +\subsection{Function \texttt{debug(result): void}} + +The function \lua{debug(result)} pretty prints a Lua table to standard +output (stdout). It is a utility function that can be used to debug and +inspect the resulting Lua table of the function \lua{parse}. You have to +compile your \TeX{} document in a console to see the terminal output. + +\InputLuaExample[firstline=4,lastline=5]{functions/debug.lua} + +\noindent +The output should look like this: + +\begin{minted}{md} +{ + ['level1'] = { + ['level2'] = { + ['key'] = 'value', + }, + } +} +\end{minted} + +%% +% +%% + +\subsection{Function \texttt{save(identifier, result): void}} + +The function \lua{save(identifier, result)} saves a result (a +table from a previous run of \lua{parse}) under an identifier. +Therefore, it is not necessary to pollute the global namespace to +store results for the later usage. + +%% +% +%% + +\subsection{Function \texttt{get(identifier): result}} + +The function \lua{get(identifier)} retrieves a saved result from the +result store. + +%% +% +%% + +\subsection{Table \texttt{is}} + +\subsubsection{Function \texttt{is.boolean(value): boolean}} +\InputLuaExample[firstline=7,lastline=23]{is-table.lua} + +\subsubsection{Function \texttt{is.dimension(value): boolean}} +\InputLuaExample[firstline=27,lastline=37]{is-table.lua} + +\subsubsection{Function \texttt{is.integer(value): boolean}} +\InputLuaExample[firstline=41,lastline=46]{is-table.lua} + +\subsubsection{Function \texttt{is.number(value): boolean}} +\InputLuaExample[firstline=50,lastline=57]{is-table.lua} + +\subsubsection{Function \texttt{is.string(value): boolean}} +\InputLuaExample[firstline=61,lastline=67]{is-table.lua} + +%----------------------------------------------------------------------- +% +%----------------------------------------------------------------------- + \section{Syntax of the recognized key-value format} %% % %% -\subsection{A attempt to put the syntax into words} +\subsection{An attempt to put the syntax into words} A key-value pair is definied by an equal sign (\texttt{key=value}). -Several key-value pairs or values without keys are lined up with commas -(\texttt{key=value,value}) and build a key-value list. Curly brackets -can be used to create a recursive data structure of nested key-value -lists (\texttt{level1=\{level2=\{key=value,value\}\}}). +Several key-value pairs or keys without values (naked keys) are lined up +with commas (\texttt{key=value,naked}) and build a key-value list. Curly +brackets can be used to create a recursive data structure of nested +key-value lists (\texttt{level1=\{level2=\{key=value,naked\}\}}). %% % @@ -231,9 +1108,17 @@ lists (\texttt{level1=\{level2=\{key=value,value\}\}}). \alt <string-quoted> \alt <string-unquoted> +<dimension> ::= <number> <unit> + +<number> ::= <sign> ( <integer> [ <fractional> ] | <fractional> ) + +<fractional> ::= `.' <integer> + <sign> ::= `-' | `+' -<integer> ::= `0' | `1' | `2' | `3' | `4' | `5' | `6' | `7' | `8' | `9' +<integer> ::= <digit> \{ <digit> \} + +<digit> ::= `0' | `1' | `2' | `3' | `4' | `5' | `6' | `7' | `8' | `9' <unit> ::= `bp' | `BP' \alt `cc' | `CC' @@ -297,8 +1182,6 @@ into Lua’s boolean type \lua{true}, the strings \texttt{false}, % %% -\clearpage - \subsubsection{number} \begin{multicols}{2} @@ -322,35 +1205,14 @@ into Lua’s boolean type \lua{true}, the strings \texttt{false}, % %% -\clearpage - \subsubsection{dimension} -|luakeys| detects \TeX{} dimensions and automatically converts the -dimensions into scaled points using the function \lua{tex.sp(dim)}. Use -the option \lua{convert_dimensions} of the function -\lua{parse(kv_string, options)} to disalbe the automatic conversion. - -\begin{minted}{lua} -local result = parse('dim=1cm', { - convert_dimensions = false, -}) -\end{minted} - -\noindent -If you want to convert a scale point into a unit string you can use the module -\href{https://raw.githubusercontent.com/latex3/lualibs/master/lualibs-util-dim.lua}{lualibs-util-dim.lua}. - -\begin{minted}{latex} -\begin{luacode} -require('lualibs') -tex.print(number.todimen(tex.sp('1cm'), 'cm', '%0.0F%s')) -\end{luacode} -\end{minted} - +\begin{multicols}{3} +\tiny \begin{center} \begin{tabular}{rl} -\textbf{Unit name} & \textbf{Description} \\\hline +% \textbf{Unit name} +& \textbf{Description} \\\hline bp & big point \\ cc & cicero \\ cm & centimeter \\ @@ -367,7 +1229,8 @@ sp & scaledpoint \\ \end{tabular} \end{center} -\begin{multicols}{2} +\columnbreak + \begin{minted}{latex} \luakeysdebug{ bp = 1bp, @@ -385,6 +1248,9 @@ sp & scaledpoint \\ sp = 1sp, } \end{minted} + +\columnbreak + \begin{minted}{lua} { ['bp'] = 65781, @@ -410,64 +1276,41 @@ sp & scaledpoint \\ \subsubsection{string} -There are two ways to specify strings: With or without quotes. If the -text have to contain commas or equal signs, then double quotation -marks must be used. - -\begin{multicols}{2} -\begin{minted}{latex} -\luakeysdebug{ - without quotes = no commas and equal signs are allowed, - with double quotes = ", and = are allowed", -} -\end{minted} -\begin{minted}{lua} -{ - ['without quotes'] = 'no commas and equal signs are allowed', - ['with double quotes'] = ', and = are allowed', -} -\end{minted} -\end{multicols} +% Es gibt zwei Möglichkeiten Zeichenketten anzugeben: +There are two ways to specify strings: +% +% Mit oder ohne doppelte Anführungszeichen. +With or without double quotes. +% +% Wenn der Text Kommas, geschweifte Klammern oder Gleichheitszeichen +% enthalten soll, müssen doppelte Anführungszeichen verwendet werden. +If the text have to contain commas, curly braces or equal signs, then +double quotes must be used. -\subsubsection{Standalone values} +\InputLuaExample[firstline=4,lastline=17]{data-types/string.lua} -Standalone values are values without a key. They are converted into an -array. In Lua an array is a table with numeric indexes (The first index -is 1). +\subsubsection{Naked keys} -\begin{multicols}{2} -\begin{minted}{latex} -\luakeysdebug{one,two,three} -\end{minted} -\columnbreak -\begin{minted}{lua} -{ 'one', 'two', 'three' } -\end{minted} +% Nackte Schlüssel sind Schlüssel ohne Wert. +Naked keys are keys without a value. +% +% Mit der Option \lua{naked_as_value} können sie als Werte in ein Feld +% übernommen werden. +Using the option \lua{naked_as_value} they can be converted into values +and stored into an array. +% +% In Lua ist ein Feld eine Tabelle mit numerischen Indizes (der erste +% Index ist 1). +In Lua an array is a table with numeric indexes (The first index is 1). -\noindent -is equivalent to - -\begin{minted}{lua} -{ - [1] = 'one', - [2] = 'two', - [3] = 'three', -} -\end{minted} -\end{multicols} +\InputLatexExample[firstline=5,lastline=12]{luakeysdebug/naked-keys.tex} \noindent +% VAlle erkannten Datentypen können als eigenständige Werte verwendet +% werden. All recognized data types can be used as standalone values. -\begin{multicols}{2} -\begin{minted}{latex} -\luakeysdebug{one,2,3cm} -\end{minted} -\columnbreak -\begin{minted}{lua} -{ 'one', 2, 5594039 } -\end{minted} -\end{multicols} +\InputLatexExample[firstline=14,lastline=19]{luakeysdebug/naked-keys.tex} %----------------------------------------------------------------------- % @@ -475,166 +1318,34 @@ All recognized data types can be used as standalone values. \clearpage -\section{Exported functions of the Lua module \texttt{luakeys.lua}} - -To learn more about the individual functions (local functions), please -read the \href{https://josef-friedrich.github.io/luakeys/}{source code -documentation}, which was created with -\href{http://stevedonovan.github.io/ldoc/}{LDoc}. The Lua module exports -this functions: - -\begin{minted}{lua} -local luakeys = require('luakeys') -local parse = luakeys.parse -local render = luakeys.render ---local print = luakeys.print -- That would overwrite the built-in Lua function -local save = luakeys.save -local get = luakeys.get -\end{minted} +\section{Examples} -%% -% -%% +\subsection{Extend and modify keys of existing macros} -\subsection{\texttt{parse(kv\_string, options)}: table} +Extend the includegraphics macro with a new key named \latex{caption} +and change the accepted values of the \latex{width} key. A number +between 0 and 1 is allowed and converted into +\latex{width=0.5\linewidth} -The function \lua{parse(input_string, options)} is the main method of -this module. It parses a key-value string into a Lua table. - -\begin{minted}{latex} -\newcommand{\mykeyvalcmd}[1][]{ - \directlua{ - result = luakeys.parse('#1') - luakeys.print(result) - } - #2 -} -\mykeyvalcmd[one=1]{test} -\end{minted} +\InputLuaExample{extend-includegraphics/extend-keys.lua} +\InputLatexExample{extend-includegraphics/extend-keys.tex} -\noindent -In plain \TeX: +\subsection{Process document class options} \begin{minted}{latex} -\def\mykeyvalcommand#1{ - \directlua{ - result = luakeys.parse('#1') - luakeys.print(result) - } -} -\mykeyvalcmd{one=1} -\end{minted} - -\noindent -The function can be called with an options table. This options are -supported: - -\begin{minted}{lua} -local result = parse('one,two,three', { - convert_dimensions = false, - unpack_single_array_value = false, - standalone_as_true = false, - converter = function(key, value, depth, current_table, root_table) - return key, value - end, - case_insensitive_keys = false, -}) +\directlua{luakeys.parse('\@classoptionslist')} \end{minted} -\noindent -The options can also be set globally using the exported table -|default_options|: +\InputLatexExample{class-options/test-class.cls} +\InputLatexExample{class-options/use-test-class.tex} \begin{minted}{lua} -luakeys.parse('dim=1cm') -- {dim = 1864679} -luakeys.default_options.convert_dimensions = false --- or: --- local defaults = luakeys.default_options --- defaults.convert_dimensions = false -luakeys.parse('dim=1cm') -- {dim = '1cm'} -\end{minted} - -%% -% -%% - -\subsection{\texttt{render(tbl)}: string} - -The function \lua{render(tbl)} reverses the function -\lua{parse(kv_string)}. It takes a Lua table and converts this table -into a key-value string. The resulting string usually has a different -order as the input table. - -\begin{minted}{lua} -result = luakeys.parse('one=1,two=2,tree=3,') -print(luakeys.render(result)) ---- one=1,two=2,tree=3, ---- or: ---- two=2,one=1,tree=3, ---- or: ---- ... -\end{minted} - -\noindent -In Lua only tables with 1-based consecutive integer keys (a.k.a. array -tables) can be parsed in order. - -\begin{minted}{lua} -result = luakeys.parse('one,two,three') -print(luakeys.render(result)) ---- one,two,three, (always) -\end{minted} - -%% -% -%% - -\subsection{\texttt{print(tbl): void}} - -The function \lua{print(tbl)} pretty prints a Lua table to standard -output (stdout). It is a utility function that can be used to debug and -inspect the resulting Lua table of the function \lua{parse}. You have to -compile your \TeX{} document in a console to see the terminal output. - -%\luakeysdebug{level1={level2={key=value}}} - -\begin{minted}{lua} -result = luakeys.parse('level1={level2={key=value}}') -luakeys.print(result) -\end{minted} - -\noindent -The output should look like this: - -\begin{minted}{md} { - ['level1'] = { - ['level2'] = { - ['key'] = 'value', - }, + [1] = '12pt', + [2] = 'landscape', } \end{minted} -%% -% -%% - -\subsection{\texttt{save(identifier, result): void}} - -The function \lua{save(identifier, result)} saves a result (a -table from a previous run of \lua{parse}) under an identifier. -Therefore, it is not necessary to pollute the global namespace to -store results for the later usage. - -%% -% -%% - -\subsection{\texttt{get(identifier): table}} - -The function \lua{get(identifier)} retrieves a saved result from the -result store. - %----------------------------------------------------------------------- % %----------------------------------------------------------------------- @@ -685,7 +1396,7 @@ An example of how to use the command in \LaTeX: \usepackage{luakeys-debug} \begin{document} \luakeysdebug[ - unpack single array values=false, + unpack=false, convert dimensions=false ]{one,two,three} \end{document} @@ -723,9 +1434,9 @@ An example of how to use the command in \LaTeX: \clearpage -\subsection{luakeys.tex} +\subsection{luakeys.sty} -\inputminted[linenos=true]{latex}{luakeys.tex} +\inputminted[linenos=true]{latex}{luakeys.sty} %% % @@ -766,9 +1477,22 @@ An example of how to use the command in \LaTeX: } \changes{v0.5}{2022/04/04}{ * Add possibility to change options globally -* New option: standalone\_as\_true +* New option: standalone_as_true * Add a recursive converter callback / hook to process the parse tree -* New option: case\_insensitive\_keys +* New option: case_insensitive_keys +} +\changes{v0.6}{2022/06/09}{ +* New feature: keys now can be defined using the function + “define(defs, opts)” or “define(kv_string, { defs = { key = { ... } } })” +* Rename the global options table from “default_options” to “opts” +* New option “format_keys” +* Remove option “case_insensitive_keys”. Use + “format_keys = \{ lower \}” to achieve the same effect. +* The default value of the option “convert_dimension” is now false. +* The option “standalone_as_true” is renamed to “naked_as_value”. + The boolean value of the option must be changed to the opposite to + produce the previous effect. +* The function “print()” is now called “debug()” } \pagebreak \PrintChanges diff --git a/macros/luatex/generic/luakeys/luakeys.lua b/macros/luatex/generic/luakeys/luakeys.lua index c5ccf6b01d..ae689d02c1 100644 --- a/macros/luatex/generic/luakeys/luakeys.lua +++ b/macros/luatex/generic/luakeys/luakeys.lua @@ -15,59 +15,120 @@ -- -- This work consists of the files luakeys.lua, luakeys.sty, luakeys.tex -- luakeys-debug.sty and luakeys-debug.tex. - --- A key-value parser written with Lpeg. -- --- Explanations of some LPeg notation forms: --- --- * `patt ^ 0` = `expression *` --- * `patt ^ 1` = `expression +` --- * `patt ^ -1` = `expression ?` --- * `patt1 * patt2` = `expression1 expression2`: Sequence --- * `patt1 + patt2` = `expression1 / expression2`: Ordered choice --- --- * [TUGboat article: Parsing complex data formats in LuaTEX with LPEG](https://tug.org/TUGboat/tb40-2/tb125menke-Patterndf) --- -- @module luakeys - local lpeg = require('lpeg') -local Variable = lpeg.V -local Pattern = lpeg.P -local Set = lpeg.S -local Range = lpeg.R -local CaptureGroup = lpeg.Cg -local CaptureFolding = lpeg.Cf -local CaptureTable = lpeg.Ct -local CaptureConstant = lpeg.Cc -local CaptureSimple = lpeg.C if not tex then - tex = {} + tex = { + -- Dummy function for the tests. + sp = function(input) + return 1234567 + end, + } +end + +if not token then + token = { + set_macro = function(csname, content, global) + end, + } +end + +local utils = { + --- Get the size of an array like table `{ 'one', 'two', 'three' }` = 3. + -- + -- @tparam table value A table or any input. + -- + -- @treturn number The size of the array like table. 0 if the input is + -- no table or the table is empty. + get_array_size = function(value) + local count = 0 + if type(value) == 'table' then + for _ in ipairs(value) do + count = count + 1 + end + end + return count + end, + + --- Get the size of a table `{ one = 'one', 'two', 'three' }` = 3. + -- + -- @tparam table value A table or any input. + -- + -- @treturn number The size of the array like table. 0 if the input is + -- no table or the table is empty. + get_table_size = function(value) + local count = 0 + if type(value) == 'table' then + for _ in pairs(value) do + count = count + 1 + end + end + return count + end, + + remove_from_array = function(array, element) + for index, value in pairs(array) do + if element == value then + array[index] = nil + return value + end + end + end, +} - -- Dummy function for the tests. - tex['sp'] = function (input) - return 1234567 +--- https://stackoverflow.com/a/1283608/10193818 +local function merge_tables(target, t2) + for k, v in pairs(t2) do + if type(v) == 'table' then + if type(target[k] or false) == 'table' then + merge_tables(target[k] or {}, t2[k] or {}) + elseif target[k] == nil then + target[k] = v + end + elseif target[k] == nil then + target[k] = v + end end + return target end ---- Option handling --- @section +--- http://lua-users.org/wiki/CopyTable +local function clone_table(orig) + local orig_type = type(orig) + local copy + if orig_type == 'table' then + copy = {} + for orig_key, orig_value in next, orig, nil do + copy[clone_table(orig_key)] = clone_table(orig_value) + end + setmetatable(copy, clone_table(getmetatable(orig))) + else -- number, string, boolean, etc + copy = orig + end + return copy +end --- This table stores all allowed option keys. -local option_keys = { - 'convert_dimensions', - 'unpack_single_array_values', - 'standalone_as_true', - 'converter', - 'case_insensitive_keys' +local all_options = { + convert_dimensions = false, + debug = false, + default = true, + defaults = false, + defs = false, + format_keys = false, + hooks = {}, + naked_as_value = false, + no_error = false, + postprocess = false, + preprocess = false, + unpack = true, } --- The default options. -local default_options = { - convert_dimensions = true, - unpack_single_array_values = true, - standalone_as_true = false, -} +local default_options = clone_table(all_options) local function throw_error(message) if type(tex.error) == 'function' then @@ -77,58 +138,142 @@ local function throw_error(message) end end ---- Convert a key so that it can be written as a table field without --- quotes and square brackets (for example `one 2` becomes `one_2`). --- The key can then reference values from a table using dot notation. --- (`table["one 2"]` becomes `table.one_2`). --- --- @tparam string key The key to be converted. --- --- @treturn string The converted key. -local function luafy_key(key) - return key:gsub('[^%w]+', '_') -end +local l3_code_cctab = 10 ---- Convert all keys in a table to strings containig only alphanumeric --- characters and underscores. +--- Convert back to strings +-- @section + +--- The function `render(tbl)` reverses the function +-- `parse(kv_string)`. It takes a Lua table and converts this table +-- into a key-value string. The resulting string usually has a +-- different order as the input table. In Lua only tables with +-- 1-based consecutive integer keys (a.k.a. array tables) can be +-- parsed in order. -- --- @param raw_options Some raw options. +-- @tparam table result A table to be converted into a key-value string. -- --- @treturn table Returns always a table. If the input value is not a --- an empty table is returned. -local function luafy_options(raw_options) - if type(raw_options) ~= 'table' then - raw_options = {} - end - local options = {} - for key, value in pairs(raw_options) do - options[luafy_key(key)] = value +-- @treturn string A key-value string that can be passed to a TeX +-- macro. +local function render(result) + local function render_inner(result) + local output = {} + local function add(text) + table.insert(output, text) + end + for key, value in pairs(result) do + if (key and type(key) == 'string') then + if (type(value) == 'table') then + if (next(value)) then + add(key .. '={') + add(render_inner(value)) + add('},') + else + add(key .. '={},') + end + else + add(key .. '=' .. tostring(value) .. ',') + end + else + add(tostring(value) .. ',') + end + end + return table.concat(output) end - return options + return render_inner(result) end ---- All option keys can be written with underscores or with spaces as --- separators. --- For the LaTeX version of the macro --- `\luakeysdebug[options]{kv-string}`. +--- The function `stringify(tbl, for_tex)` converts a Lua table into a +-- printable string. Stringify a table means to convert the table into +-- a string. This function is used to realize the `debug` function. +-- `stringify(tbl, true)` (`for_tex = true`) generates a string which +-- can be embeded into TeX documents. The macro `\luakeysdebug{}` uses +-- this option. `stringify(tbl, false)` or `stringify(tbl)` generate a +-- string suitable for the terminal. -- --- @tparam table options_raw Options in a raw format. The table may be --- empty or some keys are not set. +-- @tparam table result A table to stringify. -- --- @treturn table -local function normalize_parse_options (options_raw) - options_raw = luafy_options(options_raw) - local options = {} - - for _, option_name in ipairs(option_keys) do - if options_raw[option_name] ~= nil then - options[option_name] = options_raw[option_name] - else - options[option_name] = default_options[option_name] +-- @tparam boolean for_tex Stringify the table into a text string that +-- can be embeded inside a TeX document via tex.print(). Curly braces +-- and whites spaces are escaped. +-- +-- https://stackoverflow.com/a/54593224/10193818 +local function stringify(result, for_tex) + local line_break, start_bracket, end_bracket, indent + + if for_tex then + line_break = '\\par' + start_bracket = '$\\{$' + end_bracket = '$\\}$' + indent = '\\ \\ ' + else + line_break = '\n' + start_bracket = '{' + end_bracket = '}' + indent = ' ' + end + + local function stringify_inner(input, depth) + local output = {} + depth = depth or 0 + + local function add(depth, text) + table.insert(output, string.rep(indent, depth) .. text) + end + + local function format_key(key) + if (type(key) == 'number') then + return string.format('[%s]', key) + else + return string.format('[\'%s\']', key) + end end + + if type(input) ~= 'table' then + return tostring(input) + end + + for key, value in pairs(input) do + if (key and type(key) == 'number' or type(key) == 'string') then + key = format_key(key) + + if (type(value) == 'table') then + if (next(value)) then + add(depth, key .. ' = ' .. start_bracket) + add(0, stringify_inner(value, depth + 1)) + add(depth, end_bracket .. ','); + else + add(depth, key .. ' = ' .. start_bracket .. end_bracket .. ',') + end + else + if (type(value) == 'string') then + value = string.format('\'%s\'', value) + else + value = tostring(value) + end + + add(depth, key .. ' = ' .. value .. ',') + end + end + end + + return table.concat(output, line_break) end - return options + return + start_bracket .. line_break .. stringify_inner(result, 1) .. line_break .. + end_bracket +end + +--- The function `debug(tbl)` pretty prints a Lua table to standard +-- output (stdout). It is a utility function that can be used to +-- debug and inspect the resulting Lua table of the function +-- `parse`. You have to compile your TeX document in a console to +-- see the terminal output. +-- +-- @tparam table result A table to be printed to standard output for +-- debugging purposes. +local function debug(result) + print('\n' .. stringify(result, false)) end --- Parser / Lpeg related @@ -136,18 +281,42 @@ end --- Generate the PEG parser using Lpeg. -- +-- Explanations of some LPeg notation forms: +-- +-- * `patt ^ 0` = `expression *` +-- * `patt ^ 1` = `expression +` +-- * `patt ^ -1` = `expression ?` +-- * `patt1 * patt2` = `expression1 expression2`: Sequence +-- * `patt1 + patt2` = `expression1 / expression2`: Ordered choice +-- +-- * [TUGboat article: Parsing complex data formats in LuaTEX with LPEG](https://tug.org/TUGboat/tb40-2/tb125menke-Patterndf) +-- -- @treturn userdata The parser. -local function generate_parser(options) +local function generate_parser(initial_rule, convert_dimensions) + if convert_dimensions == nil then + convert_dimensions = false + end + + local Variable = lpeg.V + local Pattern = lpeg.P + local Set = lpeg.S + local Range = lpeg.R + local CaptureGroup = lpeg.Cg + local CaptureFolding = lpeg.Cf + local CaptureTable = lpeg.Ct + local CaptureConstant = lpeg.Cc + local CaptureSimple = lpeg.C + -- Optional whitespace local white_space = Set(' \t\n\r') --- Match literal string surrounded by whitespace local ws = function(match) - return white_space^0 * Pattern(match) * white_space^0 + return white_space ^ 0 * Pattern(match) * white_space ^ 0 end - local capture_dimension = function (input) - if options.convert_dimensions then + local capture_dimension = function(input) + if convert_dimensions then return tex.sp(input) else return input @@ -180,8 +349,9 @@ local function generate_parser(options) end end + -- LuaFormatter off return Pattern({ - 'list', + [1] = initial_rule, -- list_item* list = CaptureFolding( @@ -220,6 +390,9 @@ local function generate_parser(options) Variable('string_quoted') * -Variable('value') + Variable('string_unquoted'), + -- for is.boolean() + boolean_only = Variable('boolean') * -1, + -- boolean_true / boolean_false boolean = ( @@ -237,18 +410,31 @@ local function generate_parser(options) Pattern('FALSE') + Pattern('False'), + -- for is.dimension() + dimension_only = Variable('dimension') * -1, + dimension = ( - Variable('sign')^0 * white_space^0 * Variable('tex_number') * white_space^0 * Variable('unit') ) / capture_dimension, - number = - (white_space^0 * (Variable('lua_number') / tonumber) * white_space^0) , + -- for is.number() + number_only = Variable('number') * -1, + + -- capture number + number = Variable('tex_number') / tonumber, + -- sign? white_space? (integer+ fractional? / fractional) tex_number = - (Variable('integer')^1 * (Pattern('.') * Variable('integer')^1)^0) + - (Pattern('.') * Variable('integer')^1), + Variable('sign')^0 * white_space^0 * + (Variable('integer')^1 * Variable('fractional')^0) + + Variable('fractional'), + + sign = Set('-+'), + + fractional = Pattern('.') * Variable('integer')^1, + + integer = Range('09')^1, -- 'bp' / 'BP' / 'cc' / etc. -- https://raw.githubusercontent.com/latex3/lualibs/master/lualibs-util-dim.lua @@ -267,18 +453,6 @@ local function generate_parser(options) Pattern('pt') + Pattern('PT') + Pattern('sp') + Pattern('SP'), - lua_number = - Variable('int') * - Variable('frac')^-1, - - int = Variable('sign')^-1 * ( - Range('19') * Variable('integer') + Variable('integer') - ), - - frac = Pattern('.') * Variable('integer'), - sign = Set('-+'), - integer = Range('09')^1, - -- '"' ('\"' / !'"')* '"' string_quoted = white_space^0 * Pattern('"') * @@ -294,68 +468,25 @@ local function generate_parser(options) word_unquoted = (1 - white_space - Set('{},='))^1 }) +-- LuaFormatter on end ---- Get the size of an array like table `{ 'one', 'two', 'three' }` = 3. --- --- @tparam table value A table or any input. --- --- @treturn number The size of the array like table. 0 if the input is --- no table or the table is empty. -local function get_array_size(value) - local count = 0 - if type(value) == 'table' then - for _ in ipairs(value) do count = count + 1 end - end - return count -end - ---- Get the size of a table `{ one = 'one', 'two', 'three' }` = 3. --- --- @tparam table value A table or any input. --- --- @treturn number The size of the array like table. 0 if the input is --- no table or the table is empty. -local function get_table_size(value) - local count = 0 - if type(value) == 'table' then - for _ in pairs(value) do count = count + 1 end - end - return count -end - ---- Unpack a single valued array table like `{ 'one' }` into `one` or --- `{ 1 }` into `1`. --- --- @treturn If the value is a array like table with one non table typed --- value in it, the unpacked value, else the unchanged input. -local function unpack_single_valued_array_table(value, options) - if - type(value) == 'table' and - get_array_size(value) == 1 and - get_table_size(value) == 1 and - type(value[1]) ~= 'table' - then - if type(value[1]) == 'string' and options.standalone_as_true then - return value - else - return value[1] - end - end - return value -end - -local function visit_parse_tree(parse_tree, callback_func) - if type(parse_tree) ~= 'table' then - throw_error('Parse tree has to be a table') +local function visit_tree(tree, callback_func) + if type(tree) ~= 'table' then + throw_error('Parameter “tree” has to be a table, got: ' .. + tostring(tree)) end - local function visit_parse_tree_recursive(root_table, current_table, result, depth, callback_func) - for key, value in pairs(current_table) do + local function visit_tree_recursive(tree, + current, + result, + depth, + callback_func) + for key, value in pairs(current) do if type(value) == 'table' then - value = visit_parse_tree_recursive(root_table, value, {}, depth + 1, callback_func) + value = visit_tree_recursive(tree, value, {}, depth + 1, callback_func) end - key, value = callback_func(key, value, depth, current_table, root_table) + key, value = callback_func(key, value, depth, current, tree) if key ~= nil and value ~= nil then result[key] = value @@ -366,255 +497,574 @@ local function visit_parse_tree(parse_tree, callback_func) end end - return visit_parse_tree_recursive(parse_tree, parse_tree, {}, 1, callback_func) + local result = visit_tree_recursive(tree, tree, {}, 1, callback_func) + + if result == nil then + return {} + end + return result end ---- Normalize the result tables of the LPeg parser. This normalization --- tasks are performed on the raw input table coming directly from the --- PEG parser: --- --- * Unpack all single valued array like tables: `{ 'text' }` into --- `text` --- --- @tparam table raw The raw input table coming directly from the PEG --- parser --- --- @tparam table options Some options. A table with the key --- `unpack_single_array_values` --- --- @treturn table A normalized table ready for the outside world. -local function normalize(raw, options) - local function normalize_recursive(raw, result, options) - for key, value in pairs(raw) do - if options.unpack_single_array_values then - value = unpack_single_valued_array_table(value, options) - end - if type(value) == 'table' then - result[key] = normalize_recursive(value, {}, options) - else - result[key] = value - end +local is = { + boolean = function(value) + if value == nil then + return false end - return result - end - raw = normalize_recursive(raw, {}, options) + if type(value) == 'boolean' then + return true + end + local parser = generate_parser('boolean_only', false) + local result = parser:match(value) + return result ~= nil + end, + + dimension = function(value) + if value == nil then + return false + end + local parser = generate_parser('dimension_only', false) + local result = parser:match(value) + return result ~= nil + end, + + integer = function(value) + local n = tonumber(value) + if n == nil then + return false + end + return n == math.floor(n) + end, - if options.standalone_as_true then - raw = visit_parse_tree(raw, function (key, value) - if type(key) == 'number' and type(value) == 'string' then - return value, true - end - return key, value - end) - end + number = function(value) + if value == nil then + return false + end + if type(value) == 'number' then + return true + end + local parser = generate_parser('number_only', false) + local result = parser:match(value) + return result ~= nil + end, + + string = function(value) + return type(value) == 'string' + end, +} - if options.case_insensitive_keys then - raw = visit_parse_tree(raw, function (key, value) - if type(key) == 'string' then - return key:lower(), value - end - return key, value - end) +--- Apply the key-value-pair definitions (defs) on an input table in a +--- recursive fashion. +--- +---@param defs table A table containing all definitions. +---@param opts table The parse options table. +---@param input table The current input table. +---@param output table The current output table. +---@param unknown table Always the root unknown table. +---@param key_path table An array of key names leading to the current +---@param input_root table The root input table +--- input and output table. +local function apply_definitions(defs, + opts, + input, + output, + unknown, + key_path, + input_root) + local exclusive_groups = {} + + local function add_to_key_path(key_path, key) + local new_key_path = {} + + for index, value in ipairs(key_path) do + new_key_path[index] = value + end + + table.insert(new_key_path, key) + return new_key_path end - return raw -end + local function set_default_value(def) + if def.default ~= nil then + return def.default + elseif opts ~= nil and opts.default ~= nil then + return opts.default + end + return true + end ---- Parse a LaTeX/TeX style key-value string into a Lua table. With --- this function you should be able to parse key-value strings like --- this example: --- --- show, --- hide, --- key with spaces = String without quotes, --- string="String with double quotes: ,{}=", --- dimension = 1cm, --- number = -1.2, --- list = {one,two,three}, --- key value list = {one=one,two=two,three=three}, --- nested key = { --- nested key 2= { --- key = value, --- }, --- }, --- --- The string above results in this Lua table: --- --- { --- 'show', --- 'hide', --- ['key with spaces'] = 'String without quotes', --- string = 'String with double quotes: ,{}=', --- dimension = 1864679, --- number = -1.2, --- list = {'one', 'two', 'three'}, --- key value list = { --- one = 'one', --- three = 'three', --- two = 'two' --- }, --- ['nested key'] = { --- ['nested key 2'] = { --- key = 'value' --- } --- }, --- } --- --- @tparam string kv_string A string in the TeX/LaTeX style key-value --- format as described above. --- --- @tparam table options A table containing --- settings: `convert_dimensions`, `unpack_single_array_values`, `standalone_as_true`, `converter` --- --- @treturn table A hopefully properly parsed table you can do --- something useful with. -local function parse (kv_string, options) - if kv_string == nil then - return {} + local function find_value(search_key, def) + if input[search_key] ~= nil then + local value = input[search_key] + input[search_key] = nil + return value + -- naked keys: values with integer keys + elseif utils.remove_from_array(input, search_key) ~= nil then + return set_default_value(def) + end end - options = normalize_parse_options(options) - local parser = generate_parser(options) - local parse_tree = parser:match(kv_string) + local apply = { + alias = function(value, key, def) + if type(def.alias) == 'string' then + def.alias = { def.alias } + end + local alias_value + local used_alias_key + -- To get an error if the key and an alias is present + if value ~= nil then + alias_value = value + used_alias_key = key + end + for _, alias in ipairs(def.alias) do + local v = find_value(alias, def) + if v ~= nil then + if alias_value ~= nil then + throw_error(string.format( + 'Duplicate aliases “%s” and “%s” for key “%s”!', + used_alias_key, alias, key)) + end + used_alias_key = alias + alias_value = v + end + end + if alias_value ~= nil then + return alias_value + end + end, - if options.converter ~= nil and type(options.converter) == 'function' then - parse_tree = visit_parse_tree(parse_tree, options.converter) - end - return normalize(parse_tree, options) -end + always_present = function(value, key, def) + if value == nil and def.always_present then + return set_default_value(def) + end + end, ---- Convert back to strings --- @section + choices = function(value, key, def) + if value == nil then + return + end + if def.choices ~= nil and type(def.choices) == 'table' then + local is_in_choices = false + for _, choice in ipairs(def.choices) do + if value == choice then + is_in_choices = true + end + end + if not is_in_choices then + throw_error('The value “' .. value .. + '” does not exist in the choices: ' .. + table.concat(def.choices, ', ') .. '!') + end + end + end, ---- The function `render(tbl)` reverses the function --- `parse(kv_string)`. It takes a Lua table and converts this table --- into a key-value string. The resulting string usually has a --- different order as the input table. In Lua only tables with --- 1-based consecutive integer keys (a.k.a. array tables) can be --- parsed in order. --- --- @tparam table tbl A table to be converted into a key-value string. --- --- @treturn string A key-value string that can be passed to a TeX --- macro. -local function render (tbl) - local function render_inner(tbl) - local output = {} - local function add(text) - table.insert(output, text) - end - for key, value in pairs(tbl) do - if (key and type(key) == 'string') then - if (type(value) == 'table') then - if (next(value)) then - add(key .. '={') - add(render_inner(value)) - add('},') + data_type = function(value, key, def) + if value == nil then + return + end + if def.data_type ~= nil then + local converted + -- boolean + if def.data_type == 'boolean' then + if value == 0 or value == '' or not value then + converted = false else - add(key .. '={},') + converted = true end + -- dimension + elseif def.data_type == 'dimension' then + if is.dimension(value) then + converted = value + end + -- integer + elseif def.data_type == 'integer' then + if is.number(value) then + converted = math.floor(tonumber(value)) + end + -- number + elseif def.data_type == 'number' then + if is.number(value) then + converted = tonumber(value) + end + -- string + elseif def.data_type == 'string' then + converted = tostring(value) else - add(key .. '=' .. tostring(value) .. ',') + throw_error('Unknown data type: ' .. def.data_type) end - else - add(tostring(value) .. ',') + if converted == nil then + throw_error('The value “' .. value .. '” of the key “' .. key .. + '” could not be converted into the data type “' .. + def.data_type .. '”!') + else + return converted + end + end + end, + + exclusive_group = function(value, key, def) + if value == nil then + return + end + if def.exclusive_group ~= nil then + if exclusive_groups[def.exclusive_group] ~= nil then + throw_error('The key “' .. key .. + '” belongs to a mutually exclusive group “' .. + def.exclusive_group .. '” and the key “' .. + exclusive_groups[def.exclusive_group] .. + '” is already present!') + else + exclusive_groups[def.exclusive_group] = key + end + end + end, + + l3_tl_set = function(value, key, def) + if value == nil then + return + end + if def.l3_tl_set ~= nil then + tex.print(l3_code_cctab, '\\tl_set:Nn \\g_' .. def.l3_tl_set .. '_tl') + tex.print('{' .. value .. '}') + end + end, + + macro = function(value, key, def) + if value == nil then + return + end + if def.macro ~= nil then + token.set_macro(def.macro, value, 'global') + end + end, + + match = function(value, key, def) + if value == nil then + return end + if def.match ~= nil then + if type(def.match) ~= 'string' then + throw_error('def.match has to be a string') + end + local match = string.match(value, def.match) + if match == nil then + throw_error('The value “' .. value .. '” of the key “' .. key .. + '” does not match “' .. def.match .. '”!') + else + return match + end + end + end, + + opposite_keys = function(value, key, def) + if def.opposite_keys ~= nil then + local true_value = def.opposite_keys[true] + local false_value = def.opposite_keys[false] + if true_value == nil or false_value == nil then + throw_error( + 'Usage opposite_keys = { [true] = "...", [false] = "..." }') + end + if utils.remove_from_array(input, true_value) ~= nil then + return true + elseif utils.remove_from_array(input, false_value) ~= nil then + return false + end + end + end, + + process = function(value, key, def) + if value == nil then + return + end + if def.process ~= nil and type(def.process) == 'function' then + return def.process(value, input_root, output, unknown) + end + end, + + required = function(value, key, def) + if def.required ~= nil and def.required and value == nil then + throw_error(string.format('Missing required key “%s”!', key)) + end + end, + + sub_keys = function(value, key, def) + if def.sub_keys ~= nil then + local v + -- To get keys defined with always_present + if value == nil then + v = {} + elseif type(value) == 'string' then + v = { value } + elseif type(value) == 'table' then + v = value + end + v = apply_definitions(def.sub_keys, opts, v, output[key], unknown, + add_to_key_path(key_path, key), input_root) + if utils.get_table_size(v) > 0 then + return v + end + end + end, + } + + --- standalone values are removed. + -- For some callbacks and the third return value of parse, we + -- need an unchanged raw result from the parse function. + input = clone_table(input) + if output == nil then + output = {} + end + if unknown == nil then + unknown = {} + end + if key_path == nil then + key_path = {} + end + + for index, def in pairs(defs) do + --- Find key and def + local key + if type(def) == 'table' and def.name == nil and type(index) == 'string' then + key = index + elseif type(def) == 'table' and def.name ~= nil then + key = def.name + elseif type(index) == 'number' and type(def) == 'string' then + key = def + def = { default = true } end - return table.concat(output) + + if type(def) ~= 'table' then + throw_error('Key definition must be a table') + end + + if key == nil then + throw_error('key name couldn’t be detected!') + end + + local value = find_value(key, def) + + for _, def_opt in ipairs({ + 'alias', + 'opposite_keys', + 'always_present', + 'required', + 'data_type', + 'choices', + 'match', + 'exclusive_group', + 'macro', + 'l3_tl_set', + 'process', + 'sub_keys', + }) do + if def[def_opt] ~= nil then + local tmp_value = apply[def_opt](value, key, def) + if tmp_value ~= nil then + value = tmp_value + end + end + end + + output[key] = value end - return render_inner(tbl) + + if utils.get_table_size(input) > 0 then + -- Move to the current unknown table. + local current_unknown = unknown + for _, key in ipairs(key_path) do + if current_unknown[key] == nil then + current_unknown[key] = {} + end + current_unknown = current_unknown[key] + end + + -- Copy all unknown key-value-pairs to the current unknown table. + for key, value in pairs(input) do + current_unknown[key] = value + end + end + + return output, unknown end ---- The function `stringify(tbl, for_tex)` converts a Lua table into a --- printable string. Stringify a table means to convert the table into --- a string. This function is used to realize the `print` function. --- `stringify(tbl, true)` (`for_tex = true`) generates a string which --- can be embeded into TeX documents. The macro `\luakeysdebug{}` uses --- this option. `stringify(tbl, false)` or `stringify(tbl)` generate a --- string suitable for the terminal. --- --- @tparam table input A table to stringify. --- --- @tparam boolean for_tex Stringify the table into a text string that --- can be embeded inside a TeX document via tex.print(). Curly braces --- and whites spaces are escaped. +--- Parse a LaTeX/TeX style key-value string into a Lua table. +--- +---@param kv_string string A string in the TeX/LaTeX style key-value format as described above. +---@param opts table A table containing the settings: +--- `convert_dimensions`, `unpack`, `naked_as_value`, `converter`, +--- `debug`, `preprocess`, `postprocess`. -- --- https://stackoverflow.com/a/54593224/10193818 -local function stringify(input, for_tex) - local line_break, start_bracket, end_bracket, indent - - if for_tex then - line_break = '\\par' - start_bracket = '$\\{$' - end_bracket = '$\\}$' - indent = '\\ \\ ' - else - line_break = '\n' - start_bracket = '{' - end_bracket = '}' - indent = ' ' +---@return table result The final result of all individual parsing and normalization steps. +---@return table unknown A table with unknown, undefinied key-value pairs. +---@return table raw The unprocessed, raw result of the LPeg parser. +local function parse(kv_string, opts) + if kv_string == nil then + return {} end - local function stringify_inner(input, depth) - local output = {} - depth = depth or 0 + --- Normalize the parse options. + --- + --- @param opts table Options in a raw format. The table may be empty or some keys are not set. + --- + --- @return table + local function normalize_opts(opts) + if type(opts) ~= 'table' then + opts = {} + end + for key, _ in pairs(opts) do + if all_options[key] == nil then + throw_error('Unknown parse option: ' .. tostring(key) .. '!') + end + end + local old_opts = opts + opts = {} + for name, _ in pairs(all_options) do + if old_opts[name] ~= nil then + opts[name] = old_opts[name] + else + opts[name] = default_options[name] + end + end - local function add(depth, text) - table.insert(output, string.rep(indent, depth) .. text) + local hooks = { + kv_string = true, + keys_before_opts = true, + result_before_opts = true, + keys_before_def = true, + result_before_def = true, + keys = true, + result = true, + } + + for hook in pairs(opts.hooks) do + if hooks[hook] == nil then + throw_error('Unknown hook: ' .. tostring(hook) .. '!') + end end + return opts + end + opts = normalize_opts(opts) - local function format_key(key) - if (type(key) == 'number') then - return string.format('[%s]', key) + if type(opts.hooks.kv_string) == 'function' then + kv_string = opts.hooks.kv_string(kv_string) + end + + local result = generate_parser('list', opts.convert_dimensions):match( + kv_string) + local raw = clone_table(result) + + local function apply_hook(name) + if type(opts.hooks[name]) == 'function' then + if name:match('^keys') then + result = visit_tree(result, opts.hooks[name]) else - return string.format('[\'%s\']', key) + opts.hooks[name](result) + end + + if opts.debug then + print('After the execution of the hook: ' .. name) + debug(result) end end + end - if type(input) ~= 'table' then - return tostring(input) + local function apply_hooks(at) + if at ~= nil then + at = '_' .. at + else + at = '' end + apply_hook('keys' .. at) + apply_hook('result' .. at) + end - for key, value in pairs(input) do - if (key and type(key) == 'number' or type(key) == 'string') then - key = format_key(key) + apply_hooks('before_opts') - if (type(value) == 'table') then - if (next(value)) then - add(depth, key .. ' = ' .. start_bracket) - add(0, stringify_inner(value, depth + 1)) - add(depth, end_bracket .. ','); - else - add(depth, key .. ' = ' .. start_bracket .. end_bracket .. ',') - end - else - if (type(value) == 'string') then - value = string.format('\'%s\'', value) - else - value = tostring(value) - end + --- Normalize the result table of the LPeg parser. This normalization + -- tasks are performed on the raw input table coming directly from + -- the PEG parser: + -- + --- @param result table The raw input table coming directly from the PEG parser + --- @param opts table Some options. + local function apply_opts(result, opts) + local callbacks = { + unpack = function(key, value) + if type(value) == 'table' and utils.get_array_size(value) == 1 and + utils.get_table_size(value) == 1 and type(value[1]) ~= 'table' then + return key, value[1] + end + return key, value + end, - add(depth, key .. ' = ' .. value .. ',') + process_naked = function(key, value) + if type(key) == 'number' and type(value) == 'string' then + return value, opts.default + end + return key, value + end, + + format_key = function(key, value) + if type(key) == 'string' then + for _, style in ipairs(opts.format_keys) do + if style == 'lower' then + key = key:lower() + elseif style == 'snake' then + key = key:gsub('[^%w]+', '_') + elseif style == 'upper' then + key = key:upper() + else + throw_error('Unknown style to format keys: ' .. tostring(style) .. + ' Allowed styles are: lower, snake, upper') + end + end end + return key, value + end, + } + + if opts.unpack then + result = visit_tree(result, callbacks.unpack) + end + + if not opts.naked_as_value and opts.defs == false then + result = visit_tree(result, callbacks.process_naked) + end + + if opts.format_keys then + if type(opts.format_keys) ~= 'table' then + throw_error('The option “format_keys” has to be a table not ' .. + type(opts.format_keys)) end + result = visit_tree(result, callbacks.format_key) end - return table.concat(output, line_break) + return result + end + result = apply_opts(result, opts) + + -- All unknown keys are stored in this table + local unknown = nil + if type(opts.defs) == 'table' then + apply_hooks('before_defs') + result, unknown = apply_definitions(opts.defs, opts, result, {}, {}, {}, + clone_table(result)) end - return start_bracket .. line_break .. stringify_inner(input, 1) .. line_break .. end_bracket -end + apply_hooks() ---- The function `pretty_print(tbl)` pretty prints a Lua table to standard --- output (stdout). It is a utility function that can be used to --- debug and inspect the resulting Lua table of the function --- `parse`. You have to compile your TeX document in a console to --- see the terminal output. --- --- @tparam table tbl A table to be printed to standard output for --- debugging purposes. -local function pretty_print(tbl) - print(stringify(tbl, false)) + if opts.defaults ~= nil and type(opts.defaults) == 'table' then + merge_tables(result, opts.defaults) + end + + if opts.debug then + debug(result) + end + + -- no_error + if not opts.no_error and type(unknown) == 'table' and + utils.get_table_size(unknown) > 0 then + throw_error('Unknown keys: ' .. render(unknown)) + end + return result, unknown, raw end --- Store results @@ -623,38 +1073,12 @@ end --- A table to store parsed key-value results. local result_store = {} ---- The function `save(identifier, result): void` saves a result (a --- table from a previous run of `parse`) under an identifier. --- Therefore, it is not necessary to pollute the global namespace to --- store results for the later usage. --- --- @tparam string identifier The identifier under which the result is --- saved. --- --- @tparam table result A result to be stored and that was created by --- the key-value parser. -local function save(identifier, result) - result_store[identifier] = result -end - ---- The function `get(identifier): table` retrieves a saved result --- from the result store. --- --- @tparam string identifier The identifier under which the result was --- saved. -local function get(identifier) - -- if result_store[identifier] == nil then - -- throw_error('No stored result was found for the identifier \'' .. identifier .. '\'') - -- end - return result_store[identifier] -end - --- Exports -- @section local export = { --- @see default_options - default_options = default_options, + opts = default_options, --- @see stringify stringify = stringify, @@ -662,27 +1086,58 @@ local export = { --- @see parse parse = parse, + define = function(defs, opts) + return function(kv_string, inner_opts) + local options + if inner_opts ~= nil then + options = inner_opts + elseif opts ~= nil then + options = opts + end + + if options == nil then + options = {} + end + + options.defs = defs + + return parse(kv_string, options) + end + end, + --- @see render render = render, - --- @see pretty_print - print = pretty_print, + --- @see debug + debug = debug, - --- @see save - save = save, - - --- @see get - get = get, + --- The function `save(identifier, result): void` saves a result (a + -- table from a previous run of `parse`) under an identifier. + -- Therefore, it is not necessary to pollute the global namespace to + -- store results for the later usage. + -- + -- @tparam string identifier The identifier under which the result is + -- saved. + -- + -- @tparam table result A result to be stored and that was created by + -- the key-value parser. + save = function(identifier, result) + result_store[identifier] = result + end, + + --- The function `get(identifier): table` retrieves a saved result + -- from the result store. + -- + -- @tparam string identifier The identifier under which the result was + -- saved. + get = function(identifier) + -- if result_store[identifier] == nil then + -- throw_error('No stored result was found for the identifier \'' .. identifier .. '\'') + -- end + return result_store[identifier] + end, + + is = is, } --- http://olivinelabs.com/busted/#private -if _TEST then - export.luafy_key = luafy_key - export.luafy_options = luafy_options - export.normalize = normalize - export.normalize_parse_options = normalize_parse_options - export.unpack_single_valued_array_table = unpack_single_valued_array_table - export.visit_parse_tree = visit_parse_tree -end - return export diff --git a/macros/luatex/generic/luakeys/luakeys.sty b/macros/luatex/generic/luakeys/luakeys.sty index 2cf22b837a..51e2c9bec5 100644 --- a/macros/luatex/generic/luakeys/luakeys.sty +++ b/macros/luatex/generic/luakeys/luakeys.sty @@ -17,5 +17,5 @@ % luakeys-debug.sty and luakeys-debug.tex. \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{luakeys}[2022/04/04 v0.5 Parsing key-value options using Lua.] +\ProvidesPackage{luakeys}[2022/06/09 v0.6 Parsing key-value options using Lua.] \directlua{luakeys = require('luakeys')} diff --git a/macros/xetex/latex/bidi/README b/macros/xetex/latex/bidi/README index e19092605c..f6a8c6a282 100644 --- a/macros/xetex/latex/bidi/README +++ b/macros/xetex/latex/bidi/README @@ -1,6 +1,6 @@ ___________________ The bidi package -v37.6 +v37.7 This package provides a convenient interface for typesetting bidirectional texts in Plain TeX and LaTeX, using XeTeX engine. @@ -25,7 +25,7 @@ The announcements for the new releases of the package will also appear in the Discussions space under the Announcements category. -Current version release date: 2022/06/07 +Current version release date: 2022/06/09 ___________________________________________ Vafa Khalighi diff --git a/macros/xetex/latex/bidi/bidi-doc-intro.ltx b/macros/xetex/latex/bidi/bidi-doc-intro.ltx index 6d943f3a34..5af68bc4ae 100644 --- a/macros/xetex/latex/bidi/bidi-doc-intro.ltx +++ b/macros/xetex/latex/bidi/bidi-doc-intro.ltx @@ -20,7 +20,7 @@ If you use \textsf{bidi} package to write any input \TeX\ document, and then run * Copyright (c) 2007--2022 Vafa Khalighi * Copyright (c) 2018--2020 bidi-tex GitHub Organization * -* v37.6, 2022/06/07 +* v37.7, 2022/06/09 * * License: LaTeX Project Public License, version * 1.3c or higher (your choice) diff --git a/macros/xetex/latex/bidi/bidi-doc-title.ltx b/macros/xetex/latex/bidi/bidi-doc-title.ltx index d94f8a8f1f..9e14c7eacf 100644 --- a/macros/xetex/latex/bidi/bidi-doc-title.ltx +++ b/macros/xetex/latex/bidi/bidi-doc-title.ltx @@ -3,7 +3,7 @@ \begin{document} \title{\textcolor{blue!65!black}{\Huge The \textsf{bidi} \textit{Package}}\\ \LARGE Bidirectional typesetting in plain \TeX{} and \LaTeX, using \XeTeX{} engine\\[5pt] -\large User documentation for \textcolor{blue!65!black}{version 37.6}} +\large User documentation for \textcolor{blue!65!black}{version 37.7}} \author{Vafa Khalighi\thanks{Thanks to the bidi-tex GitHub organization consisted of David Carlisle and other members of the {\LaTeX} team to maintain the package in the period 2018--2020.}} \setcounter{page}{0} \thispagestyle{empty} @@ -13,7 +13,7 @@ \textcolor{blue!65!black}{\Huge The \textsf{bidi} \textit{Package}} \Large -User documentation for \textcolor{blue!65!black}{version 37.6}} +User documentation for \textcolor{blue!65!black}{version 37.7}} \vskip 0pt plus 3fill \textit{\large to my Master, \textbf{Ferdowsi The Great}} diff --git a/macros/xetex/latex/bidi/bidi-doc.ltx b/macros/xetex/latex/bidi/bidi-doc.ltx index e4ff1d7287..aab456d7e9 100644 --- a/macros/xetex/latex/bidi/bidi-doc.ltx +++ b/macros/xetex/latex/bidi/bidi-doc.ltx @@ -1,7 +1,7 @@ \documentclass{ltxdoc} \input{bidi-doc-preamble.ltx} \hypersetup{% - pdftitle={User documentation for version 37.6 of the bidi + pdftitle={User documentation for version 37.7 of the bidi package}% } \begin{document} diff --git a/macros/xetex/latex/bidi/bidi-doc.pdf b/macros/xetex/latex/bidi/bidi-doc.pdf Binary files differindex 59b1f457bd..50dc24496b 100644 --- a/macros/xetex/latex/bidi/bidi-doc.pdf +++ b/macros/xetex/latex/bidi/bidi-doc.pdf diff --git a/macros/xetex/latex/bidi/bidi.dtx b/macros/xetex/latex/bidi/bidi.dtx index a0f01925bb..c4ea141163 100644 --- a/macros/xetex/latex/bidi/bidi.dtx +++ b/macros/xetex/latex/bidi/bidi.dtx @@ -5,7 +5,7 @@ %<*readme> ___________________ The bidi package -v37.6 +v37.7 This package provides a convenient interface for typesetting bidirectional texts in Plain TeX and LaTeX, using XeTeX engine. @@ -30,7 +30,7 @@ The announcements for the new releases of the package will also appear in the Discussions space under the Announcements category. -Current version release date: 2022/06/07 +Current version release date: 2022/06/09 ___________________________________________ Vafa Khalighi @@ -89,17 +89,23 @@ by Vafa Khalighi. \generate{\file{beamerbasecolor-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerbasecolor-xetex-bidi.def}}} \generate{\file{beamerbaseframecomponents-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerbaseframecomponents-xetex-bidi.def}}} \generate{\file{beamerbaselocalstructure-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerbaselocalstructure-xetex-bidi.def}}} +\generate{\file{beamerbasenavigation-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerbasenavigation-xetex-bidi.def}}} \generate{\file{beamerinnerthemedefault-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerinnerthemedefault-xetex-bidi.def}}} \generate{\file{beamerinnerthemecircles-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerinnerthemecircles-xetex-bidi.def}}} +\generate{\file{beamerinnerthemeinmargin-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerinnerthemeinmargin-xetex-bidi.def}}} \generate{\file{beamerinnerthemerectangles-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerinnerthemerectangles-xetex-bidi.def}}} \generate{\file{beamerinnerthemerounded-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerinnerthemerounded-xetex-bidi.def}}} \generate{\file{beamerouterthemedefault-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerouterthemedefault-xetex-bidi.def}}} \generate{\file{beamerouterthemeinfolines-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerouterthemeinfolines-xetex-bidi.def}}} -\generate{\file{beamerouterthemeshadow-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerouterthemeshadow-xetex-bidi.def}}} +\generate{\file{beamerouterthememiniframes-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerouterthememiniframes-xetex-bidi.def}}} \generate{\file{beamerouterthemesidebar-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerouterthemesidebar-xetex-bidi.def}}} \generate{\file{beamerouterthemesplit-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerouterthemesplit-xetex-bidi.def}}} \generate{\file{beamerouterthemeshadow-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerouterthemeshadow-xetex-bidi.def}}} +\generate{\file{beamerouterthemesmoothbars-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerouterthemesmoothbars-xetex-bidi.def}}} +\generate{\file{beamerouterthemesmoothtree-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerouterthemesmoothtree-xetex-bidi.def}}} +\generate{\file{beamerouterthemetree-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerouterthemetree-xetex-bidi.def}}} \generate{\file{beamerthemeHannover-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerthemeHannover-xetex-bidi.def}}} +\generate{\file{beamerthemeSingapore-xetex-bidi.def}{\from{\jobname.dtx}{table,beamerthemeSingapore-xetex-bidi.def}}} \generate{\file{bidi.sty}{\from{\jobname.dtx}{table,bidi.sty}}} \generate{\file{bidi.tex}{\from{\jobname.dtx}{table,bidi.tex}}} \generate{\file{bidi2in1.sty}{\from{\jobname.dtx}{table,bidi2in1.sty}}} @@ -252,7 +258,7 @@ by Vafa Khalighi. \documentclass{ltxdoc} \input{bidi-doc-preamble.ltx} \hypersetup{% - pdftitle={Source documentation for version 37.6 of the bidi + pdftitle={Source documentation for version 37.7 of the bidi package}% } \EnableCrossrefs @@ -271,7 +277,7 @@ by Vafa Khalighi. % \GetFileInfo{\jobname.dtx} % \title{\textcolor{blue!65!black}{\Huge The \textsf{bidi} \textit{Package}}\\ %\LARGE Bidirectional typesetting in plain \TeX{} and \LaTeX, using \XeTeX{} engine\\[5pt] -%\large Source documentation for \textcolor{blue!65!black}{version 37.6}} +%\large Source documentation for \textcolor{blue!65!black}{version 37.7}} % \author{Vafa Khalighi\thanks{Thanks to the bidi-tex GitHub organization consisted of David Carlisle and other members of the {\LaTeX} team to maintain the package in the period 2018--2020.}} %\setcounter{page}{0} %\thispagestyle{empty} @@ -281,7 +287,7 @@ by Vafa Khalighi. %\textcolor{blue!65!black}{\Huge The \textsf{bidi} \textit{Package}} % %\Large -%Source documentation for \textcolor{blue!65!black}{version 37.6}} +%Source documentation for \textcolor{blue!65!black}{version 37.7}} % %\vskip 0pt plus 3fill %\textit{\large to my Master, \textbf{Ferdowsi The Great}} @@ -330,7 +336,7 @@ by Vafa Khalighi. %\iffalse %<*table> %\fi -%% \CheckSum{53191} +%% \CheckSum{53787} %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z @@ -2404,7 +2410,7 @@ by Vafa Khalighi. %\fi % \section{File \texttt{beamerbaseframecomponents-xetex-bidi.def}} % \begin{macrocode} -\ProvidesFile{beamerbaseframecomponents-xetex-bidi.def}[2022/06/06 v0.2 bidi adaptations for beamerbaseframecomponents package for XeTeX engine] +\ProvidesFile{beamerbaseframecomponents-xetex-bidi.def}[2022/06/09 v0.3 bidi adaptations for beamerbaseframecomponents package for XeTeX engine] \renewcommand{\setbeamersize}[1]{% \beamer@dogeometryfalse% \setkeys{beamer@margin}{#1}% @@ -2465,7 +2471,9 @@ by Vafa Khalighi. \usebeamertemplate***{sidebar left}% \vfil% }}% - \hskip-\textwidth + \@ifpackageloaded{beamerinnerthemeinmargin}{}{% + \hskip-\textwidth + }% \fi {\setbox\beamer@tempbox=\hbox{\vbox to \sidebarheight{% \usebeamercolor*{sidebar left}% @@ -2875,6 +2883,66 @@ by Vafa Khalighi. % \end{macrocode} % \iffalse %</beamerbaselocalstructure-xetex-bidi.def> +%<*beamerbasenavigation-xetex-bidi.def> +%\fi +% \section{File \texttt{beamerbasenavigation-xetex-bidi.def}} +% \begin{macrocode} +\ProvidesFile{beamerbasenavigation-xetex-bidi.def}[2022/06/09 v0.1 bidi adaptations for beamerbasenavigation package for XeTeX engine] +\def\slideentry#1#2#3#4#5#6{% + %section number, subsection number, slide number, first/last frame, page number, part number + \ifnum#6=\c@part\ifnum#1>0\ifnum#3>0% + \ifbeamer@compress% + \advance\beamer@xpos by1\relax% + \else% + \ifnum#2=0% + \beamer@ypos@offset=1\relax% + \fi + \beamer@xpos=#3\relax% + \beamer@ypos=#2\relax% + \advance\beamer@ypos by \beamer@ypos@offset\relax + \fi% + \hbox to 0pt{% + \beamer@tempdim=-\beamer@vboxoffset% + \advance\beamer@tempdim by-\beamer@boxsize% + \multiply\beamer@tempdim by\beamer@ypos% + \advance\beamer@tempdim by -.05cm% + \raise\beamer@tempdim\hbox{% + \beamer@tempdim=\beamer@boxsize% + \multiply\beamer@tempdim by\beamer@xpos% + \advance\beamer@tempdim by -\beamer@boxsize% + \advance\beamer@tempdim by 1pt% + \kern\beamer@tempdim + \global\beamer@section@min@dim\beamer@tempdim + \hbox{\beamer@link(#4){{% + \usebeamerfont{mini frame}% + \ifnum\c@section=#1% + \ifnum\c@subsection=#2% + \usebeamercolor[fg]{mini frame}% + \ifnum\c@subsectionslide=#3% + \usebeamertemplate{mini frame}%\beamer@minislidehilight% + \else% + \usebeamertemplate{mini frame in current subsection}%\beamer@minisliderowhilight% + \fi% + \else% + \usebeamercolor{mini frame}% + %\color{fg!50!bg}% + \usebeamertemplate{mini frame in other subsection}%\beamer@minislide% + \fi% + \else% + \usebeamercolor{mini frame}% + %\color{fg!50!bg}% + \usebeamertemplate{mini frame in other subsection}%\beamer@minislide% + \fi% + }}}}\hskip-10cm plus 1fil% + }\fi\fi% + \else% + \fakeslideentry{#1}{#2}{#3}{#4}{#5}{#6}% + \fi\ignorespaces + } + +% \end{macrocode} +% \iffalse +%</beamerbasenavigation-xetex-bidi.def> %<*beamerinnerthemedefault-xetex-bidi.def> %\fi % \section{File \texttt{beamerinnerthemedefault-xetex-bidi.def}} @@ -3028,6 +3096,108 @@ by Vafa Khalighi. % \end{macrocode} % \iffalse %</beamerinnerthemecircles-xetex-bidi.def> +%<*beamerinnerthemeinmargin-xetex-bidi.def> +%\fi +% \section{File \texttt{beamerinnerthemeinmargin-xetex-bidi.def}} +% \begin{macrocode} +\ProvidesFile{beamerinnerthemeinmargin-xetex-bidi.def}[2022/06/09 v0.1 bidi adaptations for beamerinnerthemeinmargin package for XeTeX engine] +\AtBeginDocument{% + \setbeamersize{sidebar width left=.25\paperwidth}% +} + +\bidi@csundef{beamer@@tmpop@section in toc@inmargin} + +\bidi@csundef{beamer@@tmpop@title page@inmargin} + +\bidi@csundef{beamer@@tmpop@block begin@inmargin} + +\bidi@csundef{beamer@@tmpop@block end@inmargin} + +\bidi@csundef{beamer@@tmpop@block alerted begin@inmargin} + +\bidi@csundef{beamer@@tmpop@block alerted end@inmargin} + +\bidi@csundef{beamer@@tmpop@block example begin@inmargin} + +\bidi@csundef{beamer@@tmpop@block example end@inmargin} + +\defbeamertemplate*{section in toc}{inmargin} +{\leavevmode + \beamer@putleft{{\usebeamercolor[fg]{section in toc}\inserttocsection}\strut}{2.5ex}} + +\defbeamertemplate*{title page}{inmargin} +{ + \begin{block}{\inserttitleindicator} + \bgroup\usebeamercolor[fg]{title}\usebeamerfont{title}\inserttitle\egroup\par + \usebeamercolor[fg]{subtitle}\usebeamerfont{subtitle}\insertsubtitle + \end{block} + \vfill + \ifx\insertauthor\@empty + \else + \begin{block}{\insertauthorindicator} + \bgroup\usebeamercolor[fg]{author}\usebeamerfont{author}\insertauthor\egroup\par + \end{block} + \fi + \ifx\insertinstitute\@empty + \else + \begin{block}{\insertinstituteindicator} + \bgroup\usebeamercolor[fg]{institute}\usebeamerfont{institute}\insertinstitute\egroup\par + \end{block} + \fi + \ifx\insertdate\@empty + \else + \begin{block}{\insertdateindicator} + \bgroup\usebeamercolor[fg]{date}\usebeamerfont{date}\insertdate\egroup\par + \end{block} + \fi +} + +\defbeamertemplate*{block begin}{inmargin} +{ + \par\vskip\medskipamount% + \leavevmode% + \beamer@putleft{\normalfont{\usebeamercolor[fg]{block title}\usebeamerfont*{block title}\insertblocktitle}}{2.5ex}% + \beginL\beamer@putright + %\usebeamercolor[fg]{block body}% to be done! +} + +\defbeamertemplate*{block end}{inmargin} +{\endbeamer@putright\endL\vskip\smallskipamount} + +\defbeamertemplate*{block alerted begin}{inmargin} +{ + \par\vskip\medskipamount% + \leavevmode% + \beamer@putleft{\normalfont{\usebeamercolor[fg]{block title alerted}\usebeamerfont*{block title alerted}\insertblocktitle}}{2.5ex}% + \beginL\beamer@putright + %\usebeamercolor[fg]{block body alerted}% to be done! +} + +\defbeamertemplate*{block alerted end}{inmargin} +{\endbeamer@putright\endL\vskip\smallskipamount} + +\defbeamertemplate*{block example begin}{inmargin} +{ + \par\vskip\medskipamount% + \leavevmode% + \beamer@putleft{\normalfont{\usebeamercolor[fg]{block title example}\usebeamerfont*{block title example}\insertblocktitle}}{2.5ex}% + \beginL\beamer@putright + %\usebeamercolor[fg]{block body example}% to be done +} + +\defbeamertemplate*{block example end}{inmargin} +{\endbeamer@putright\endL\vskip\smallskipamount} + +\bidi@AfterFile{beamerinnerthemerectangles-xetex-bidi.def}{% + \setbeamertemplate{section in toc}[inmargin]% + \setbeamertemplate{subsection in toc}[inmargin]% + \setbeamertemplate{subsubsection in toc}[inmargin]% +} + + +% \end{macrocode} +% \iffalse +%</beamerinnerthemeinmargin-xetex-bidi.def> %<*beamerinnerthemerectangles-xetex-bidi.def> %\fi % \section{File \texttt{beamerinnerthemerectangles-xetex-bidi.def}} @@ -3074,7 +3244,7 @@ by Vafa Khalighi. %\fi % \section{File \texttt{beamerouterthemeinfolines-xetex-bidi.def}} % \begin{macrocode} -\ProvidesFile{beamerouterthemeinfolines-xetex-bidi.def}[2022/06/01 v0.1 bidi adaptations for beamerouterthemeinfolines package for XeTeX engine] +\ProvidesFile{beamerouterthemeinfolines-xetex-bidi.def}[2022/06/09 v0.2 bidi adaptations for beamerouterthemeinfolines package for XeTeX engine] \bidi@csundef{beamer@@tmpop@footline@infolines theme} \defbeamertemplate*{footline}{infolines theme} @@ -3101,23 +3271,71 @@ by Vafa Khalighi. \vskip0pt% } +\bidi@csundef{beamer@@tmpop@headline@infolines theme} + +\defbeamertemplate*{headline}{infolines theme} +{% + \leavevmode% + \hbox{% + \if@RTL + \begin{beamercolorbox}[wd=.5\paperwidth,ht=2.65ex,dp=1.5ex,left]{section in head/foot}% +\else + \begin{beamercolorbox}[wd=.5\paperwidth,ht=2.65ex,dp=1.5ex,right]{section in head/foot}% +\fi + \usebeamerfont{section in head/foot}\insertsectionhead\hspace*{2ex} + \end{beamercolorbox}% +\if@RTL + \begin{beamercolorbox}[wd=.5\paperwidth,ht=2.65ex,dp=1.5ex,right]{subsection in head/foot}% +\else + \begin{beamercolorbox}[wd=.5\paperwidth,ht=2.65ex,dp=1.5ex,left]{subsection in head/foot}% +\fi + \usebeamerfont{subsection in head/foot}\hspace*{2ex}\insertsubsectionhead + \end{beamercolorbox}}% + \vskip0pt% +} + +\bidi@AfterFile{beamerouterthemesplit-xetex-bidi.def}{% + \setbeamertemplate{footline}[infolines theme]% +} % \end{macrocode} % \iffalse %</beamerouterthemeinfolines-xetex-bidi.def> -%<*beamerouterthemeshadow-xetex-bidi.def> +%<*beamerouterthememiniframes-xetex-bidi.def> %\fi -% \section{File \texttt{beamerouterthemeshadow-xetex-bidi.def}} +% \section{File \texttt{beamerouterthememiniframes-xetex-bidi.def}} % \begin{macrocode} -\ProvidesFile{beamerouterthemeshadow-xetex-bidi.def}[2022/06/07 v0.1 bidi adaptations for beamerouterthemeshadow package for XeTeX engine] -\AtBeginDocument{% - \setbeamertemplate{frametitle}[shadow theme]% +\ProvidesFile{beamerouterthememiniframes-xetex-bidi.def}[2022/06/09 v0.1 bidi adaptations for beamerouterthememiniframes package for XeTeX engine] +\bidi@csundef{beamer@@tmpop@headline@miniframes theme} + +\defbeamertemplate*{headline}{miniframes theme} +{% + \begin{beamercolorbox}[colsep=1.5pt]{upper separation line head} + \end{beamercolorbox} + \begin{beamercolorbox}{section in head/foot} + \vskip2pt\if@RTL\beginR\fi\insertnavigation{\paperwidth}\if@RTL\endR\fi\vskip2pt + \end{beamercolorbox}% + \ifbeamer@theme@subsection% + \begin{beamercolorbox}[colsep=1.5pt]{middle separation line head} + \end{beamercolorbox} + \if@RTL + \begin{beamercolorbox}[ht=2.5ex,dp=1.125ex,% + rightskip=.3cm,leftskip=.3cm plus1fil]{subsection in head/foot} + \else + \begin{beamercolorbox}[ht=2.5ex,dp=1.125ex,% + leftskip=.3cm,rightskip=.3cm plus1fil]{subsection in head/foot} + \fi + \usebeamerfont{subsection in head/foot}\insertsubsectionhead + \end{beamercolorbox}% + \fi% + \begin{beamercolorbox}[colsep=1.5pt]{lower separation line head} + \end{beamercolorbox} } % \end{macrocode} % \iffalse -%</beamerouterthemeshadow-xetex-bidi.def> +%</beamerouterthememiniframes-xetex-bidi.def> %<*beamerouterthemesidebar-xetex-bidi.def> %\fi % \section{File \texttt{beamerouterthemesidebar-xetex-bidi.def}} @@ -3249,16 +3467,23 @@ by Vafa Khalighi. %\fi % \section{File \texttt{beamerouterthemesplit-xetex-bidi.def}} % \begin{macrocode} -\ProvidesFile{beamerouterthemesplit-xetex-bidi.def}[2022/06/01 v0.1 bidi adaptations for beamerouterthemesplit package for XeTeX engine] +\ProvidesFile{beamerouterthemesplit-xetex-bidi.def}[2022/06/09 v0.2 bidi adaptations for beamerouterthemesplit package for XeTeX engine] \bidi@csundef{beamer@@tmpop@footline@split theme} \defbeamertemplate*{footline}{split theme} {% \leavevmode% - \hbox{\begin{beamercolorbox}[wd=.5\paperwidth,ht=2.5ex,dp=1.125ex,leftskip=.3cm plus1fill,rightskip=.3cm]{author in head/foot}% + \hbox{\if@RTL\begin{beamercolorbox}[wd=.5\paperwidth,ht=2.5ex,dp=1.125ex,rightskip=.3cm plus1fill,leftskip=.3cm]{author in head/foot}% +\else +\begin{beamercolorbox}[wd=.5\paperwidth,ht=2.5ex,dp=1.125ex,leftskip=.3cm plus1fill,rightskip=.3cm]{author in head/foot}% +\fi \usebeamerfont{author in head/foot}\insertshortauthor \end{beamercolorbox}% + \if@RTL + \begin{beamercolorbox}[wd=.5\paperwidth,ht=2.5ex,dp=1.125ex,rightskip=.3cm,leftskip=.3cm plus1fil]{title in head/foot}% +\else \begin{beamercolorbox}[wd=.5\paperwidth,ht=2.5ex,dp=1.125ex,leftskip=.3cm,rightskip=.3cm plus1fil]{title in head/foot}% +\fi \usebeamerfont{title in head/foot}\insertshorttitle\nobreak\hfill\bgroup\usebeamercolor[fg]{page number in head/foot}\usebeamerfont{page number in head/foot}\usebeamertemplate{page number in head/foot}\egroup \end{beamercolorbox}}% \vskip0pt% @@ -3272,7 +3497,7 @@ by Vafa Khalighi. %\fi % \section{File \texttt{beamerouterthemeshadow-xetex-bidi.def}} % \begin{macrocode} -\ProvidesFile{beamerouterthemeshadow-xetex-bidi.def}[2022/06/01 v0.1 bidi adaptations for beamerouterthemeshadow package for XeTeX engine] +\ProvidesFile{beamerouterthemeshadow-xetex-bidi.def}[2022/06/07 v0.2 bidi adaptations for beamerouterthemeshadow package for XeTeX engine] \bidi@csundef{beamer@@tmpop@frametitle@shadow theme} \defbeamertemplate*{frametitle}{shadow theme} @@ -3321,10 +3546,277 @@ by Vafa Khalighi. \vskip-2pt } +\AtBeginDocument{% + \setbeamertemplate{frametitle}[shadow theme]% +} + % \end{macrocode} % \iffalse %</beamerouterthemeshadow-xetex-bidi.def> +%<*beamerouterthemesmoothbars-xetex-bidi.def> +%\fi +% \section{File \texttt{beamerouterthemesmoothbars-xetex-bidi.def}} +% \begin{macrocode} +\ProvidesFile{beamerouterthemesmoothbars-xetex-bidi.def}[2022/06/09 v0.1 bidi adaptations for beamerouterthemesmoothbars package for XeTeX engine] +\bidi@csundef{beamer@@tmpop@headline@smoothbars theme} + +\bidi@csundef{beamer@@tmpop@frametitle@smoothbars theme} + +\defbeamertemplate*{headline}{smoothbars theme} +{% + \pgfuseshading{beamer@barshade}% + \vskip-0.05ex% + \begin{beamercolorbox}[wd=\paperwidth,ht=1ex,dp=0ex]{empty} + \begin{pgfpicture} + \begin{pgfscope}% + \ifbeamer@sb@subsection% + \pgfsetfillcolor{subsection in head/foot.bg}% + \else% + \pgfsetfillcolor{section in head/foot.bg}% + \fi% + \pgfpathrectangle{\pgfpoint{-.5\paperwidth}{-0.5ex}}{\pgfpoint{\paperwidth}{1ex}}% + \pgfsetfading{beamer@belowframetitlemask}{}% + \pgfusepath{fill}% + \end{pgfscope}% + \end{pgfpicture}% + \end{beamercolorbox}% + \ifbeamer@sb@subsection% + \vskip-9.75ex% + \else% + \vskip-6.85ex% + \fi% + \begin{beamercolorbox}[ignorebg,ht=2.25ex,dp=3.75ex]{section in head/foot} + \insertnavigation{\paperwidth} + \end{beamercolorbox}% + \ifbeamer@sb@subsection% + \if@RTL + \begin{beamercolorbox}[ignorebg,ht=2.125ex,dp=1.125ex,% + rightskip=.3cm,leftskip=.3cm plus1fil]{subsection in head/foot} + \else + \begin{beamercolorbox}[ignorebg,ht=2.125ex,dp=1.125ex,% + leftskip=.3cm,rightskip=.3cm plus1fil]{subsection in head/foot} + \fi + \usebeamerfont{subsection in head/foot}\insertsubsectionhead + \end{beamercolorbox}% + \fi% +}% + +\defbeamertemplate*{frametitle}{smoothbars theme} +{% + \nointerlineskip% + \vskip-0.19ex% + \usebeamerfont{headline}% + \begin{beamercolorbox}[wd=\paperwidth,ht=1ex,dp=1ex,vmode]{empty} + \pgfuseshading{beamer@aboveframetitle}% + \end{beamercolorbox}% + \vskip-1ex% + \nointerlineskip% + \if@RTL + \begin{beamercolorbox}[wd=\paperwidth,rightskip=.3cm,leftskip=.3cm plus1fil,vmode]{frametitle} + \else + \begin{beamercolorbox}[wd=\paperwidth,leftskip=.3cm,rightskip=.3cm plus1fil,vmode]{frametitle} + \fi + \vskip0.5ex% + \usebeamerfont*{frametitle}\strut\insertframetitle% + \ifx\insertframesubtitle\@empty% + \strut\par% + \else + \par{\usebeamerfont*{framesubtitle}{\usebeamercolor[fg]{framesubtitle}\strut\insertframesubtitle}\strut\par}% + \fi%% + \usebeamerfont{headline}% + \vskip0.05ex% + \end{beamercolorbox}% + \nointerlineskip% + \vskip-0.05ex% + \begin{beamercolorbox}[wd=\paperwidth,ht=1ex,dp=0ex]{empty} + \begin{pgfpicture} + \begin{pgfscope}% + \pgfsetfillcolor{frametitle.bg}% + \pgfpathrectangle{\pgfpoint{-.5\paperwidth}{-.5ex}}{\pgfpoint{\paperwidth}{1ex}}% + \pgfsetfading{beamer@belowframetitlemask}{}% + \pgfusepath{fill}% + \end{pgfscope}% + \end{pgfpicture}% + \end{beamercolorbox}% +} + +\AtBeginDocument{% + \setbeamertemplate{frametitle}[smoothbars theme]% +} + + +% \end{macrocode} +% \iffalse +%</beamerouterthemesmoothbars-xetex-bidi.def> +%<*beamerouterthemesmoothtree-xetex-bidi.def> +%\fi +% \section{File \texttt{beamerouterthemesmoothtree-xetex-bidi.def}} +% \begin{macrocode} +\ProvidesFile{beamerouterthemesmoothtree-xetex-bidi.def}[2022/06/09 v0.1 bidi adaptations for beamerouterthemesmoothtree package for XeTeX engine] +\bidi@csundef{beamer@@tmpop@headline@smoothtree theme} + +\bidi@csundef{beamer@@tmpop@frametitle@smoothtree theme} + +\defbeamertemplate*{headline}{smoothtree theme} +{% + \pgfuseshading{beamer@treeshade}% + \vskip-0.05ex% + \begin{beamercolorbox}[wd=\paperwidth,ht=1ex,dp=0ex]{empty} + \begin{pgfpicture} + \begin{pgfscope}% + \pgfsetfillcolor{subsection in head/foot.bg}% + \pgfpathrectangle{\pgfpoint{-.5\paperwidth}{-0.5ex}}{\pgfpoint{\paperwidth}{1ex}}% + \pgfsetfading{beamer@belowframetitlemask}{}% + \pgfusepath{fill}% + \end{pgfscope}% + \end{pgfpicture}% + \end{beamercolorbox}% + \vskip-9.15ex% + \if@RTL + \begin{beamercolorbox}[wd=\paperwidth,ht=1.125ex,dp=1.125ex,ignorebg,% + rightskip=.3cm,leftskip=.3cm plus1fil]{title in head/foot} + \else + \begin{beamercolorbox}[wd=\paperwidth,ht=1.125ex,dp=1.125ex,ignorebg,% + leftskip=.3cm,rightskip=.3cm plus1fil]{title in head/foot} + \fi + \usebeamerfont{title in head/foot}\insertshorttitle + \end{beamercolorbox} + \if@RTL + \begin{beamercolorbox}[wd=\paperwidth,ht=2.125ex,dp=1.125ex,ignorebg,% + rightskip=.3cm,leftskip=.3cm plus1fil]{section in head/foot} + \else + \begin{beamercolorbox}[wd=\paperwidth,ht=2.125ex,dp=1.125ex,ignorebg,% + leftskip=.3cm,rightskip=.3cm plus1fil]{section in head/foot} + \fi + \usebeamerfont{section in head/foot}% + \hskip6pt\insertsectionhead + \end{beamercolorbox} + \if@RTL + \begin{beamercolorbox}[wd=\paperwidth,ht=2.125ex,dp=1.125ex,ignorebg,% + rightskip=.3cm,leftskip=.3cm plus1fil]{subsection in head/foot} + \else + \begin{beamercolorbox}[wd=\paperwidth,ht=2.125ex,dp=1.125ex,ignorebg,% + leftskip=.3cm,rightskip=.3cm plus1fil]{subsection in head/foot} + \fi + \usebeamerfont{subsection in head/foot}% + \hskip12pt\insertsubsectionhead + \end{beamercolorbox} + \vskip-0.4ex% +} + +\defbeamertemplate*{frametitle}{smoothtree theme} +{% + \nointerlineskip% + \vskip-0.05ex% + \usebeamerfont{headline}% + \begin{beamercolorbox}[wd=\paperwidth,ht=0.85ex,dp=0ex]{empty} + \pgfuseshading{beamer@aboveframetitle}% + \end{beamercolorbox} + \nointerlineskip% + \if@RTL + \begin{beamercolorbox}[wd=\paperwidth,rightskip=.935cm,leftskip=.3cm plus1fil]{frametitle} + \else + \begin{beamercolorbox}[wd=\paperwidth,leftskip=.935cm,rightskip=.3cm plus1fil]{frametitle} + \fi + \vskip-1.2ex% + \usebeamerfont*{frametitle}\strut\insertframetitle% + \ifx\insertframesubtitle\@empty% + \strut\par% + \else + \par{\usebeamerfont*{framesubtitle}{\usebeamercolor[fg]{framesubtitle}\strut\insertframesubtitle}\strut\par}% + \fi%% + \usebeamerfont{headline}% + \end{beamercolorbox}% + \nointerlineskip + \vskip-0.2ex% + \begin{beamercolorbox}[wd=\paperwidth,ht=1ex,dp=0ex]{empty} + \begin{pgfpicture} + \begin{pgfscope}% + \pgfsetfillcolor{frametitle.bg}% + \pgfpathrectangle{\pgfpoint{-.5\paperwidth}{-0.5ex}}{\pgfpoint{\paperwidth}{1ex}}% + \pgfsetfading{beamer@belowframetitlemask}{}% + \pgfusepath{fill}% + \end{pgfscope}% + \end{pgfpicture}% + \end{beamercolorbox}% +} + + +\AtBeginDocument{% + \setbeamertemplate{frametitle}[smoothtree theme]% +} + + +% \end{macrocode} +% \iffalse +%</beamerouterthemesmoothtree-xetex-bidi.def> +%<*beamerouterthemetree-xetex-bidi.def> +%\fi +% \section{File \texttt{beamerouterthemetree-xetex-bidi.def}} +% \begin{macrocode} +\ProvidesFile{beamerouterthemetree-xetex-bidi.def}[2022/06/09 v0.1 bidi adaptations for beamerouterthemetree package for XeTeX engine] +\bidi@csundef{beamer@@tmpop@headline@tree theme} + +\defbeamertemplate*{headline}{tree theme} +{% + \begin{beamercolorbox}[wd=\paperwidth,colsep=1.5pt]{upper separation line head} + \end{beamercolorbox} + \if@RTL + \begin{beamercolorbox}[wd=\paperwidth,ht=2.5ex,dp=1.125ex,% + rightskip=.3cm,leftskip=.3cm plus1fil]{title in head/foot} + \else + \begin{beamercolorbox}[wd=\paperwidth,ht=2.5ex,dp=1.125ex,% + leftskip=.3cm,rightskip=.3cm plus1fil]{title in head/foot} + \fi + \usebeamerfont{title in head/foot}\insertshorttitle + \end{beamercolorbox} + \if@RTL + \begin{beamercolorbox}[wd=\paperwidth,ht=2.5ex,dp=1.125ex,% + rightskip=.3cm,leftskip=.3cm plus1fil]{section in head/foot} + \else + \begin{beamercolorbox}[wd=\paperwidth,ht=2.5ex,dp=1.125ex,% + leftskip=.3cm,rightskip=.3cm plus1fil]{section in head/foot} + \fi + \usebeamerfont{section in head/foot}% + \ifbeamer@tree@showhooks + \setbox\beamer@tempbox=\hbox{\insertsectionhead}% + \ifdim\wd\beamer@tempbox>1pt% + \hskip2pt\raise1.9pt\hbox{\vrule width0.4pt height1.875ex\vrule width 5pt height0.4pt}% + \hskip1pt% + \fi% + \else% + \hskip6pt% + \fi% + \insertsectionhead + \end{beamercolorbox} + \if@RTL + \begin{beamercolorbox}[wd=\paperwidth,ht=2.5ex,dp=1.125ex,% + rightskip=.3cm,leftskip=.3cm plus1fil]{subsection in head/foot} + \else + \begin{beamercolorbox}[wd=\paperwidth,ht=2.5ex,dp=1.125ex,% + leftskip=.3cm,rightskip=.3cm plus1fil]{subsection in head/foot} + \fi + \usebeamerfont{subsection in head/foot}% + \ifbeamer@tree@showhooks + \setbox\beamer@tempbox=\hbox{\insertsubsectionhead}% + \ifdim\wd\beamer@tempbox>1pt% + \hskip9.4pt\raise1.9pt\hbox{\vrule width0.4pt height1.875ex\vrule width 5pt height0.4pt}% + \hskip1pt% + \fi% + \else% + \hskip12pt% + \fi% + \insertsubsectionhead + \end{beamercolorbox} + \begin{beamercolorbox}[wd=\paperwidth,colsep=1.5pt]{lower separation line head} + \end{beamercolorbox} +} + + +% \end{macrocode} +% \iffalse +%</beamerouterthemetree-xetex-bidi.def> %<*beamerthemeHannover-xetex-bidi.def> %\fi % \section{File \texttt{beamerthemeHannover-xetex-bidi.def}} @@ -3342,13 +3834,30 @@ by Vafa Khalighi. % \end{macrocode} % \iffalse %</beamerthemeHannover-xetex-bidi.def> +%<*beamerthemeSingapore-xetex-bidi.def> +%\fi +% \section{File \texttt{beamerthemeSingapore-xetex-bidi.def}} +% \begin{macrocode} +\ProvidesFile{beamerthemeSingapore-xetex-bidi.def}[2022/06/09 v0.1 bidi adaptations for beamerthemeSingapore package for XeTeX engine] +\addtoheadtemplate{\pgfuseshading{beamer@headfade}\vskip-1.25cm}{} + +\beamertemplatedotitem + +\AtBeginDocument{% + \setbeamertemplate{frametitle}[default][center]% +} + + +% \end{macrocode} +% \iffalse +%</beamerthemeSingapore-xetex-bidi.def> %<*bidi.sty> %\fi % \section{File \texttt{bidi.sty}} % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\def\bididate{2022/06/07} -\def\bidi@version{37.6} +\def\bididate{2022/06/09} +\def\bidi@version{37.7} \ProvidesPackage{bidi}[\bididate\space v\bidi@version\space Bidirectional typesetting in plain TeX and LaTeX] \edef\@bidi@info{****************************************************^^J% @@ -3436,7 +3945,7 @@ Bidirectional typesetting in plain TeX and LaTeX] } \newcommand*{\@bidi@pdfcustomproperties}{% This is the bidi package, Version \bidi@version, - Released June 7, 2022. + Released June 9, 2022. } \newcommand*{\bidi@beamer@ragged}{} \@RTLmainfalse @@ -3680,9 +4189,9 @@ Bidirectional typesetting in plain TeX and LaTeX] %\fi % \section{File \texttt{bidi.tex}} % \begin{macrocode} -\def\bididate{2022/06/07} +\def\bididate{2022/06/09} \catcode`@=11 -\def\bidi@version{37.6} +\def\bidi@version{37.7} \let \protect \relax \newlinechar`\^^J \edef\@bidi@info{****************************************************^^J% @@ -3784,7 +4293,7 @@ Bidirectional typesetting in plain TeX and LaTeX] } \def\@bidi@pdfcustomproperties{% This is the bidi package, Version \bidi@version, - Released June 7, 2022. + Released June 9, 2022. } \def\bidi@pdfm@mark{% \special{pdf:% @@ -24215,7 +24724,7 @@ to\rtside{\box\bslice\hfil}} %\fi % \section{File \texttt{latex-xetex-bidi.def}} % \begin{macrocode} -\ProvidesFile{latex-xetex-bidi.def}[2022/06/07 v1.4.4 bidi adaptations for `latex.ltx' for XeTeX engine] +\ProvidesFile{latex-xetex-bidi.def}[2022/06/09 v1.4.5 bidi adaptations for `latex.ltx' for XeTeX engine] \newcommand{\TeXXeTOn}{\TeXXeTstate\@ne} \newcommand{\TeXXeTOff}{\TeXXeTstate\z@} \TeXXeTOn @@ -25173,17 +25682,23 @@ $\@@underline{\hbox{#1}}\m@th$\relax\fi\fi} \@ifpackageloaded{beamerbasecolor}{\input{beamerbasecolor-xetex-bidi.def}}{} \@ifpackageloaded{beamerbaseframecomponents}{\input{beamerbaseframecomponents-xetex-bidi.def}}{} \@ifpackageloaded{beamerbaselocalstructure}{\input{beamerbaselocalstructure-xetex-bidi.def}}{} +\@ifpackageloaded{beamerbasenavigation}{\input{beamerbasenavigation-xetex-bidi.def}}{} \@ifpackageloaded{beamerinnerthemedefault}{\input{beamerinnerthemedefault-xetex-bidi.def}}{} \@ifpackageloaded{beamerinnerthemecircles}{\input{beamerinnerthemecircles-xetex-bidi.def}}{} +\@ifpackageloaded{beamerinnerthemeinmargin}{\input{beamerinnerthemeinmargin-xetex-bidi.def}}{} \@ifpackageloaded{beamerinnerthemerectangles}{\input{beamerinnerthemerectangles-xetex-bidi.def}}{} \@ifpackageloaded{beamerinnerthemerounded}{\input{beamerinnerthemerounded-xetex-bidi.def}}{} \@ifpackageloaded{beamerouterthemedefault}{\input{beamerouterthemedefault-xetex-bidi.def}}{} \@ifpackageloaded{beamerouterthemeinfolines}{\input{beamerouterthemeinfolines-xetex-bidi.def}}{} -\@ifpackageloaded{beamerouterthemeshadow}{\input{beamerouterthemeshadow-xetex-bidi.def}}{} +\@ifpackageloaded{beamerouterthememiniframes}{\input{beamerouterthememiniframes-xetex-bidi.def}}{} \@ifpackageloaded{beamerouterthemesidebar}{\input{beamerouterthemesidebar-xetex-bidi.def}}{} \@ifpackageloaded{beamerouterthemesplit}{\input{beamerouterthemesplit-xetex-bidi.def}}{} \@ifpackageloaded{beamerouterthemeshadow}{\input{beamerouterthemeshadow-xetex-bidi.def}}{} +\@ifpackageloaded{beamerouterthemesmoothbars}{\input{beamerouterthemesmoothbars-xetex-bidi.def}}{} +\@ifpackageloaded{beamerouterthemesmoothtree}{\input{beamerouterthemesmoothtree-xetex-bidi.def}}{} +\@ifpackageloaded{beamerouterthemetree}{\input{beamerouterthemetree-xetex-bidi.def}}{} \@ifpackageloaded{beamerthemeHannover}{\input{beamerthemeHannover-xetex-bidi.def}}{} +\@ifpackageloaded{beamerthemeSingapore}{\input{beamerthemeSingapore-xetex-bidi.def}}{} % \end{macrocode} % \iffalse %</latex-xetex-bidi.def> diff --git a/macros/xetex/latex/bidi/bidi.pdf b/macros/xetex/latex/bidi/bidi.pdf Binary files differindex 28d4d2d664..27dd542f58 100644 --- a/macros/xetex/latex/bidi/bidi.pdf +++ b/macros/xetex/latex/bidi/bidi.pdf diff --git a/macros/xetex/latex/thesis-qom/README b/macros/xetex/latex/thesis-qom/README index 106e2d6586..94269e7093 100644 --- a/macros/xetex/latex/thesis-qom/README +++ b/macros/xetex/latex/thesis-qom/README @@ -1,22 +1,22 @@ -these-qom; Thesis style of the University of Qom, Iran. -ver 0.42 +these-qom; Thesis style of the University of Qom, Iran. +ver 0.5 _____________________ -The class has been written for the University of Qom students +The class has been written for the University of Qom students who want to write their projects, theses, and dissertations. For more information, please see the documentation. -Current version release date: 2018/11/10 +Current version release date: 2022/06/09 The style assumes that the user has the following fonts installed on its system: -XB Niloofar, IranNastaliq, IRlotus, XB Zar, XB Titre, Yas. -The final file must be run with XeLaTeX. +XB Niloofar, IranNastaliq, IRlotus, XB Zar, XB Titre, Yas. +The final file must be run with XeLaTeX. _____________________ Seiied-Mohammad-Javad Razvian javadr@gmail.com -Copyright © 2017-2018 +Copyright © 2017-2022 It may be distributed and/or modified under the LaTeX Project Public License, version 1.3c or higher (your choice). The latest version of this license is at: http://www.latex-project.org/lppl.txt diff --git a/macros/xetex/latex/thesis-qom/doc/thesis-qom.pdf b/macros/xetex/latex/thesis-qom/doc/thesis-qom.pdf Binary files differindex 5f93705603..251b6c5d02 100644 --- a/macros/xetex/latex/thesis-qom/doc/thesis-qom.pdf +++ b/macros/xetex/latex/thesis-qom/doc/thesis-qom.pdf diff --git a/macros/xetex/latex/thesis-qom/doc/thesis-qom.tex b/macros/xetex/latex/thesis-qom/doc/thesis-qom.tex index 934c733c0b..7e23c477f2 100644 --- a/macros/xetex/latex/thesis-qom/doc/thesis-qom.tex +++ b/macros/xetex/latex/thesis-qom/doc/thesis-qom.tex @@ -32,8 +32,8 @@ \include{chapters/qomthesis-guide} % chapter 2 \include{chapters/latexCommands} % chapter 3 \include{chapters/bib-index} % chapter 4 -%\include{chapters/correctWriting} % chapter 5 -%\include{chapters/realSample} % chapter 6 +\include{chapters/correctWriting} % chapter 5 +\include{chapters/realSample} % chapter 6 \appendix \include{chapters/installation} % appendix 1 diff --git a/macros/xetex/latex/thesis-qom/tex/thesis-qom.cls b/macros/xetex/latex/thesis-qom/tex/thesis-qom.cls index e96a15e731..901a2bdbf7 100644 --- a/macros/xetex/latex/thesis-qom/tex/thesis-qom.cls +++ b/macros/xetex/latex/thesis-qom/tex/thesis-qom.cls @@ -1,61 +1,20 @@ -%%% Version 0.42 +%%% Version 0.5 %%% This work is inspired by `Tabriz_thesis.cls' by Vahid Damanafshan, -%%% `yazd-thesis.cls' by Vahid Damanafshan, `KNTU_thesis.cls' by Farschad Torabi, and -%%% `aut-thesis' by Vafa Khalighi. +%%% `yazd-thesis.cls' by Vahid Damanafshan, `KNTU_thesis.cls' by Farschad Torabi, and +%%% `aut-thesis' by Vafa Khalighi. %%% __________________________________ %%% -%%% Copyright © 2017-2018 Seiied-Mohammad-Javad Razavian -%%% -%%% http://www.parsilatex.com +%%% Copyright © 2017-2022 Seiied-Mohammad-Javad Razavian +%%% +%%% http://www.parsilatex.com %%% __________________________________ -%%% -%%% Change Log: -%%% ver 0.42, Nov 10th, 2018 -%%% logo is replaced by logo.jpg because of a conflict with ls-R databese. -%%% ver 0.41, Oct 15th, 2018 -%%% thesis-qom.pdf is now attached to the class documentation. -%%% ver 0.4, Oct 12th, 2018 -%%% The new version is adapted with bidi ver 34.5 and bidi ver 21.6; in this new version extrafootnotefeatures have many extra features than to past, as a result there is no need to patch footnotes. -%%% ver 0.33, Feb 4th, 2018 -%%% The style is called thesis-qom by know. -%%% ver 0.32, Jan 2nd, 2018 -%%% After bidi ver 30.2 and xepersian ver 20.1 ther is no need so adjust text digit font in the style, -%%% because those packages do it as desirable. These updates happened in January 1st, 2018. -%%% ver 0.31, Dec 17th, 2017 -%%% some little change in toc style -%%% ver 0.3, Dec 12th, 2017 -%%% \listofsymbols macro is defined with the aid of Vahid Damanafshan. -%%% ver 0.29, Dec 11th, 2017 -%%% scratch option replaced by final -%%% ver 0.28, Dec 11th, 2017 -%%% Final improvement in setting digits' font to Yas font; it'll be done with the aid of some xetex interal macros. -%%% Thanks to Vafa Khalighi for his draft in doing such an action automatically. -%%% ver 0.27, Dec 10th, 2017 -%%% Another improvement in sophisticated main matter page numbering. -%%% ver 0.26, Dec 9th, 2017 -%%% There is no neeed to \mainmatter macro, it'll be set automatically by some hacks. -%%% ver 0.25, Dec 6th, 2017 -%%% some other improvement in en2fa dictionary. https://tex.stackexchange.com/questions/404984 -%%% ver 0.24, Dec 6th, 2017 -%%% definition of \lettergroup macro changed in coordination with style of fa2en dictionary . -%%% ver 0.23, Dec 5th, 2017 -%%% scratch option causes the preamble pages not to show. Some improvement in dictionaries. -%%% ver 0.22, Dec 4th, 2017 -%%% some improvement in TOC. -%%% ver 0.21, Dec 3rd, 2017 -%%% adding \strut to \RTL and \LTR command, for solving http://qa.parsilatex.com/28105 by vafa khalighi. -%%% Some improvement in dictionaries code. -%%% ver 0.2, Dec 3rd, 2017 -%%% Dictionary files are automatically read from the dicfa2en.tex and dicen2fa.tex. -%%% ver 0.1, Nov 12th, 2017 -%%% First Release - +%%% \NeedsTeXFormat{LaTeX2e}[1994/06/01] -\def\qom@thesis@date{2018/11/10} -\def\qom@thesis@version{0.42} +\def\qom@thesis@date{2022/06/09} +\def\qom@thesis@version{0.5} \ProvidesClass{thesis-qom}[% \qom@thesis@date\space version\qom@thesis@version\space - University of Qom thesis class% + University of Qom thesis class% ] \newif\if@qom@print \newif\if@qom@index @@ -73,7 +32,7 @@ \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{xepersian}} \DeclareOption{final}{\@qom@draftfalse\@qom@printfalse} \DeclareOption{print}{\@qom@printtrue} -\DeclareOption{phd}{\qom@thesistype=\z@\relax} %default option +\DeclareOption{phd}{\qom@thesistype=\z@\relax} %default option \DeclareOption{ms}{\qom@thesistype=\@ne\relax} \DeclareOption{bs}{\qom@thesistype=\tw@\relax} \DeclareOption{index}{\@qom@indextrue}% @@ -213,11 +172,11 @@ \def\@striprank#1({\def\@@striprank##1){##1}% \edef\@rank{\@@striprank#1}}% \def\@get@name@rank#1{% - \@get#1(\relax);% - \edef\@tmpa{\@rank}% - \edef\@relax{\relax}% - \ifx\@tmpa\@relax% - \else\expandafter\@striprank\@rank\fi% + \@get#1(\relax);% + \edef\@tmpa{\@rank}% + \edef\@relax{\relax}% + \ifx\@tmpa\@relax% + \else\expandafter\@striprank\@rank\fi% }% \def\cleardoublepage{\clearpage\if@twoside \ifodd\c@page\else \hbox{} @@ -279,18 +238,18 @@ %\WarningFilter{latex}{Underfull} %\WarningFilter{latex}{Overfull} %\WarningFilter{latex}{LaTeX} -%\WarningsOff[Fancyhdr,fancyhdr, hyperref] +%\WarningsOff[Fancyhdr,fancyhdr, hyperref] %\ActivateWarningFilters %\SafeMode %------------------------------------------------------------------------------------------------------------------- -% در ورژن جدید زیپرشین برای تایپ متنهای ریاضی، این سه بسته، حتماً باید فراخوانی شود؛ این بستهها در صورت نیاز کاربر به متن افزوده خواهد شد. +% در ورژن جدید زیپرشین برای تایپ متنهای ریاضی، این سه بسته، حتماً باید فراخوانی شود؛ این بستهها در صورت نیاز کاربر به متن افزوده خواهد شد. \RequirePackage{amsmath} \RequirePackage{amsthm} \RequirePackage{amssymb} \RequirePackage{biditools} \RequirePackage{multicol} % بستهای برای تنطیم حاشیههای بالا، پایین، چپ و راست صفحه -\RequirePackage[top=40mm, bottom=30mm, left=30mm, right=40mm, +\RequirePackage[top=40mm, bottom=30mm, left=30mm, right=40mm, bindingoffset=0mm, headsep=15mm]{geometry} % \RequirePackage{graphicx} @@ -318,9 +277,9 @@ \RequirePackage[titles, subfigure]{tocloft} \addtolength{\cftchapnumwidth}{10pt} \addtolength{\cftsecnumwidth}{12pt} -\addtolength{\cftsubsecnumwidth}{14pt} +\addtolength{\cftsubsecnumwidth}{14pt} -% بستهای برای ظاهر شدن «مراجع» در فهرست مطالب +% بستهای برای ظاهر شدن «مراجع» در فهرست مطالب %nottoc Disables the inclusion of the ToC. %notlot Disables the inclusion of the List of Tables. %notlof Disables the inclusion of the List of Figures. @@ -330,11 +289,11 @@ \PassOptionsToPackage{quickindex-variant1}{xepersian}% \RequirePackage{makeidx}% \makeindex% -\fi +\fi \RequirePackage{tikz} \global\let\tikz@ensure@dollar@catcode=\relax \RequirePackage{apptools} -%%%%% The hyperref package should be the last package before xepersian package. +%%%%% The hyperref package should be the last package before xepersian package. \if@qom@print \PassOptionsToPackage{monocolor, hyperref}{xcolor} \RequirePackage[hidelinks=true]{hyperref} @@ -343,14 +302,14 @@ \RequirePackage[ pagebackref, colorlinks=true, %% به جای استفاده از مربع قرمز دور موارد ارجاعی از لینک های رنگی استفاده کند. - linkcolor=red, anchorcolor=green, citecolor=magenta, urlcolor=cyan, filecolor=magenta, %% رنگ برخی از لینک ها . + linkcolor=red, anchorcolor=green, citecolor=magenta, urlcolor=cyan, filecolor=magenta, %% رنگ برخی از لینک ها . ]{hyperref} -\fi +\fi %% در این قسمت تنظیمات بسته hyperref را قرار می دهیم. %% این تنظیمات شامل موارد زیر است. \hypersetup{ %% موقعی که فایل پی دی اف خروجی را باز می کنید صفحه به صورت عریض و بزرگ باز می شود. -pdfmenubar=false, pdfstartview=FitH, +pdfmenubar=false, pdfstartview=FitH, %% در قسمت مراجع شماره صفحه ای که به آن مرجع ارجاع داده است را وارد می کند، %% مواردی که برای فعال سازی این که شماره اشکال را به صورت ارجاعی نشان دهد pagebackref =true,hyperfigures=true, @@ -367,29 +326,29 @@ bookmarksnumbered = true % \usepackage[para*]{manyfoot} % \SetFootnoteHook{\setLTR} % \DeclareNewFootnote[para]{A} - \RequirePackage[extrafootnotefeatures, computeautoilg]{xepersian}[2018/10/06] %ver 21.6 and upper + \RequirePackage[extrafootnotefeatures, computeautoilg]{xepersian}[2018/10/06] %ver 21.6 and upper \@ifpackagelater{xepersian}{2018/10/06}{}{% \typeout{} \typeout{############## FATAL ERROR ##############} - \ClassError{thesis-qom}{You must update your TeX distribution; \MessageBreak + \ClassError{thesis-qom}{You must update your TeX distribution; \MessageBreak This version of thesis-qom just works \MessageBreak with xepersian ver 21.6 or upper }{if you have no time to update your TeX distribution,\MessageBreak do use there-qom version 0.34 or below.} \end{document} - } + } \normalRTLparaLTRfootnotes* - % in case of Kashida=off option, because nastaliq font has no support for kashida and the code needs to know about that. + % in case of Kashida=off option, because nastaliq font has no support for kashida and the code needs to know about that. \if@bidi@csundef{if@Kashida@on}{\newif\if@Kashida@on}{} % See http://qa.parsilatex.com/7884 for details \if@bidi@csundef{@bidi@removefromreset}{}{% \@bidi@removefromreset{footnote}{chapter}% } % %\settextfont[Language=Default,Scale=1.33,BoldFont={IRlotus}]{IRLotus} %scale adopted with respect to XB Zar font. - \settextfont[Scale=1.12,]{XB Niloofar} %scale adopted with respect to XB Zar font. + \settextfont[Scale=1.12,]{XB Niloofar} %scale adopted with respect to XB Zar font. \setdigitfont[Scale=1]{Yas} %% \setlatintextfont[Scale=1.1,]{Linux Libertine}%Times New Roman %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \@ifpackageloaded{listings}{ - \lstset{ + \lstset{ basicstyle=\setLTR\@nonlatinfalse\footnotesize\ttfamily, % from xepersian ver. 16.8 captiondirection=RTL, captionscript=nonlatin, } @@ -406,18 +365,24 @@ bookmarksnumbered = true % \DefaultMathsDigits % %\DeclareMathSizes{textsize}{mathsize}{scriptsize}{scriptscriptsize} - % گزینه اول: این برای چه دسته فونتی است. پیش فرض استایل ما فونت 10pt است. + % گزینه اول: این برای چه دسته فونتی است. پیش فرض استایل ما فونت 10pt است. % گزینه دوم: اندازه فونت توابع و موجودات ریاضی درون متن. % گزینه سوم: برای اسکریپت ها، اندازه زیرنویس و بالانویس. % گزینه چهارم: برای زیرنویس زیرنویس. - % در دستورات زیر ما برای سه حالت، اندازههای مورد نظر را تعریف کرده ایم. + % در دستورات زیر ما برای سه حالت، اندازههای مورد نظر را تعریف کرده ایم. % \DeclareMathSizes{10}{11}{9}{8} % For size 10 text % \DeclareMathSizes{11}{12}{11}{10} % For size 11 text % \DeclareMathSizes{12}{13}{12}{11} % For size 12 text %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newsavebox\qom@thesis@proof@box - \sbox{\qom@thesis@proof@box}{\textcolor{gray}{\hboxR{\tiny آماده شده توسط کلاس \texttt{thesis-qom}، نسخهٔ \lr{\qom@thesis@version}}}} + \def\@getcl@ss#1.cls#2\relax{\def\@currentclass{#1}} + \def\@getclass{\expandafter\@getcl@ss\@filelist\relax} + \@getclass + \sbox{\qom@thesis@proof@box}{\textcolor{gray}{\hboxR{\tiny% + \char"0622\char"0645\char"0627\char"062F\char"0647{ }\char"200C\char"0634\char"062F\char"0647{ }% + \char"062A\char"0648\char"0633\char"0637{ }\char"06A9\char"0644\char"0627\char"0633{ }% + \texttt{\@currentclass}، \char"0646\char"0633\char"062E\char"0647\char"0654{ }\lr{\qom@thesis@version}}}} \newdimen\qom@thesis@proof@box@dim@ht \newdimen\qom@thesis@proof@box@dim@wd \qom@thesis@proof@box@dim@wd=\wd\qom@thesis@proof@box @@ -425,10 +390,10 @@ bookmarksnumbered = true \AtBeginDocument{\AtBeginShipoutInit}% \AtBeginShipout{\AtBeginShipoutLowerRight{% % \put doesn't work properly in index pages! - %\put(0,\LengthToUnit{\ht\qom@thesis@proof@box}){\rotatebox{90}{\usebox\qom@thesis@proof@box}}% + %\put(0,\LengthToUnit{\ht\qom@thesis@proof@box}){\rotatebox{90}{\usebox\qom@thesis@proof@box}}% \begin{tikzpicture}[color=black,remember picture, overlay, every node/.style={inner sep=0pt},] - \node at (current page.south east) - [anchor=north, xshift=-\qom@thesis@proof@box@dim@ht,yshift=\qom@thesis@proof@box@dim@wd+2] + \node at (current page.south east) + [anchor=north, xshift=-\qom@thesis@proof@box@dim@ht,yshift=\qom@thesis@proof@box@dim@wd+2] {\rotatebox{90}{\usebox\qom@thesis@proof@box}}; \end{tikzpicture} }} @@ -445,7 +410,7 @@ bookmarksnumbered = true {\typeout{Succeeded in changing `ه` into `ه`}} {\typeout{Failed in changing `ه` into `ه`}} \PersianAlphs -%%% because of computeautoilg the changing from RTL to LTR causes a little space. in this case user can use below macro. +%%% because of computeautoilg the changing from RTL to LTR causes a little space. in this case user can use below macro. \def\bigpar{\par\medskip} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \if@qom@debug @@ -474,9 +439,9 @@ bookmarksnumbered = true \def\Thesis{\ifcase\qom@thesistype{رساله}\or{پایاننامه}\or{پروژه}\fi} % \def\titlepage{\newpage\centering - \thispagestyle{empty} - \parindent 0pt \parskip 10pt plus 1fil minus 1fil - \def\baselinestretch{1}\@normalsize\vbox to \vsize\bgroup\vbox to 9in\bgroup} + \thispagestyle{empty} + \parindent 0pt \parskip 10pt plus 1fil minus 1fil + \def\baselinestretch{1}\@normalsize\vbox to \vsize\bgroup\vbox to 9in\bgroup} \def\endtitlepage{\par\kern 0pt\egroup\vss\egroup\newpage} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newenvironment{preamblepage}{% @@ -497,7 +462,7 @@ bookmarksnumbered = true %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %\renewenvironment{abstract}{ %\section*{چکیده} -%\settextfont[Scale=1.2]{Adobe Arabic} +%\settextfont[Scale=1.2]{Adobe Arabic} %\setlatintextfont[Scale=1]{Times New Roman} %}{\\*[8pt]} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -515,57 +480,57 @@ bookmarksnumbered = true \rule{\textwidth}{1mm}\vspace{-\baselineskip}\\[2pt] \rule{\textwidth}{1pt} - - \noindent - اینجانب آقای/خانم: + + \noindent + اینجانب آقای/خانم: {\ifx\@author@persian\undefined\qom@dotline{سیدمحمدجواد رضویان}\else\bfseries\@author@persian\fi{} } - دانشجوی مقطع + دانشجوی مقطع {کارشناسی ارشد}\ifnum\qom@thesistype=1\rlap{\checkmark}\fi$\bigcirc$ %\hskip 10pt - {دکتری}\ifnum\qom@thesistype=0\rlap{\checkmark}\fi$\bigcirc$ %\hskip 10pt - به شماره دانشجویی + {دکتری}\ifnum\qom@thesistype=0\rlap{\checkmark}\fi$\bigcirc$ %\hskip 10pt + به شماره دانشجویی {\ifx\@student@id\undefined\qom@dotline{۹۶ ۱۲۱۴۱۰۱۸}\else\bfseries\@student@id\fi{} } رشته {\ifx\@major\undefined\qom@dotline{مهندسی کامپیوتر}\else\bfseries\@major\fi{} } {\ifx\@field\undefined\else گرایش \bfseries\@field\fi } - که در تاریخ + که در تاریخ {\ifx\@defensedate\undefined\qom@dotline{۱۳۹۶/۰۷/۱۴}\else\bfseries\LR{\@defensedate}\fi{} } از \Thesis{} خود تحت عنوان:\\ \centerline{\ifx\@title@persian\undefined\qom@dotlined{7cm}\else\bfseries«\@title@persian»\fi} - با کسب نمره با عدد: + با کسب نمره با عدد: {\ifx\@grade\undefined\qom@dotline{۱۹/۲۵}\else\bfseries\LR{$\mathbf{\@grade}$}\fi{} } - با حروف: + با حروف: {\ifx\@grade@letters\undefined\qom@dotline{نوزده و بیست و پنج صدم تمام}\else\bfseries\@grade@letters\fi} - و با درجه + و با درجه {\ifx\@degree\undefined\qom@dotline{عالی}\else\bfseries\@degree\fi{} }\linebreak دفاع نمودهام، بدین وسیله متعهد میشوم که: - \begin{enumerate}[label=\arabic*-] - \item - این \Thesis{} حاصل تحقیق و پژوهش انجام شده توسط اینجانب بوده و در مواردی که از دستاوردهای - علمی و پژوهشی دیگران اعم از پایاننامه، کتاب، مقاله، \ldots استفاده نمودهام، مطابق ضوابط و رویه موجود، نام منبع مورد استفاده و سایر مشخصات - آن را در فهرست مربوطه ذکر و درج کردهام. - \item - این \Thesis{} قبلاً برای هیچ مدرک تحصیلی هم سطح، پایینتر یا بالاتر در سایر \linebreak - دانشگاهها و مؤسسات آموزش عالی ارائه نشده است. - \item - چنانچه بعد از فراغت از تحصیل، قصد استفاده و هرگونه بهرهبرداری اعم از چاپ کتاب، ثبت اختراع و \ldots - از این \Thesis{} را داشته باشم، از حوزه معاونت پژوهشی واحد مجوزهای مربوطه را اخذ نمایم. - \item - چنانچه در هر مقطع زمانی خلاف موارد فوق ثابت شود، عواقب ناشی از آن را میپذیرم و واحد دانشگاه قم مجاز است با اینجانب مطابق ضوابط و مقررات - رفتار نموده و در صورت ابطال مدرک تحصیلیام هیچگونه ادعایی نخواهم داشت. - \end{enumerate} + \begin{enumerate}[label=\arabic*-] + \item + این \Thesis{} حاصل تحقیق و پژوهش انجام شده توسط اینجانب بوده و در مواردی که از دستاوردهای + علمی و پژوهشی دیگران اعم از پایاننامه، کتاب، مقاله، \ldots استفاده نمودهام، مطابق ضوابط و رویه موجود، نام منبع مورد استفاده و سایر مشخصات + آن را در فهرست مربوطه ذکر و درج کردهام. + \item + این \Thesis{} قبلاً برای هیچ مدرک تحصیلی هم سطح، پایینتر یا بالاتر در سایر \linebreak + دانشگاهها و مؤسسات آموزش عالی ارائه نشده است. + \item + چنانچه بعد از فراغت از تحصیل، قصد استفاده و هرگونه بهرهبرداری اعم از چاپ کتاب، ثبت اختراع و \ldots + از این \Thesis{} را داشته باشم، از حوزه معاونت پژوهشی واحد مجوزهای مربوطه را اخذ نمایم. + \item + چنانچه در هر مقطع زمانی خلاف موارد فوق ثابت شود، عواقب ناشی از آن را میپذیرم و واحد دانشگاه قم مجاز است با اینجانب مطابق ضوابط و مقررات + رفتار نموده و در صورت ابطال مدرک تحصیلیام هیچگونه ادعایی نخواهم داشت. + \end{enumerate} \vfill \begin{footnotesize} \bfseries - \begin{tabularx}{\textwidth}{@{\hskip 1cm}c@{\hskip 2.5cm}c} - صحت امضای دانشجو مورد تایید است. & نام و نامخانوادگی متعهد: \\ - نماینده تحصیلات تکمیلی & {\scriptsize تاریخ و امضاء} \\ - نام و نامخانوادگی: \ldots\ldots\ldots & \\ - {\scriptsize تاریخ و امضاء} & \\ - \end{tabularx} - \end{footnotesize} - \vfill\null + \begin{tabularx}{\textwidth}{@{\hskip 1cm}c@{\hskip 2.5cm}c} + صحت امضای دانشجو مورد تایید است. & نام و نامخانوادگی متعهد: \\ + نماینده تحصیلات تکمیلی & {\scriptsize تاریخ و امضاء} \\ + نام و نامخانوادگی: \ldots\ldots\ldots & \\ + {\scriptsize تاریخ و امضاء} & \\ + \end{tabularx} + \end{footnotesize} + \vfill\null \end{preamblepage} } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -592,32 +557,32 @@ bookmarksnumbered = true % \end{center} {\bfseries با تأييدات خداوند متعال و با استعانت از حضرت ولی عصر} - {\footnotesize (عجل الله تعالی فرجه الشريف)} - - - جلسه دفاعیه \ifcase\qom@thesistype{رساله دکتری}\or{پایاننامه کارشناسی ارشد}\fi{} خانم/آقای{} - {\ifx\@author@persian\undefined\qom@dotlined{4cm}\else\bfseries\@author@persian\fi} - رشته + {\footnotesize (عجل الله تعالی فرجه الشريف)} + + + جلسه دفاعیه \ifcase\qom@thesistype{رساله دکتری}\or{پایاننامه کارشناسی ارشد}\fi{} خانم/آقای{} + {\ifx\@author@persian\undefined\qom@dotlined{4cm}\else\bfseries\@author@persian\fi} + رشته {\ifx\@major\undefined\qom@dotline{مهندسی کامپیوتر}\else\bfseries\@major\fi} - تحت عنوان - {\ifx\@title@persian\undefined\qom@dotlined{9cm}\else\bfseries\@title@persian\fi} - با حضور هیأت داوران در محل دانشگاه قم در تاریخ + تحت عنوان + {\ifx\@title@persian\undefined\qom@dotlined{9cm}\else\bfseries\@title@persian\fi} + با حضور هیأت داوران در محل دانشگاه قم در تاریخ {\ifx\@defensedate\undefined\qom@dotline{۱۳۹۶/۰۷/۱۴}\else\bfseries\LR{\@defensedate}\fi{} } - تشکیل گردید. - - در این جلسه، \Thesis{} با نمره (به عدد - {\bfseries\ifx\@grade\undefined\ldots\ldots\ldots\else\LR{$\mathbf{\@grade}$}\fi}{،} - به حروف - {\bfseries\ifx\@grade@letters\undefined\ldots\ldots\ldots\ldots\ldots\ldots\ldots\ldots\else\@grade@letters\fi}) و \linebreak + تشکیل گردید. + + در این جلسه، \Thesis{} با نمره (به عدد + {\bfseries\ifx\@grade\undefined\ldots\ldots\ldots\else\LR{$\mathbf{\@grade}$}\fi}{،} + به حروف + {\bfseries\ifx\@grade@letters\undefined\ldots\ldots\ldots\ldots\ldots\ldots\ldots\ldots\else\@grade@letters\fi}) و \linebreak با درجه عالی ~% - \ifx\@degree\@excellent\rlap{\checkmark}\fi$\bigcirc$ \hskip 10pt + \ifx\@degree\@excellent\rlap{\checkmark}\fi$\bigcirc$ \hskip 10pt بسیار~خوب~% - \ifx\@degree\@verygood\rlap{\checkmark}\fi$\bigcirc$\hskip 10pt + \ifx\@degree\@verygood\rlap{\checkmark}\fi$\bigcirc$\hskip 10pt خوب~% - \ifx\@degree\@good\rlap{\checkmark}\fi$\bigcirc$\hskip 10pt + \ifx\@degree\@good\rlap{\checkmark}\fi$\bigcirc$\hskip 10pt قابل~قبول~% - \ifx\@degree\@acceptable\rlap{\checkmark}\fi$\bigcirc$\hskip 10pt مورد دفاع قرار گرفت. - + \ifx\@degree\@acceptable\rlap{\checkmark}\fi$\bigcirc$\hskip 10pt مورد دفاع قرار گرفت. + \vskip 5pt \def\@nextrow{\\[10pt]} \begin{tabularx}{\textwidth}{|@{\hskip 3pt}p{4cm}@{\hskip 3pt}|@{\hskip 2pt}c@{\hskip 2pt}|@{}c@{}|@{}X@{}|} @@ -626,73 +591,73 @@ bookmarksnumbered = true \multicolumn{1}{c|}{\titrfont\small سمت} & \multicolumn{1}{c|}{\titrfont\small مرتبه علمی} & \multicolumn{1}{c|}{\titrfont\small امضاء} - \\[5pt] + \\[5pt] \toprule\toprule % &&&\\ - \ifnum\qom@thesis@supervisor>\z@ - \@first@supervisor@name@persian & - \ifcase\qom@thesis@supervisor\or استاد راهنما\or استاد راهنمای اوّل\fi & - \@first@supervisor@rank@persian & \@nextrow - \ifnum\qom@thesis@supervisor=\tw@ - \@second@supervisor@name@persian & - \@too{استاد} \@too{راهنمای} - دوّم & - \@second@supervisor@rank@persian & \@nextrow\fi + \ifnum\qom@thesis@supervisor>\z@ + \@first@supervisor@name@persian & + \ifcase\qom@thesis@supervisor\or استاد راهنما\or استاد راهنمای اوّل\fi & + \@first@supervisor@rank@persian & \@nextrow + \ifnum\qom@thesis@supervisor=\tw@ + \@second@supervisor@name@persian & + \@too{استاد} \@too{راهنمای} + دوّم & + \@second@supervisor@rank@persian & \@nextrow\fi \fi \ifnum\qom@thesis@advisor>\z@ - \@first@advisor@name@persian & - \ifcase\qom@thesis@advisor\or{ استاد مشاور}\or{استاد مشاور اوّل}\fi & + \@first@advisor@name@persian & + \ifcase\qom@thesis@advisor\or{ استاد مشاور}\or{استاد مشاور اوّل}\fi & \@first@advisor@rank@persian & \@nextrow - \ifnum\qom@thesis@advisor=\tw@ + \ifnum\qom@thesis@advisor=\tw@ \@second@advisor@name@persian & - \@too{استاد} \@too{مشاور} - دوّم & + \@too{استاد} \@too{مشاور} + دوّم & \@second@advisor@rank@persian &\@nextrow\fi\fi \ifnum\qom@thesis@referee@enternal>\z@ - \@first@referee@name & - \ifcase\qom@thesis@referee@enternal\or{داور داخلی}\or{داور داخلی اوّل}\fi & + \@first@referee@name & + \ifcase\qom@thesis@referee@enternal\or{داور داخلی}\or{داور داخلی اوّل}\fi & \@first@referee@rank & \@nextrow - \ifnum\qom@thesis@referee@enternal=\tw@ - \@second@referee@name & \@too{داور} \@too{داخلی} + \ifnum\qom@thesis@referee@enternal=\tw@ + \@second@referee@name & \@too{داور} \@too{داخلی} دوّم & \@second@referee@rank & \@nextrow\fi\fi \ifnum\qom@thesis@referee@external>\z@ \@first@referee@external@name & - \ifcase\qom@thesis@referee@external\or{داور خارجی}\or{داور خارجی اوّل}\fi & - \@first@referee@external@rank &\@nextrow + \ifcase\qom@thesis@referee@external\or{داور خارجی}\or{داور خارجی اوّل}\fi & + \@first@referee@external@rank &\@nextrow \ifnum\qom@thesis@referee@external=\tw@ - \@second@referee@external@name & \@too{داور} \@too{خارجی} - دوّم - & \@second@referee@external@rank & \@nextrow\fi\fi + \@second@referee@external@name & \@too{داور} \@too{خارجی} + دوّم + & \@second@referee@external@rank & \@nextrow\fi\fi - \ifx\qom@graduate@repsentative@name\undefined\else\qom@graduate@repsentative@name\fi & - \parbox[t]{4.1cm}{\centering استاد ناظر و \par نماینده تحصیلات تکمیلی} - & \ifx\qom@graduate@repsentative@rank\undefined\else\qom@graduate@repsentative@rank\fi & + \ifx\qom@graduate@repsentative@name\undefined\else\qom@graduate@repsentative@name\fi & + \parbox[t]{4.1cm}{\centering استاد ناظر و \par نماینده تحصیلات تکمیلی} + & \ifx\qom@graduate@repsentative@rank\undefined\else\qom@graduate@repsentative@rank\fi & \\ % & نماینده تحصیلات تکمیلی & & \\[5pt] \bottomrule \end{tabularx} - \bigskip + \bigskip % \vfill \begin{tabularx}{\textwidth}{XX} \begin{minipage}{.4\textwidth} \centering معاون آموزشی و پژوهشی دانشکده\\[5pt] - نام و امضاء + نام و امضاء \end{minipage} & \begin{minipage}{.4\textwidth} \centering مدیر آموزش و تحصیلات تکمیلی \\[5pt] - نام و امضاء + نام و امضاء \end{minipage}\\ \end{tabularx} - \vfill - \thispagestyle{empty} - } + \vfill +\thispagestyle{empty} +} \end{preamblepage}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\qomtitle}{% @@ -700,7 +665,7 @@ bookmarksnumbered = true \if@qom@draft\else \begin{preamblepage} \vspace*{\fill} - \textcolor{gray}{\hfill\tiny آماده شده توسط کلاس \texttt{thesis-qom}، نسخهٔ \lr{\qom@thesis@version}} + \hfill\usebox\qom@thesis@proof@box \end{preamblepage} \fi @@ -724,12 +689,12 @@ bookmarksnumbered = true \begin{titlepage} {\zarfont\fontsize{12}{14}\selectfont\includegraphics[width=2cm, height=2cm]{logo.jpg}\\[-7pt] \bfseries دانشگاه قم} \\[-5pt] - {\zarfont\fontsize{12}{14}\selectfont\bfseries دانشکده + {\zarfont\fontsize{12}{14}\selectfont\bfseries دانشکده \ifx\@faculty\undefined\qom@dotline{علوم ریاضی}\else\@faculty\fi - \\[-7pt] - گروه + \\[-7pt] + گروه \ifx\@department\undefined\qom@dotline{علوم کامپیوتر}\else\@department\fi} - \\%[5pt] + \\%[5pt] %\par %\vspace{.3\baselineskip} {\vskip 2ex @@ -738,7 +703,7 @@ bookmarksnumbered = true } %\vskip 2ex % \vskip 5pt - \centerline{\zarfont\fontsize{12}{14}\selectfont\bfseries رشته + \centerline{\zarfont\fontsize{12}{14}\selectfont\bfseries رشته {\ifx\@major\undefined\qom@dotline{مهندسی کامپیوتر}\else\bfseries\@major\fi}{} \ifx\@field\undefined\else گرایش \@field\fi} \vskip 4ex @@ -746,7 +711,7 @@ bookmarksnumbered = true \ifx\@title@persian\undefined\qom@dotlined{9cm}\else\bfseries {\fontsize{22}{24}\selectfont\@title@persian }\fi} \baselineskip=1.5cm\par \vskip 4ex - \baselineskip=1cm + \baselineskip=1cm % \large {\bfseries\ifcase\qom@thesis@supervisor%0 @@ -760,7 +725,7 @@ bookmarksnumbered = true \fontsize{12}{14}\selectfont\@first@supervisor@name@persian{} و \@second@supervisor@name@persian \fi } - \par + \par {\bfseries\ifcase\qom@thesis@advisor\relax%0 \ifnum\qom@thesistype=0\titrfont استاد مشاور: \\ \qom@dotlined{5cm} \fi \or%1 @@ -779,12 +744,12 @@ bookmarksnumbered = true \ifx\@author@persian\undefined\qom@dotlined{4cm} \else\fontsize{12}{14}\selectfont\bfseries\@author@persian\fi} \par - {\bfseries\fontsize{12}{14}\selectfont\zarfont + {\bfseries\fontsize{12}{14}\selectfont\zarfont \ifx\@submissiondate\undefined ماه سال\else\@submissiondate\fi} \end{titlepage} -\end{preamblepage} +\end{preamblepage} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% برای پروژه کارشناسی نیازی به صفحات زیر نیست. +% برای پروژه کارشناسی نیازی به صفحات زیر نیست. \if@qom@draft\else \ifnum\qom@thesistype<\tw@ %%%%%%%%%%%%%%% صفحه تأییده داوران @@ -792,28 +757,28 @@ bookmarksnumbered = true %%%%%%%%%%%%%%% صفحه تعهدنامه اصالت پایاننامه/رساله \oathpage% %%%%%%%%%%%%%%%%%%%%%%%%%%% -\fi +\fi \fi %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%% صفحه تقدیم +%%%%%%%%%%%%%%% صفحه تقدیم \if@qom@draft\else \begin{preamblepage} \ifx\@dedicatedto\undefined% \else - \pagetitle{تقدیم} + \pagetitle{تقدیم} {\@dedicatedto} \fi -\end{preamblepage} +\end{preamblepage} \fi -%%%%%%%%%%%%%%% صفحه نیایش +%%%%%%%%%%%%%%% صفحه نیایش \if@qom@draft\else \begin{preamblepage} \ifx\@praise\undefined% \else - \pagetitle{نیایش} + \pagetitle{نیایش} {\@praise} \fi -\end{preamblepage} +\end{preamblepage} \fi %%%%%%%%%%%%%%% صفحه سپاسگزاری \if@qom@draft\else @@ -843,14 +808,14 @@ bookmarksnumbered = true %%%%%%%%%%%%%%%%%%%%%%%%%%%%% % دستورهایی برای سفارشی کردن صفحات اول فصلها \newcommand\mycustomraggedright{% - \if@RTL\raggedleft% - \else\raggedright% - \fi} - %%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\if@RTL\raggedleft% +\else\raggedright% +\fi} +%%%%%%%%%%%%%%%%%%%%%%%%%%%% \bidi@AfterPackage{xepersian}{% \SepMark{-} % دستوری برای حذف کلمه «چکیده» -\renewcommand{\abstractname}{} +\def\abstractname{} % دستوری برای حذف کلمه «abstract» %\renewcommand{\latinabstract}{} % دستوری برای تغییر نام کلمه «اثبات» به «برهان» @@ -859,7 +824,7 @@ bookmarksnumbered = true \renewcommand{\bibname}{منابع و مآخذ} % دستوری برای تعریف واژهنامه انگلیسی به فارسی \newcommand\persiangloss[2]{#1\dotfill\lr{#2}\\} -% دستوری برای تعریف واژهنامه فارسی به انگلیسی +% دستوری برای تعریف واژهنامه فارسی به انگلیسی \newcommand\englishgloss[2]{#2\dotfill\lr{#1}\\} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% با دستور newtheoremstyle شما می توانید یک استایل جدید برای محیط هایی چون plain، definition و ... تعریف کنید. شکل کلی این دستور به صورت زیر است. @@ -873,9 +838,9 @@ bookmarksnumbered = true %% {headpunctuation}% punctuation between head and body %% {headspace}% space after theorem head; " " = normal interword space %% {headspec}% Manually specify head -% % تعریف محیطهای گوناگون مانند محیط برای قضیه و ... -%% theoremstyle = > plain, definition, remark -%% با دستور newtheorem یک نوع از استایلی که در بالای آن تعریف شده است ایجاد می کنیم. +% % تعریف محیطهای گوناگون مانند محیط برای قضیه و ... +%% theoremstyle = > plain, definition, remark +%% با دستور newtheorem یک نوع از استایلی که در بالای آن تعریف شده است ایجاد می کنیم. % تعریف و نحوه ظاهر شدن عنوان قضیهها، تعریفها، مثالها و ... \theoremstyle{definition} \newtheorem{definition}{تعریف}[chapter] @@ -903,46 +868,46 @@ bookmarksnumbered = true %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \AtBeginDocument{% \def\@makechapterhead#1{% - \vspace*{50\p@}% - {\parindent \z@ \if@RTL\raggedleft\else\raggedright\fi \normalfont + \vspace*{50\p@}% + {\parindent \z@ \if@RTL\raggedleft\else\raggedright\fi \normalfont \ifnum \c@secnumdepth >\m@ne - \if@mainmatter - \huge\bfseries \@chapapp\space + \if@mainmatter + \huge\bfseries \@chapapp\space \ifappendix \harfi{chapter}\else \expandafter\tartibinumeral\c@chapter\fi \par\nobreak \vskip 20\p@ - \fi + \fi \fi \interlinepenalty\@M \Huge \bfseries #1\par\nobreak \vskip 40\p@ \nobreak \thispagestyle{empty} - }} + }} \def\@makeschapterhead#1{% - \vspace*{50\p@}% - {\parindent \z@ \if@RTL\raggedleft\else\raggedright\fi + \vspace*{50\p@}% + {\parindent \z@ \if@RTL\raggedleft\else\raggedright\fi \normalfont \interlinepenalty\@M \Huge \bfseries #1\par\nobreak \vskip 40\p@ \thispagestyle{empty} - }} - \bidi@appto{\appendix}{%\addcontentsline{toc}{chapter}{پیوستها}%\appendices - \appendixtrue} - %% The followings are hacks for not using \mainmatter macro by users. - %% Sophisticated front matter page-numbering + }} + \bidi@appto{\appendix}{%\addcontentsline{toc}{chapter}{پیوستها}%\appendices + \appendixtrue} + %% The followings are hacks for not using \mainmatter macro by users. + %% Sophisticated front matter page-numbering % \bidi@preto{\chapter}{\if@qom@preamble\else\ifappendix\else\ifnum\c@chapter=0\mainmatter\fi\fi\fi} % \bidi@patchcmd{\@chapter}{\if@mainmatter}{\if@qom@preamble\else\ifappendix\else\ifnum\c@chapter=0\global\mainmatter\fi\fi\fi\if@mainmatter}{}{} - \bidi@patchcmd{\secdef}{\@dblarg}{\if@qom@preamble\else\ifappendix\else\ifnum\c@chapter=0\mainmatter\fi\fi\fi\@dblarg}{}{} - \bidi@appto{\tableofcontents}{\@qom@preamblefalse} - \bidi@appto{\listoffigures}{\@qom@preamblefalse} - \bidi@appto{\listoftables}{\@qom@preamblefalse} - \bidi@appto{\lstlistoflistings}{\@qom@preamblefalse} - \bidi@appto{\listofsymbols}{\@qom@preamblefalse} - \bidi@appto{\endacronym}{\@qom@preamblefalse} - \setlength{\parindent}{1cm} - \setlength{\parskip}{0pt} + \bidi@patchcmd{\secdef}{\@dblarg}{\if@qom@preamble\else\ifappendix\else\ifnum\c@chapter=0\mainmatter\fi\fi\fi\@dblarg}{}{} + \bidi@appto{\tableofcontents}{\@qom@preamblefalse} + \bidi@appto{\listoffigures}{\@qom@preamblefalse} + \bidi@appto{\listoftables}{\@qom@preamblefalse} + \bidi@appto{\lstlistoflistings}{\@qom@preamblefalse} + \bidi@appto{\listofsymbols}{\@qom@preamblefalse} + \bidi@appto{\endacronym}{\@qom@preamblefalse} + \setlength{\parindent}{1cm} + \setlength{\parskip}{0pt} % %\setlength{\footskip}{ %\paperheight -(1in+\voffset+\topmargin+\headheight+\headsep+\textheight) -1cm @@ -950,7 +915,7 @@ bookmarksnumbered = true \pagenumbering{roman} \qomtitle \frontmatter -} +}%End of AtBeginDocument %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \def\@part[#1]#2{% \ifnum\c@secnumdepth >-2\relax @@ -962,10 +927,9 @@ bookmarksnumbered = true \markboth{}{}% {\centering \interlinepenalty \@M -\ifnum \c@secnumdepth >-2\relax - \huge\bfseries \partname\nobreakspace\thepart -\par -\vskip 20\p@ +\ifnum \c@secnumdepth >-2\relax% + \huge\bfseries \partname\nobreakspace\thepart + \par\vskip 20\p@ \fi \Huge\bfseries #2\par}% \@endpart} @@ -979,7 +943,7 @@ bookmarksnumbered = true %\vskip 20\p@ %\fi %\fi -%\interlinepenalty\@M +%\interlinepenalty\@M %\Huge \bfseries #1\par\nobreak %\vskip 120\p@ %}} @@ -1052,13 +1016,13 @@ bookmarksnumbered = true \parskip\z@ \@plus .3\p@\relax \if@qom@dicentofa% \def\qom@dicrow##1##2{\bigskip##1\dotfill\rl{##2}\par}%% en2fa - \fi% + \fi% \if@qom@dicfatoen% \def\qom@dicrow##1##2{\medskip##1\dotfill\dotfill\hbox{\lr{##2}}\par}%% fa2en \fi% \def\qom@dic@letter@space{\def\qom@dic@letter@space{\bigskip}}% \def\qom@dic@letter@title##1{% - \qom@dic@letter@space\centerline{\normalfont\textbf{##1}}\nobreak}% + \qom@dic@letter@space\centerline{\normalfont\textbf{##1}}\nobreak}% \expandafter\gdef\expandafter\qom@trimtok##1=##2;\relax{\qom@dicrow{##1}{##2}}% \gdef\qom@trimmer##1{\expandafter\qom@trimtok ##1;\relax}% \catcode\endlinechar=9 % @@ -1110,23 +1074,23 @@ bookmarksnumbered = true \fi %%%%%%%%%%%%%%%%%%%%%% Index %%%%%%%%%%%%%%%%%%%%%%%%% \if@qom@index - \providecommand*\lettergroup[1]{% - \par% + \providecommand*\lettergroup[1]{% + \par% \def\qom@lettergroup{#1}% - \ifx\qom@lettergroup\qom@Aa% + \ifx\qom@lettergroup\qom@Aa% \textbf{آ}% - \else% + \else% \ifx\qom@lettergroup\qom@He% \textbf{ه}% - \else% + \else% \textbf{#1}% \fi% \fi% - \par% - \nopagebreak% - }% + \par% + \nopagebreak% + }% \printindex% - \fi + \fi %%%%%%%%%%%%%%%%%%%%%% English Abstract %%%%%%%%%%%%%%%%%%%%%%%%% \begin{preamblepage} \begin{latin} @@ -1138,9 +1102,9 @@ bookmarksnumbered = true \end{abstractcount} \vspace*{1cm}\par {\noindent {\bfseries Keywords:} - \ifx\@keywords@english\undefined\else\@keywords@english{}\fi} + \ifx\@keywords@english\undefined\else\@keywords@english{}\fi} \fi - \end{latin} + \end{latin} \end{preamblepage} %%%%%%%%%%%%%%%%%%%%%% English Title %%%%%%%%%%%%%%%%%%%%%%%%% \begin{preamblepage} @@ -1148,12 +1112,12 @@ bookmarksnumbered = true \begin{latin} {\fontsize{12}{14}\selectfont\includegraphics[width=2cm, height=2cm]{logo.jpg}\\ The University of Qom} \\[5pt] - {\fontsize{12}{14}\selectfont Faculty of + {\fontsize{12}{14}\selectfont Faculty of \ifx\@faculty@english\undefined\qom@dotline{Mathematics}\else\@faculty@english\fi - \\[5pt] - Department of + \\[5pt] + Department of \ifx\@department@english\undefined\qom@dotline{Computer Science}\else\@department@english\fi} - \\[10pt] + \\[10pt] %\par %\vspace{.3\baselineskip} % {\vskip 4ex @@ -1163,8 +1127,8 @@ bookmarksnumbered = true %\vskip 2ex \vskip 5pt \begin{center} - {\fontsize{12}{14}\selectfont\bfseries - A Thesis Submitted in Partial Fulfillment of the Requirements for\linebreak the Degree of + {\fontsize{12}{14}\selectfont\bfseries + A Thesis Submitted in Partial Fulfillment of the Requirements for\linebreak the Degree of \ifcase\qom@thesistype{Doctor of Philosophy}\or{Master of Science}\or{Bachelor of Science}\fi{} in {\ifx\@major@english\undefined\qom@dotline{Computer Science}\else\bfseries\@major@english\fi}{} } @@ -1174,30 +1138,30 @@ bookmarksnumbered = true \ifx\@title@english\undefined\qom@dotlined{9cm}\else\bfseries {\fontsize{22}{24}\selectfont\@title@english }\fi} \baselineskip=1.5cm\par \vskip 4ex - \baselineskip=.5cm + \baselineskip=.5cm \large {\large\ifcase\qom@thesis@supervisor@english%0 - \textsf{Supervisor:} \\ - \qom@dotlined{5cm} + \textsf{Supervisor:} \\ + \qom@dotlined{5cm} \or%1 - \textsf{Supervisor:} \\ - \bfseries\fontsize{12}{14}\selectfont\@first@supervisor@name@english + \textsf{Supervisor:} \\ + \bfseries\fontsize{12}{14}\selectfont\@first@supervisor@name@english \or%2 - \textsf{Supervisors:} \\ - \bfseries\fontsize{12}{14}\selectfont\@first@supervisor@name@english{} and \@second@supervisor@name@english + \textsf{Supervisors:} \\ + \bfseries\fontsize{12}{14}\selectfont\@first@supervisor@name@english{} and \@second@supervisor@name@english \fi } - \par + \par {\large\ifcase\qom@thesis@advisor@english\relax%0 \ifnum\qom@thesistype=0 Advisor: \\ \qom@dotlined{5cm} \fi \or%1 - \textsf{Advisor:} \\ - \bfseries\fontsize{12}{14}\selectfont% - \@first@advisor@name@english + \textsf{Advisor:} \\ + \bfseries\fontsize{12}{14}\selectfont% + \@first@advisor@name@english \or%2 - \textsf{Advisors:} \\ - \bfseries\fontsize{12}{14}\selectfont% - \@first@advisor@name@english{} and \@second@advisor@name@english + \textsf{Advisors:} \\ + \bfseries\fontsize{12}{14}\selectfont% + \@first@advisor@name@english{} and \@second@advisor@name@english \fi } \par @@ -1206,33 +1170,29 @@ bookmarksnumbered = true \ifx\@author@english\undefined\qom@dotlined{4cm} \else\fontsize{12}{14}\selectfont\bfseries\@author@english\fi} \par - {\fontsize{12}{14}\selectfont + {\fontsize{12}{14}\selectfont \ifx\@submissiondate@english\undefined Season Year\else\@submissiondate@english\fi} - \end{latin} + \end{latin} \end{titlepage} - \end{preamblepage} + \end{preamblepage} %%%%%%%%%%%%%%%%%%% Blank Page %%%%%%%%%%%%%%%%%%%%%%%%% \cleardoublepage \newpage\null \thispagestyle{empty} -} - -\endinput - - -%% -%% Copyright © 2017-2018 by Seiied-Mohammad-Javad Razavian -%% +}%End of \AtEndDocument +%% +%% Copyright © 2017-2022 by Seiied-Mohammad-Javad Razavian +%% %% Distributable under the LaTeX Project Public License, %% version 1.3c or higher (your choice). The latest version of %% this license is at: http://www.latex-project.org/lppl.txt -%% +%% %% This work is "maintained" (as per LPPL maintenance status) %% by Seiied-Mohammad-Javad Razavian -%% +%% %% It is a based on Tabriz_thesis of Vahid Damanafshan, %% which was based on xepersian-thesis.cls by Vafa Khalighi %% ____________________________________________________________________ %% Special thanks to Vafa Khalighi for the XePersian Package. %% This work is supported by University of Qom. -%% End of file `thesis-qom.cls'. +%% End of file `thesis-qom.cls'.
\ No newline at end of file diff --git a/macros/xetex/latex/xepersian/README b/macros/xetex/latex/xepersian/README index a4c10257a1..c0b4f52b1f 100644 --- a/macros/xetex/latex/xepersian/README +++ b/macros/xetex/latex/xepersian/README @@ -1,6 +1,6 @@ ____________________ The XePersian package -v24.3 +v24.4 The xepersian package provides a convenient interface for typesetting Persian and English texts in LaTeX, using XeTeX @@ -25,7 +25,7 @@ The announcements for the new releases of the package will also appear in the Discussions space under the Announcements category. -Current version release date: 2022/06/06 +Current version release date: 2022/06/09 ___________________________________________ Vafa Khalighi diff --git a/macros/xetex/latex/xepersian/xepersian-doc-intro.ltx b/macros/xetex/latex/xepersian/xepersian-doc-intro.ltx index 6b3d601450..cb79496e0e 100644 --- a/macros/xetex/latex/xepersian/xepersian-doc-intro.ltx +++ b/macros/xetex/latex/xepersian/xepersian-doc-intro.ltx @@ -25,7 +25,7 @@ If you use \textsf{\XePersian} package to write any input \TeX\ document, and th * Copyright (c) 2008--2022 Vafa Khalighi * Copyright (c) 2018--2020 bidi-tex GitHub Organization * -* v24.3, 2022/06/06 +* v24.4, 2022/06/09 * * License: LaTeX Project Public License, version * 1.3c or higher (your choice) diff --git a/macros/xetex/latex/xepersian/xepersian-doc-title.ltx b/macros/xetex/latex/xepersian/xepersian-doc-title.ltx index 4c124fdd69..b6cb704736 100644 --- a/macros/xetex/latex/xepersian/xepersian-doc-title.ltx +++ b/macros/xetex/latex/xepersian/xepersian-doc-title.ltx @@ -3,7 +3,7 @@ \begin{document} \title{\textcolor{blue!65!black}{\Huge The \textsf{\XePersian} \textit{Package}}\\ \LARGE Persian for \LaTeXe, using {\XeTeX} engine\\[5pt] -\large User documentation for \textcolor{blue!65!black}{version 24.3}} +\large User documentation for \textcolor{blue!65!black}{version 24.4}} \author{Vafa Khalighi\thanks{Thanks to the bidi-tex GitHub organization consisted of David Carlisle and other members of the {\LaTeX} team to maintain the package in the period 2018--2020.}} \setcounter{page}{0} \thispagestyle{empty} @@ -13,7 +13,7 @@ \textcolor{blue!65!black}{\Huge The \textsf{\XePersian} \textit{Package}} \Large -User documentation for \textcolor{blue!65!black}{version 24.3}} +User documentation for \textcolor{blue!65!black}{version 24.4}} \vskip 0pt plus 3fill \textit{\large to my Master, \textbf{Ferdowsi The Great}} diff --git a/macros/xetex/latex/xepersian/xepersian-doc.ltx b/macros/xetex/latex/xepersian/xepersian-doc.ltx index 332b573ade..d8778c1cf4 100644 --- a/macros/xetex/latex/xepersian/xepersian-doc.ltx +++ b/macros/xetex/latex/xepersian/xepersian-doc.ltx @@ -1,7 +1,7 @@ \documentclass{ltxdoc} \input{xepersian-doc-preamble.ltx} \hypersetup{% - pdftitle={User documentation for version 24.3 of the XePersian + pdftitle={User documentation for version 24.4 of the XePersian package}% } \begin{document} diff --git a/macros/xetex/latex/xepersian/xepersian-doc.pdf b/macros/xetex/latex/xepersian/xepersian-doc.pdf Binary files differindex fec43fc3ab..7a554684a2 100644 --- a/macros/xetex/latex/xepersian/xepersian-doc.pdf +++ b/macros/xetex/latex/xepersian/xepersian-doc.pdf diff --git a/macros/xetex/latex/xepersian/xepersian.dtx b/macros/xetex/latex/xepersian/xepersian.dtx index 992f4e27d4..25b58e5801 100644 --- a/macros/xetex/latex/xepersian/xepersian.dtx +++ b/macros/xetex/latex/xepersian/xepersian.dtx @@ -5,7 +5,7 @@ %<*readme> ____________________ The XePersian package -v24.3 +v24.4 The xepersian package provides a convenient interface for typesetting Persian and English texts in LaTeX, using XeTeX @@ -31,7 +31,7 @@ also appear in the Discussions space under the Announcements category. -Current version release date: 2022/06/06 +Current version release date: 2022/06/09 ___________________________________________ Vafa Khalighi @@ -168,7 +168,7 @@ by Vafa Khalighi. \documentclass{ltxdoc} \input{xepersian-doc-preamble.ltx} \hypersetup{% - pdftitle={Source documentation for version 24.3 of the XePersian + pdftitle={Source documentation for version 24.4 of the XePersian package}% } \EnableCrossrefs @@ -187,7 +187,7 @@ by Vafa Khalighi. % \GetFileInfo{\jobname.dtx} % \title{\textcolor{blue!65!black}{\Huge The \textsf{\XePersian} \textit{Package}}\\ %\LARGE Persian for \LaTeXe, using {\XeTeX} engine\\[5pt] -%\large Source documentation for \textcolor{blue!65!black}{version 24.3}} +%\large Source documentation for \textcolor{blue!65!black}{version 24.4}} % \author{Vafa Khalighi\thanks{Thanks to the bidi-tex GitHub organization consisted of David Carlisle and other members of the {\LaTeX} team to maintain the package in the period 2018--2020.}} %\setcounter{page}{0} %\thispagestyle{empty} @@ -197,7 +197,7 @@ by Vafa Khalighi. %\textcolor{blue!65!black}{\Huge The \textsf{\XePersian} \textit{Package}} % %\Large -%Source documentation for \textcolor{blue!65!black}{version 24.3}} +%Source documentation for \textcolor{blue!65!black}{version 24.4}} % %\vskip 0pt plus 3fill %\textit{\large to my Master, \textbf{Ferdowsi The Great}} @@ -245,7 +245,7 @@ by Vafa Khalighi. %\iffalse %<*table> %\fi -%% \CheckSum{11150} +%% \CheckSum{11153} %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z @@ -431,7 +431,7 @@ by Vafa Khalighi. %\fi % \section{File \texttt{beamerbasetranslator-xepersian.def}} % \begin{macrocode} -\ProvidesFile{beamerbasetranslator-xepersian.def}[2022/05/24 v0.1 xepersian changes to beamerbasetranslator package] +\ProvidesFile{beamerbasetranslator-xepersian.def}[2022/06/09 v0.2 xepersian changes to beamerbasetranslator package] \newcommand*{\ProvideTranslation}[2]{% \providetranslation{#1}{\ifRtoL{#2}{#1}}% } @@ -446,6 +446,9 @@ by Vafa Khalighi. \ProvideTranslation{Definitions}{تعریفها} \ProvideTranslation{Example}{مثال} \ProvideTranslation{Examples}{مثالها} +\ProvideTranslation{Who?}{ارایهدهنده} +\ProvideTranslation{From?}{از} +\ProvideTranslation{When?}{زمان} % \end{macrocode} @@ -3580,8 +3583,8 @@ U+003E U+003E <> U+00BB ; >> -> RIGHT POINTING GUILLEMET % \section{File \texttt{xepersian.sty}} % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\def\xepersian@version{24.3} -\def\xepersiandate{2022/06/06} +\def\xepersian@version{24.4} +\def\xepersiandate{2022/06/09} \ProvidesPackage{xepersian}[\xepersiandate\space v\xepersian@version\space Persian typesetting in XeLaTeX] \RequirePackage{fontspec} @@ -4430,7 +4433,7 @@ Persian typesetting in XeLaTeX] \newcommand*{\@xepersian@pdfcustomproperties}{% This is the xepersian package, Version \xepersian@version, - Released June 6, 2022. + Released June 9, 2022. } \newcommand\twocolumnstableofcontents{% diff --git a/macros/xetex/latex/xepersian/xepersian.pdf b/macros/xetex/latex/xepersian/xepersian.pdf Binary files differindex 39bb3139eb..6ac59b7fd0 100644 --- a/macros/xetex/latex/xepersian/xepersian.pdf +++ b/macros/xetex/latex/xepersian/xepersian.pdf |