Interface LaTeX3 para funções

Interface LaTeX3 para funções

Recentemente postei uma pergunta sobre como escrever uma macro em TeX simples que modificaria os elementos em uma lista especificada pelo usuário. Mencionei espontaneamente minha antipatia pela interface do TeX, então alguém me mostrou o LaTeX3, que deveria ser, como o manual promete, mais parecido com uma linguagem de programação moderna. Estou apenas começando a programar em TeX, então tem sido uma batalha difícil tentar entender o manual. Presumo que seja porque o manual foi escrito para usuários experientes do TeX; no entanto, não parece haver uma alternativa para quem está começando no LaTeX3/TeX, então não tenho escolha a não ser trabalhar com o que tenho. É por isso que estou postando isso. O manual é confuso e eu gostaria de esclarecer um pouco dessa confusão fazendo algumas perguntas simples sobre sintaxe.

Devo mencionar que a pessoa que me falou sobre o LaTeX3 também me deu uma solução para minha postagem original usando sua interface. Consegui usar esta solução em conjunto com o manual para começar a descobrir alguns fatos básicos sobre a sintaxe do LaTeX3. Vou falar sobre o que consegui descobrir, mas aviso justo, algumas delas são baseadas em minhas próprias inferências - extraídas com a ajuda do exemplo fornecido pelo usuário stackexchange - e não em instruções explícitas no manual, então espere erros. Gostaria que você soubesse que não estou ofuscando as coisas quando às vezes uso minha própria terminologia. É simplesmente difícil falar sobre um assunto que você não entende completamente de uma forma estruturada.

Além disso, estou escrevendo isso como uma postagem separada, não como um comentário, devido ao seu tamanho. Desde já, obrigado.

-------------------------------------------------- -------------------------------------------------- -------------------

Definições de função.

O que consegui descobrir até agora:

Uma nova função é definida, entre outras formas, com o seguinte código:

\cs_new_<restrictions>:Npn <function name> <function parameters> {<replacement code>}

O \cs_new_<restrictions>é um comando LaTeX, o Npn está lá para dizer ao “analisador” da interface o que ele deve esperar após a \cs_new_<restrictions>: Npnparte do código, neste caso, uma única palavra de controle de token, ou seja <function name>, um ou mais parâmetros, ou seja <function parameters>, e um token list, ou seja {<code>}, que substitui a função.

Então, se eu quiser definir uma nova função que receba, digamos, 4 argumentos, eu poderia fazer isso com o seguinte código

\cs_new_<restrictions>:Npn \myfunction #1 #2 #3 #4 {<code>}

E da mesma forma, o código para uma função com 2 argumentos pode ser parecido com isto

\cs_new_<restrictions>:Npn \myfunction #1 #2 {<code>}

Claro, estou assumindo - e corrija-me se estiver errado - os espaços não são necessários, porque o analisador já foi informado sobre como delinear os "meta" argumentos ( <function name>, <parameters>, {<code>}) um do outro com a ajuda de a "metaassinatura"Npn.

Agora, se eu quiser acabar com os #, posso usar o seguinte comando genérico

\cs_new_<restrictions>:Nn <function name>:<function signature> {<code>}

Acordo semelhante, exceto que agora o analisador espera algo <function signature>como Nn, NnN, TnN ou algo assim, depois de <function name>.

Então, novamente, uma função com 4 argumentos poderia ser assim

\cs_new_<restrictions>:Nn \myfunction:NNNN {<code>}

e um com 2 argumentos como este

\cs_new_<restrictions>:Nn \myfunction:NN {<code>}

Existem outros comandos nol3básicobiblioteca para criação de funções, mas sua estrutura geral parece ser essencialmente a mesma. A única diferença está em sua funcionalidade. Por exemplo, usar \cs_set...em vez de \cs_new...torna a função local em oposição a global. Provavelmente escreverei um post de acompanhamento pedindo mais detalhes sobre o que são as expansões e-type e x-type, mas por enquanto acho que é melhor nos concentrarmos no panorama geral.

De qualquer forma, está certo até agora?

Ok, seguindo em frente.

Definições de variáveis.

O que consegui descobrir até agora:

Portanto, existem alguns tipos de dados no LaTeX3, mas os principais sãolistas de tokens,cordas,inteiros,sequências, elistas separadas por vírgula. Cada um deles usa suas próprias abreviações, mas em geral, ao definir uma nova variável, você declara o tipo e segue com uma palavra-chave comonovoouconstdependendo se você está inicializando a variável.

Por exemplo, se eu quiser declarar, mas não inicializar, umlista de tokensvariável eu uso o código:

\tl_new:N \mytokenList

e então, em algum momento, posso armazenar uma lista de tokens \mytokenListcom o código:

\tl_set:Nn \mytokenList {<tokens>}

Mas, se eu souber quais dados quero armazenar na variável desde o início, posso usar este comando (não se aplica asequênciasouinteiros)

\tl_const:Nn \mytokenList {<tokens>}

Além: notei que mesmo variáveis ​​possuem "assinaturas de função". Provavelmente facilita a definição de um regime de análise.

Isso é o mais geral possível, antes de precisar especificar a que tipo de dados estou me referindo, porque cada um tem suas próprias operações associadas.

