Создание Виженера квадрат в названием latex3


Я пытаюсь создать Виженера квадрат, используя expl3. Моя цель-обеспечить удобный интерфейс для разных алфавитов и разных масштабах. Поэтому я выбрал табличный подход, который, казалось, очень легко настроить.

Моменты я особенно ценить отзывы:

  • Используя табличные хорошая идея или может быть очень плохо (например, когда пользователь настраивает массив тянется)?
  • Я злоупотребляю expl3 в любой момент (локальные и глобальные)?
  • пользовательский интерфейс в целом (ключ-стоимостного подхода)

Код:

\documentclass{article}
\usepackage[landscape]{geometry}
\usepackage{xparse}

\ExplSyntaxOn
\keys_define:nn { vigenere }
    {
        font        .code:n    = { \cs_set_eq:NN \__vigenere_font: #1 },
        font   .default:n = { \small },
        font   .initial:n = { \small },
        tabcolsep .dim_set:N = \l__vigenere_tabcolsep_dim,
        tabcolsep .initial:n = { 3pt },
        alphabet  .tl_set:N  = \l__vigenere_alphabet_tl,
        alphabet  .initial:n = { 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 }
    }
\NewDocumentCommand { \printvigeneretabular } { O{} }
    {
        \group_begin:
        \keys_set:nn { vigenere } { #1 }
        \clist_set:NV  \l_tmpa_clist \l__vigenere_alphabet_tl
        \clist_clear:N \l_tmpb_clist
        \tl_clear:N    \l_tmpa_tl
        \int_step_inline:nnnn { 1 } { 1 } { \clist_count:N \l_tmpa_clist }
            {
                \tl_put_right:Nx \l_tmpa_tl { c| }
            }
        \__vigenere_font:
        \dim_set_eq:NN \tabcolsep \l__vigenere_tabcolsep_dim
        \expandafter\tabular\expandafter{\expandafter|\l_tmpa_tl}
            \hline
            \bool_while_do:nn { \int_compare_p:n { \clist_count:N \l_tmpa_clist > 0 } }
                {
                    \clist_use:Nnnn \l_tmpa_clist { & } { & } { & }
                    \clist_if_empty:NF \l_tmpb_clist
                        { & \clist_use:Nnnn \l_tmpb_clist { & } { & } { & } }
                    \clist_gpop:NN \l_tmpa_clist \l_tmpa_tl
                    \clist_gput_right:NV \l_tmpb_clist \l_tmpa_tl
                    \\\hline
                }
        \endtabular
        \group_end:
    }
\ExplSyntaxOff

\begin{document}
 \printvigeneretabular\par
 \printvigeneretabular[font=\tiny,alphabet={1,2,3,4,5,6,7,8,9,10},tabcolsep=1pt]
\end{document}


138
6
tex
задан 5 марта 2018 в 06:03 Источник Поделиться
Комментарии
1 ответ

О ваших пунктах:


  1. Интерфейс кажется довольно ясным.

  2. Если вы боитесь о \arraystretch параметр подвергается насилию, вы правы: на двойном размеченный документ все таблицы выходят ужасно и местные средства зачастую не обойтись. Может быть, при добавлении stretch ключ может помочь в этих случаях.

  3. Да, ты злоупотребляешь локальных и глобальных заданий.

Некоторые замечания по поводу кода:


  1. Нет смысла в ключе alphabet чтобы установить Тл переменной, которая затем преобразуется в clist

  2. Там нет необходимости, чтобы установить .default:n для font ключ: значение, указанное .default:n будет использоваться, если ключ называется без присвоения значения

  3. \int_step_inline:nnnn можно сделать более просто с помощью * Особенность tabular

  4. Никогда не используйте \expandafter в expl3 код

  5. Вы не должны использовать глобальные задания на локальные переменные

  6. \clist_gpop:NN должно быть \clist_gpop_left:NN (но я изменил его в \seq_pop_left:NN)

  7. Один человек может сделать с простой петли, используя \prg_replicate:nn

Я тоже предпочитаю готовить стол за столом, с последовательностями вместо clists, которые менее эффективны.

\documentclass{article}
\usepackage[landscape]{geometry}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand { \printvigeneretabular } { O{} }
{
\vigenere_tabular:n { #1 }
}

% keys
\keys_define:nn { vigenere }
{
font .code:n = { \cs_set_eq:NN \__vigenere_font: #1 },
font .initial:n = { \small },
tabcolsep .dim_set:N = \l__vigenere_tabcolsep_dim,
tabcolsep .initial:n = { 3pt },
alphabet .clist_set:N = \l__vigenere_alphabet_clist,
alphabet .initial:n = { 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 }
}

% variables
\tl_new:N \l__vigenere_tablebody_tl
\seq_new:N \l__vigenere_alphabet_seq

% internal function
\cs_new_protected:Nn \vigenere_tabular:n
{
\group_begin:
% set the keys
\keys_set:nn { vigenere } { #1 }
% make a sequence from the alphabet
\seq_set_from_clist:NN \l__vigenere_alphabet_seq \l__vigenere_alphabet_clist
% set the font and the tabcolsep
\__vigenere_font:
\dim_set_eq:NN \tabcolsep \l__vigenere_tabcolsep_dim
% prepare the table body
\tl_clear:N \l__vigenere_tablebody_tl
\prg_replicate:nn { \seq_count:N \l__vigenere_alphabet_seq }
{
\tl_put_right:Nx \l__vigenere_tablebody_tl
{
\seq_use:Nn \l__vigenere_alphabet_seq { & }
\exp_not:n { \\ \hline }
}
\seq_pop_left:NN \l__vigenere_alphabet_seq \l_tmpa_tl
\seq_put_right:NV \l__vigenere_alphabet_seq \l_tmpa_tl
}
% make the table
\tabular { | *{\clist_count:N \l__vigenere_alphabet_clist }{ c| } }
\hline
\tl_use:N \l__vigenere_tablebody_tl
\endtabular
\group_end:
}
\ExplSyntaxOff

\begin{document}

\printvigeneretabular

\printvigeneretabular[font=\tiny,alphabet={1,2,3,4,5,6,7,8,9,10},tabcolsep=1pt]

\end{document}

4
ответ дан 5 марта 2018 в 09:03 Источник Поделиться