[latex3-commits] [git/LaTeX3-latex3-latex3] expandable-file-parse: Implement expandable \file_parse_full_name:n (8c3846b5b)
PhelypeOleinik
tex.phelype at gmail.com
Wed Jun 24 19:37:12 CEST 2020
Repository : https://github.com/latex3/latex3
On branch : expandable-file-parse
Link : https://github.com/latex3/latex3/commit/8c3846b5b18500c9b4743167ec45db13f124888a
>---------------------------------------------------------------
commit 8c3846b5b18500c9b4743167ec45db13f124888a
Author: PhelypeOleinik <tex.phelype at gmail.com>
Date: Wed Jun 24 14:37:12 2020 -0300
Implement expandable \file_parse_full_name:n
and have \file_parse_full_name:nNNN use the expandable implementation underneath
>---------------------------------------------------------------
8c3846b5b18500c9b4743167ec45db13f124888a
l3kernel/l3file.dtx | 152 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 108 insertions(+), 44 deletions(-)
diff --git a/l3kernel/l3file.dtx b/l3kernel/l3file.dtx
index c189e4bdd..8b941181b 100644
--- a/l3kernel/l3file.dtx
+++ b/l3kernel/l3file.dtx
@@ -3358,63 +3358,127 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\file_parse_full_name:nNNN, \file_parse_full_name:VNNN}
-% \begin{macro}
-% {\@@_parse_full_name_auxi:w, \@@_parse_full_name_split:nNNNTF}
-% Parsing starts by stripping off any surrounding quotes. Then find
-% the directory |#4| by splitting at the last~|/|. (The auxiliary
-% returns \texttt{true}/\texttt{false} depending on whether it found
-% the delimiter.) We correct for the case of a file in the root |/|,
-% as in that case we wish to keep the trailing (and only) slash. Then
-% split the base name |#5| at the last dot. If there was indeed a
-% dot, |#5| contains the name and |#6| the extension without the dot,
-% which we add back for convenience. In the special case of no
-% extension given, the auxiliary stored the name into |#6|, we just
-% have to move it to |#5|.
-% \begin{macrocode}
-\cs_new_protected:Npn \file_parse_full_name:nNNN #1#2#3#4
- {
- \exp_after:wN \@@_parse_full_name_auxi:w
- \tl_to_str:n { #1 " #1 " } \s_@@_stop #2#3#4
+% \begin{macro}{\file_parse_full_name:n, \file_parse_full_name_apply:nN}
+% \begin{macro}{\@@_parse_full_name_end:nnn}
+% The main parsing macro \cs{file_parse_full_name_apply:nN} passes the
+% file name |#1| thorugh \cs{__kernel_file_name_sanitize:n} so that we
+% have a single normalised way to treat files internally.
+% \cs{file_parse_full_name:n} uses the former, with a dummy macro to
+% leave each part of the name within a pair of braces.
+% \begin{macrocode}
+\cs_new:Npn \file_parse_full_name:n #1
+ {
+ \file_parse_full_name_apply:nN {#1}
+ \@@_parse_full_name_end:nnn
}
-\cs_generate_variant:Nn \file_parse_full_name:nNNN { V }
-\cs_new_protected:Npn \@@_parse_full_name_auxi:w
- #1 " #2 " #3 \s_@@_stop #4#5#6
- {
- \@@_parse_full_name_split:nNNNTF {#2} / #4 #5
- { \str_if_empty:NT #4 { \str_set:Nn #4 { / } } }
- { }
- \exp_args:No \@@_parse_full_name_split:nNNNTF {#5} . #5 #6
- { \str_put_left:Nn #6 { . } }
+\cs_new:Npn \@@_parse_full_name_end:nnn #1 #2 #3
+ { {#1} {#2} {#3} }
+\cs_new:Npn \file_parse_full_name_apply:nN #1
+ {
+ \exp_args:Ne \@@_parse_full_name_auxi:nN
+ { \__kernel_file_name_sanitize:n {#1} }
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\@@_parse_full_name_auxi:nN}
+% \begin{macro}{\@@_parse_full_name_area:nw}
+% \cs{@@_parse_full_name_area:nw} splits the file name into chunks
+% separated by |/|, until the last one is reached. The last chunk is
+% the file name plus the extension, and everything before that is the
+% path. When \cs{@@_parse_full_name_area:nw} is done, it leaves
+% the path within braces after the scan mark \cs{s_@@_stop} and
+% proceeds parsing the actual file name.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_full_name_auxi:nN #1
+ {
+ \@@_parse_full_name_area:nw { } #1
+ / \q_@@_nil \s_@@_stop
+ }
+\cs_new:Npn \@@_parse_full_name_area:nw #1 #2 / #3 \s_@@_stop
+ {
+ \@@_quark_if_nil:nTF {#3}
{
- \str_set_eq:NN #5 #6
- \str_clear:N #6
+ \@@_parse_full_name_base:nw { } #2 . \q_@@_nil
+ \s_@@_stop {#1}
}
+ { \@@_parse_full_name_area:nw { #1 / #2 } #3 \s_@@_stop }
}
-\cs_new_protected:Npn \@@_parse_full_name_split:nNNNTF #1#2#3#4
+% \end{macrocode}
+%
+% \begin{macro}{\@@_parse_full_name_base:nw}
+% \cs{@@_parse_full_name_base:nw} does roughly the same as above, but
+% it separates the chunks at each period. However here there's some
+% extra complications: In case |#1| is empty, it is assumed that the
+% extension is actually empty, and the file name is |#2|. Besides, an
+% extra |.| has to be added to |#2| because it is later removed in
+% \cs{@@_parse_full_name_tidy:nnnN}. In any case, if there's an
+% extension, it is returned with a leading |.|.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_full_name_base:nw #1 #2 . #3 \s_@@_stop
{
- \cs_set_protected:Npn \@@_tmp:w ##1 ##2 #2 ##3 \s_@@_stop
+ \@@_quark_if_nil:nTF {#3}
{
- \tl_if_empty:nTF {##3}
+ \tl_if_empty:nTF {#1}
{
- \str_set:Nn #4 {##2}
- \tl_if_empty:nTF {##1}
- {
- \str_clear:N #3
- \use_ii:nn
- }
- {
- \str_set:Nx #3 { \str_tail:n {##1} }
- \use_i:nn
- }
+ \tl_if_empty:nTF {#2}
+ { \@@_parse_full_name_tidy:nnnN { } { } }
+ { \@@_parse_full_name_tidy:nnnN { .#2 } { } }
}
- { \@@_tmp:w { ##1 #2 ##2 } ##3 \s_@@_stop }
+ { \@@_parse_full_name_tidy:nnnN {#1} { .#2 } }
}
- \@@_tmp:w { } #1 #2 \s_@@_stop
+ { \@@_parse_full_name_base:nw { #1 . #2 } #3 \s_@@_stop }
}
% \end{macrocode}
+%
+% \begin{macro}{\@@_parse_full_name_tidy:nnnN}
+% Now we just need to tidy some bits left loose before. The loop
+% used in the two macros above start with a leading |/| and |.| in the
+% file path an name, so here we need to remove them, except in the
+% path, if it is a single |/|, in which case it's left as is. After
+% all's done, pass to |#4|.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_full_name_tidy:nnnN #1 #2 #3 #4
+ {
+ \exp_args:Nee #4
+ {
+ \tl_if_empty:nF {#3}
+ {
+ \str_if_eq:nnF {#3} { / }
+ { \use_none:n }
+ }
+ #3
+ }
+ {
+ \tl_if_empty:nF {#1}
+ { \use_none:n }
+ #1
+ }
+ {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\file_parse_full_name:nNNN, \file_parse_full_name:VNNN}
+% \begin{macrocode}
+\cs_new_protected:Npn \file_parse_full_name:nNNN #1 #2 #3 #4
+ {
+ \file_parse_full_name_apply:nN {#1}
+ \@@_full_name_assign:nnnNNN #2 #3 #4
+ }
+\cs_new_protected:Npn \@@_full_name_assign:nnnNNN #1 #2 #3 #4 #5 #6
+ {
+ \str_set:Nn #4 {#1}
+ \str_set:Nn #5 {#2}
+ \str_set:Nn #6 {#3}
+ }
+\cs_generate_variant:Nn \file_parse_full_name:nNNN { V }
+% \end{macrocode}
+% \end{macro}
%
% \begin{macro}{\file_show_list:, \file_log_list:, \@@_list:N}
% \begin{macro}[EXP]{\@@_list_aux:n}
More information about the latex3-commits
mailing list.