-------------------------------------------------- -------------------------------------------------- -------------------

Isso é o que tenho até agora. Eu apreciaria qualquer feedback. Esse material não é fácil de aprender sozinho! Especialmente com conhecimento mínimo de TeX, então peço desculpas se alguns de vocês estão olhando para isso e pensando "bem, obviamente". De qualquer forma, obrigado novamente.

Responder1

Existem duas maneiras principais de definir funções:

\cs_new<restrictions>:Npn

\cs_new<restrictions>:Nn

onde pode estar _protected, _noparou _protected_nopar.

Ambas as formas verificam se o N-argumento (ou seja, um único token) a seguir é uma sequência de controle (ou caractere ativo) que está atualmente indefinido eglobalmentedefinir a sequência de controle.

Qual é a diferença? Que a primeira família requer, após a sequência de controle a ser definida, um “texto de parâmetro” antes de {delimitar o “texto de substituição” da função.

O “texto do parâmetro” pode ser qualquer sequência de tokens, incluindo #1, #2e assim por diante, até #9. Porém, para apreciar todo o poder desta liberdade, você precisa estar familiarizado com o capítulo 20 do TeXbook e o conceito de “argumento delimitado”.

Vamos manter as coisas simples, no entanto. Os dois trechos de código a seguir são completamente equivalentes:

\cs_new:Npn \harry_foo:nn #1 #2 { -#1-#2- }
\cs_new:Nn \harry_foo:nn { -#1-#2- }

porque este último fornecerá automaticamente o texto do parâmetro #1#2com base na assinatura da função a ser definida, neste caso :nn.

A assinatura deve consistir em uma sequência (possivelmente vazia) de caracteres ne N.

Observe que os espaços são ignorados quando \ExplSyntaxOnestão ativos, então

\cs_new:Npn \harry_foo:nn #1 #2 { -#1-#2- }
\cs_new:Npn \harry_foo:nn #1#2 { -#1-#2- }
\cs_new:Npn \harry_foo:nn #1#2{ -#1-#2- }

são todos equivalentes. Poderia haver um espaço mesmo depois #, mas eu não recomendo.

As regras de sintaxe do TeX especificam que quando ele espera um “texto de parâmetro” (basicamente, ao fazer \defatribuições semelhantes e após ter armazenado o nome da macro a ser definida)tudoaté o primeiro {faz parte do texto do parâmetro. Não há como prever qual é o texto do parâmetro, daí o pespecificador de argumento especial que significa apenas “tudo até {”.

Apenas textos de parâmetros simples como #1, #1#2e assim por diante podem ser gerados automaticamente, o que é feito quando se usa a segunda família \cs_new<restrictions>:Nn.

Onde você está errado? Supondo que você possa usar Tcomo especificador na assinatura. Os especificadores de argumento Tou Fsão adicionados quando \prg_new_conditional<restrictions>:Nnné executado.

Além disso, sua análise do texto do parâmetro está errada, como mostrado anteriormente.

E quanto a \cs_set<restrictions>:Npne :Nn? Tudo o que foi dito acima se aplica, com a diferença de que a função a ser definida não é verificada se está definida ou não e seu significado será sobrescrito silenciosamente, mas o escopo da declaração coincide com o grupo atual. Normalmente, \cs_set...é usado para funções temporárias que precisam se adaptar ao contexto para que seu significado não seja fixo.


As convenções de nomenclatura para variáveisrecomendaque seu nome começa com l, gou c. Na verdade, as variáveis ​​usadas no expl3código devem estar em conformidade com a convenção; é possível usar nomes “normais”, como \myTokenListpara variáveis ​​do tipo tl(talvez também clist) que serão usadas no documento.

As variáveis ​​que começam com ldevem sempre sofrer ações localmente ( \tl_set:Nn, por exemplo), enquanto as variáveis ​​que começam com gdevem sempre receber ações globalmente ( \tl_gset:Nn, por exemplo).

Variáveis ​​começando com csãoconstantese deveria sernuncaagido após ter sido atribuído um valor, mas apenas usado.

Pode-se definir constantes com

\tl_const:Nn \c_harry_foo_tl {<tokens>}
\str_const:Nn \c_harry_foo_str {<tokens>}
\clist_const:Nn \c_harry_foo_clist {<comma list>}
\seq_const_from_clist:Nn \c_harry_foo_seq {<comma list>}
\prop_const_from_keyval:Nn \c_harry_foo_prop {<key-value list>}
\int_const:Nn \c_harry_foo_int {<integer expression>}
\fp_const:Nn \c_harry_foo_int {<fp expression>}
\bool_const:Nn \c_harry_foo_bool {<boolean expression>}
\dim_const:Nn \c_harry_foo_dim {<dimen expression>}
\skip_const:Nn \c_harry_foo_dim {<skip expression>}
\muskip_const:Nn \c_harry_foo_dim {<muskip expression>}
\intarray_const_from_clist:Nn \c_harry_foo_intarray {<comma list>}
\regex_const:Nn \c_harry_foo_regex {<regex>}
\cc_tab_const:Nn \c_harry_foo_cctab {<code>}

informação relacionada