[latex3-commits] [git/LaTeX3-latex3-latex3] l3bitset: added l3bitset and load it (f490cbecb)
Ulrike Fischer
fischer at troubleshooting-tex.de
Wed Dec 16 19:18:59 CET 2020
Repository : https://github.com/latex3/latex3
On branch : l3bitset
Link : https://github.com/latex3/latex3/commit/f490cbecb2ab37d6db976f19ae5382746843879a
>---------------------------------------------------------------
commit f490cbecb2ab37d6db976f19ae5382746843879a
Author: Ulrike Fischer <fischer at troubleshooting-tex.de>
Date: Wed Dec 16 19:18:59 2020 +0100
added l3bitset and load it
>---------------------------------------------------------------
f490cbecb2ab37d6db976f19ae5382746843879a
l3kernel/l3.ins | 1 +
l3kernel/l3bitset.dtx | 551 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 552 insertions(+)
diff --git a/l3kernel/l3.ins b/l3kernel/l3.ins
index ad3b5267d..46884ac85 100644
--- a/l3kernel/l3.ins
+++ b/l3kernel/l3.ins
@@ -68,6 +68,7 @@ and all files in that bundle must be distributed together.
\from{l3str.dtx} {package}
\from{l3seq.dtx} {package}
\from{l3int.dtx} {package}
+ \from{l3bitset.dtx} {package}
\from{l3flag.dtx} {package}
\from{l3prg.dtx} {package}
\from{l3sys.dtx} {package,tex}
diff --git a/l3kernel/l3bitset.dtx b/l3kernel/l3bitset.dtx
new file mode 100644
index 000000000..fca6f6ebe
--- /dev/null
+++ b/l3kernel/l3bitset.dtx
@@ -0,0 +1,551 @@
+% \iffalse meta-comment
+%
+%% File: l3bitset.dtx
+%
+% Copyright (C) 2020 The LaTeX3 Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3bitset bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+% \title{^^A
+% The \pkg{l3bitset} package \\ Bitsets ^^A
+% }
+%
+% \author{^^A
+% The \LaTeX3 Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team at latex-project.org}
+% {latex-team at latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released XXXX-XX-XX}
+%
+% \maketitle
+% \begin{documentation}
+%
+% This package defines and implements the data type \texttt{bitset}, a vector of
+% bits. The size of the vector may grow dynamically.
+% Individual bits can be set and cleared by index and by name.
+% The index is unlike other indices in expl3 modules \emph{zero based} as this
+% is the standard for bitset data types.
+% A \texttt{bitset} can be output as binary number or---as needed e.g. in a
+% PDF dictionary---as decimal (arabic) number.
+% Currently only a small subset of the functions provided by the \pkg{bitset}
+% package are implemented here, mainly the functions needed to use bitsets in
+% PDF dictionaries.
+%
+% The bitset is stored as a string and so the vector size is theoretically
+% unlimited, only restricted by \TeX-memory, but the export function
+% \cs{bitset_to_arabic:N} uses a function from the \texttt{int} module and
+% so the length is practically restricted to values smaller than 31 if this
+% output is needed.
+%
+% \section{Creating bitsets}
+% \begin{function}[added = 2020-12-13]
+% {\bitset_new:N,\bitset_new:c}
+% \begin{syntax}
+% \cs{bitset_new:N} \meta{bitset var} \\
+% \end{syntax}
+% Creates a new \meta{bitset var} or raises an error if the name is already taken.
+% The declaration is global. The \meta{bitset var} is initially empty.
+%
+% Bitsets are implemented as string variables consisting of
+% \texttt{1}'s and \texttt{0}'s.
+% The rightmost number is the index position 0, so
+% the string variable can be viewed directly as the binary number.
+%
+% \end{function}
+%
+% \begin{function}[EXP, pTF,added = 2020-12-14]
+% { \bitset_if_exist:N, \bitset_if_exist:c }
+% \begin{syntax}
+% \cs{bitset_if_exist_p:N} \meta{bitset var}
+% \cs{bitset_if_exist:NTF} \meta{bitset var} \Arg{true code} \Arg{false code}%
+% \end{syntax}
+% Tests whether the \meta{bitset var} exist.
+% \end{function}
+
+%
+% \section{Setting and clearing bits}
+%
+% \begin{function}[added = 2020-12-13]
+% { \bitset_set:Nn, \bitset_set:cn, \bitset_gset:Nn, \bitset_gset:cn }
+% \begin{syntax}
+% \cs{bitset_set:Nn} \meta{bitset var} \Arg{integer expression}\\
+% \cs{bitset_gset:Nn} \meta{bitset var} \Arg{integer expression}
+% \end{syntax}
+% Evaluates the \meta{integer expression} and sets the bit of the
+% index position it represents to 1. Index position are zero based and set from
+% right to left (so one can view the bitset as a binary number).
+% If needed the length of the bit vector is enlarged.
+% If the \meta{integer expression} evaluates to a negative number, nothing happens.
+% \end{function}
+%
+% \begin{function}[added = 2020-12-13]
+% { \bitset_clear:Nn, \bitset_clear:cn, \bitset_gclear:Nn, \bitset_clear:cn }
+% \begin{syntax}
+% \cs{bitset_clear:Nn} \meta{bitset var} \Arg{integer expression}\\
+% \cs{bitset_gclear:Nn} \meta{bitset var} \Arg{integer expression}
+% \end{syntax}
+% Evaluates the \meta{integer expression} and clears the bit of the
+% index position it represents (sets it to 0).
+% The index is zero based. If the \meta{integer expression} evaluates to a
+% negative number or is larger than the current length of the bit vector
+% nothing happens. If the leading (left most) bit is cleared,
+% zeros are not trimmed but stay in the bit vector.
+% \end{function}
+%
+% \section{Using bitsets}
+%
+% \begin{function}[EXP,added = 2020-12-14]
+% { \bitset_index:Nn, \bitset_index:cn }
+% \begin{syntax}
+% \cs{bitset_index:Nn} \meta{bitset var} \Arg{integer expression}
+% \end{syntax}
+% Evaluates the \meta{integer expression} and output \texttt{1} if the bit is
+% set and \texttt{0} otherwise.
+% \end{function}
+%
+% \begin{function}[EXP,added = 2020-12-13]
+% {\bitset_to_bin:N, \bitset_to_bin:c}
+% \begin{syntax}
+% \cs{bitset_to_bin:N} \meta{bitset var}
+% \end{syntax}
+% This leaves the current value of the bitset expressed as
+% a binary (string) number in the input stream.
+% If no bit has been set yet, the output is empty.
+% \end{function}
+% \begin{function}[EXP,added = 2020-12-13]
+% {\bitset_to_arabic:N, \bitset_to_arabic:c}
+% \begin{syntax}
+% \cs{bitset_to_arabic:N} \meta{bitset var}
+% \end{syntax}
+% This leaves the current value of the bitset expressed as
+% a decimal number in the input stream. If no bit has been set yet,
+% the output is zero. The function uses \cs{int_from_bin:n}, so it
+% can only be used with a bitset whose value is smaller than $2^{31}-1$.
+% \end{function}
+%
+%
+% \begin{function}[added = 2020-12-13]
+% {\bitset_show:N, \bitset_show:c}
+% \begin{syntax}
+% \cs{bitset_show:N} \meta{bitset var}
+% \end{syntax}
+% Displays the binary and decimal value of the \meta{bitset var} on the terminal,
+% \end{function}
+%
+% \begin{function}[added = 2020-12-13]
+% {\bitset_log:N, \bitset_log:c}
+% \begin{syntax}
+% \cs{bitset_log:N} \meta{bitset var}
+% \end{syntax}
+% Writes the value of the \meta{bitset var} in the log file.
+% \end{function}
+%
+
+% \section{Syntactic sugar: Setting bits by keys}
+%
+% If a property with the same name as the bitset exists which maps names to
+% (explizit) numbers, it is possible to set and clear bits by the keys of this property.
+%
+% For example after this settings
+%
+% \begin{verbatim}
+% \bitset_new:N \l_pdfannot_F_bitset
+% \prop_new:N \l_pdfannot_F_bitset_prop
+% \prop_set_from_keyval:Nn \l_pdfannot_F_bitset_prop
+% {
+% Invisible = 0,
+% Hidden = 1,
+% Print = 2,
+% NoZoom = 3,
+% NoRotate = 4,
+% NoView = 5,
+% ReadOnly = 6,
+% Locked = 7,
+% ToggleNoView = 8,
+% LockedContents = 9
+% }
+% \end{verbatim}
+% it is possible to set bit 2 by using
+% |\bitset_set_key:Nn \l_pdfannot_F_bitset {Print}|
+% If a key is unknown a warning is issued.
+% It is not needed to give all index positions a name.
+% \begin{function}[added = 2020-12-13]
+% {\bitset_set_key:Nn, \bitset_set_key:cn,
+% \bitset_gset_key:Nn,\bitset_gset_key:cn }
+% \begin{syntax}
+% \cs{bitset_set_key:nn} \meta{bitset var} \Arg{key}\\
+% \cs{bitset_gset_key:nn} \meta{bitset var} \Arg{key}
+% \end{syntax}
+% This sets the bit of the position described by key to \texttt{1}.
+%
+% If needed the length of the bit vector is enlarged.
+% \end{function}
+% \begin{function}[added = 2020-12-13]
+% {\bitset_clear_key:Nn, \bitset_clear_key:cn,
+% \bitset_gclear_key:Nn, \bitset_clear_key:cn,}
+% \begin{syntax}
+% \cs{bitset_clear_key:Nn} \meta{bitset var} \Arg{key}\\
+% \cs{bitset_gclear_key:Nn} \meta{bitset var} \Arg{key}
+% \end{syntax}
+% This sets the bit of the position described by key to 0.
+% If the leading (left most) bit is cleared, zeros are not
+% trimmed but stay in the bit vector.
+% \end{function}
+% \begin{function}[EXP,added = 2020-12-14]
+% {\bitset_key:Nn}
+% \begin{syntax}
+% \cs{bitset_key:Nn} \meta{bitset var} \Arg{key}
+% \end{syntax}
+% This outputs \texttt{1} if the bit is set, \texttt{0} otherwise.
+% \end{function}
+% \end{documentation}
+%
+% \begin{implementation}
+% \section{\pkg{l3bitset} implementation}
+% \TestFiles{m3bitset001,m3bitset002}
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=bitset>
+% \end{macrocode}
+% A bitset is a string variable.
+% \begin{macro}
+% {
+% \bitset_new:N, \bitset_new:c
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \bitset_new:N #1
+ {
+ \str_new:N #1
+ }
+\cs_generate_variant:Nn \bitset_new:N {c}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[pTF]
+% {
+% \bitset_if_exist:N, \bitset_if_exist:c
+% }
+%
+% Existence tests.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn
+ \bitset_if_exist:N \str_if_exist:N { p , T , F , TF }
+\prg_new_eq_conditional:NNn
+ \bitset_if_exist:c \str_if_exist:c
+ { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}
+% {
+% \bitset_set:Nn, \bitset_set:cn,
+% \bitset_gset:Nn, \bitset_gset:cn,
+% }
+% A bit is set by either extending the string or by splitting it and
+% then inserting an 1. It is not checked if the value was already 1.
+% \begin{macrocode}
+% #1 name, #2 index (integer expression,zero based)
+\cs_new_protected:Npn \bitset_set:Nn #1 #2
+ {
+ \int_compare:nNnT {#2 } > { -1 }
+ {
+ \int_compare:nNnTF {\str_count:N #1 } < { #2 + 1 }
+ {
+ %extend the str
+ \int_step_inline:nn { #2 - \str_count:N #1 }
+ {
+ \str_put_left:Nn #1 { 0 }
+ }
+ \str_put_left:Nn #1 { 1 }
+ }
+ {
+ %replace value
+ \str_set:Nx #1
+ {
+ \str_range:Nnn #1 {1}{-2 - (#2)}
+ 1
+ \str_range:Nnn #1 {0 -(#2)}{-1}
+ }
+ }
+ }
+ }
+
+%#1 name, #2 index (integer expression,zero based)
+\cs_new_protected:Npn \bitset_gset:Nn #1 #2
+ {
+ \int_compare:nNnT {#2 } > { -1 }
+ {
+ \int_compare:nNnTF {\str_count:N #1 } < { #2 + 1 }
+ {
+ %extend the str
+ \int_step_inline:nn { #2 - \str_count:N #1 }
+ {
+ \str_gput_left:Nn #1 { 0 }
+ }
+ \str_gput_left:Nn #1 { 1 }
+ }
+ {
+ % replace the value
+ \str_gset:Nx #1
+ {
+ \str_range:Nnn #1 {1}{-2 -(#2)}
+ 1
+ \str_range:Nnn #1 {0 -(#2)}{-1}
+ }
+ }
+ }
+ }
+\cs_generate_variant:Nn \bitset_set:Nn {cn}
+\cs_generate_variant:Nn \bitset_gset:Nn {cn}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}
+% {
+% \bitset_clear:Nn, \bitset_clear:cn,
+% \bitset_gclear:Nn, \bitset_gclear:cn
+% }
+% Clearing a bit has only to do something if the string is longer than then index.
+% \begin{macrocode}
+\cs_new_protected:Npn \bitset_clear:Nn #1 #2 %#1 name, #2 index (zero based)
+ {
+ \int_compare:nNnT {#2 } > { -1 }
+ {
+ \int_compare:nNnT {\str_count:N #1 } > { #2 }
+ {
+ % need to replace the str
+ \str_set:Nx #1
+ {
+ \str_range:Nnn #1 {1}{-2 - (#2)}
+ 0
+ \str_range:Nnn #1 { 0 - (#2)}{-1}
+ }
+ }
+ }
+ }
+
+\cs_new_protected:Npn \bitset_gclear:Nn #1 #2 %#1 name, #2 index (zero based)
+ {
+ \int_compare:nNnT {#2 } > { -1 }
+ {
+ \int_compare:nNnT {\str_count:N #1 } > { #2 }
+ {
+ % need to replace the str
+ \str_gset:Nx #1
+ {
+ \str_range:Nnn #1 {1}{-2 -(#2)}
+ 0
+ \str_range:Nnn #1 {0 - (#2)}{-1}
+ }
+ }
+ }
+ }
+\cs_generate_variant:Nn \bitset_clear:Nn {cn}
+\cs_generate_variant:Nn \bitset_gclear:Nn {cn}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}
+% {
+% \bitset_to_arabic:N, \bitset_to_arabic:c,
+% \bitset_to_bin:N, \bitset_to_bin:c,
+% }
+% The naming of the commands follow the names in the \texttt{int} module.
+% \cs{bitset_to_arabic:N} uses \cs{int_from_bin:n} and so can only handle small
+% numbers. There is no test for the string length, so that long bitset with
+% many leading zeros work nevertheless.
+% \begin{macrocode}
+\cs_new:Npn \bitset_to_arabic:N #1
+ {
+ \exp_args:Ne \int_from_bin:n { #1 }
+ }
+
+\cs_new:Npn \bitset_to_bin:N #1
+ {
+ #1
+ }
+
+\cs_generate_variant:Nn \bitset_to_arabic:N {c}
+\cs_generate_variant:Nn \bitset_to_bin:N {c}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}
+% {
+% \bitset_index:Nn, \bitset_index:cn
+% }
+% \begin{macrocode}
+\cs_new:Npn \bitset_index:Nn #1 #2
+ {
+ \int_eval:n { \str_item:Nn #1 { -1 - (#2)} +0 }
+ }
+\cs_generate_variant:Nn \bitset_index:Nn {cn}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{macro}
+% {
+% \bitset_show:N, \bitset_show:c,
+% \bitset_log:N, \bitset_log:c
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \bitset_show:N { \@@_show:NN \msg_show:nnxxxx }
+\cs_generate_variant:Nn \bitset_show:N { c }
+\cs_new_protected:Npn \bitset_log:N { \@@_show:NN \msg_log:nnxxxx }
+\cs_generate_variant:Nn \bitset_log:N { c }
+\cs_new_protected:Npn \__bitset_show:NN #1#2
+ {
+ \__kernel_chk_defined:NT #2
+ {
+ #1 { LaTeX/kernel } { show-bitset }
+ { \token_to_str:N #2 }
+ { \bitset_to_bin:N #2 }
+ { \int_compare:nNnTF { \str_count:N #2 } < {32}
+ { \bitset_to_arabic:N #2 }
+ {---bitset~is~to~long~to~show~it--- }
+ } { }
+ }
+ }
+
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}
+% {
+% \bitset_set_key:Nn, \bitset_set_key:cn,
+% \bitset_gset_key:Nn, \bitset_gset_key:cn
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \bitset_set_key:Nn #1 #2
+ {
+ \prop_if_in:cnTF { \cs_to_str:N #1_prop } {#2}
+ {
+ \bitset_set:Nn #1
+ {
+ \prop_item:cn{ \cs_to_str:N #1_prop }{#2}
+ }
+ }
+ {
+ \__kernel_msg_warning:nnxx { kernel } { bitset-unknown-key }
+ { \token_to_str:N #1 }
+ { \tl_to_str:n { #2} }
+ }
+ }
+
+\cs_new_protected:Npn \bitset_gset_key:Nn #1 #2
+ {
+ \prop_if_in:cnTF { \cs_to_str:N #1_prop } {#2}
+ {
+ \bitset_gset:Nn #1
+ {
+ \prop_item:cn{ \cs_to_str:N #1_prop }{#2}
+ }
+ }
+ {
+ \__kernel_msg_warning:nnxx { kernel } { bitset-unknown-key }
+ { \token_to_str:N #1 }
+ { \tl_to_str:n { #2} }
+
+ }
+ }
+\cs_generate_variant:Nn \bitset_set_key:Nn {cn}
+\cs_generate_variant:Nn \bitset_gset_key:Nn {cn}
+
+% \end{macrocode}
+% \end{macro}%
+% \begin{macro}
+% {
+% \bitset_clear_key:Nn, \bitset_clear_key:cn,
+% \bitset_gclear_key:Nn, \bitset_gclear_key:cn,
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \bitset_clear_key:Nn #1 #2
+ {
+ \prop_if_in:cnTF { \cs_to_str:N #1_prop } {#2}
+ {
+ \bitset_clear:Nn #1
+ {
+ \prop_item:cn{ \cs_to_str:N #1_prop }{#2}
+ }
+ }
+ {
+ \__kernel_msg_warning:nnxx { kernel } { bitset-unknown-key }
+ { \token_to_str:N #1 }
+ { \tl_to_str:n { #2} }
+ }
+ }
+
+\cs_new_protected:Npn \bitset_gclear_key:Nn #1 #2
+ {
+ \prop_if_in:cnTF { \cs_to_str:N #1_prop } {#2}
+ {
+ \bitset_gclear:Nn #1
+ {
+ \prop_item:cn{ \cs_to_str:N #1_prop }{#2}
+ }
+ }
+ {
+ \__kernel_msg_warning:nnxx { kernel } { bitset-unknown-key }
+ { \token_to_str:N #1 }
+ { \tl_to_str:n { #2} }
+ }
+ }
+\cs_generate_variant:Nn \bitset_clear_key:Nn {cn}
+\cs_generate_variant:Nn \bitset_gclear_key:Nn {cn}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}
+% {
+% \bitset_key:Nn, \bitset_key:cn
+% }
+% \begin{macrocode}
+\cs_new:Npn \bitset_key:Nn #1 #2
+ {
+ \prop_if_in:cnTF { \cs_to_str:N #1_prop } {#2}
+ {
+ \int_eval:n
+ {
+ \str_item:Nn #1
+ { -1 -(\prop_item:cn{\cs_to_str:N #1_prop}{#2}) }
+ +0
+ }
+ }
+ {
+ 0
+ }
+ }
+\cs_generate_variant:Nn \bitset_key:Nn {cn}
+% \end{macrocode}
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+% \end{macro}%
+% \end{implementation}
+%
+% \PrintIndex
More information about the latex3-commits
mailing list.