Interfaz LaTeX3 para funciones

Interfaz LaTeX3 para funciones

Recientemente publiqué una pregunta sobre cómo escribir una macro en TeX simple que modificaría los elementos en una lista especificada por el usuario. Mencioné sin pensar mi disgusto por la interfaz de TeX, así que alguien me recomendó LaTeX3, que se supone que, como promete el manual, se parece más a un lenguaje de programación moderno. Recién estoy comenzando a programar en TeX, por lo que ha sido una batalla cuesta arriba tratar de entender el manual. Supongo que se debe a que el manual fue escrito para usuarios experimentados de TeX; sin embargo, no parece haber una alternativa para las personas que recién comienzan en LaTeX3/TeX, así que no tengo más opción que trabajar con lo que tengo. Por eso estoy publicando esto. El manual es confuso y me gustaría aclarar parte de esa confusión haciéndole algunas preguntas sencillas sobre la sintaxis.

Debo mencionar que la persona que me habló de LaTeX3 también me dio una solución a mi publicación original usando su interfaz. Pude utilizar esta solución junto con el manual para comenzar a resolver algunos datos básicos sobre la sintaxis de LaTeX3. Voy a hablar de lo que logré descubrir, pero una advertencia: parte de esto se basa en mis propias inferencias, extraídas con la ayuda del ejemplo proporcionado por el usuario de stackexchange, no en instrucciones explícitas en el manual. así que espere errores. Me gustaría que supieras que no estoy confundiendo las cosas cuando a veces uso mi propia terminología. Simplemente es difícil hablar sobre un tema que no comprendes completamente de manera estructurada.

Además, escribo esto como una publicación separada, no como un comentario, debido a su extensión. Gracias de antemano.

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

Definiciones de funciones.

Lo que he logrado descubrir hasta ahora:

Una nueva función se define, entre otras formas, con el siguiente código:

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

Es \cs_new_<restrictions>un comando LaTeX, el Npn está ahí para decirle al "analizador" de la interfaz qué debe esperar después de la \cs_new_<restrictions>: Npnparte del código, en este caso, una única palabra de control de token, es decir <function name>, uno o más parámetros, es decir <function parameters>, y un token. list, es decir {<code>}, que reemplaza la función.

Entonces, si quiero definir una nueva función que tome, digamos, 4 argumentos, podría hacerlo con el siguiente código

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

Y de manera similar, el código para una función con 2 argumentos podría verse así

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

Por supuesto, supongo (y corríjanme si me equivoco) que los espacios no son necesarios, porque al analizador ya se le ha dicho cómo delimitar los "meta" argumentos ( <function name>, <parameters>, {<code>}) entre sí con la ayuda de la "metafirma"npn.

Ahora, si quiero eliminar los #, puedo usar el siguiente comando genérico

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

Trato similar, excepto que ahora el analizador espera algo <function signature>como Nn, NnN, TnN o algo así, después <function name>.

De nuevo, una función con 4 argumentos podría verse así

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

y uno con 2 argumentos como este

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

Hay otros comandos en elconceptos básicos de l3biblioteca para crear funciones, pero su estructura general parece ser esencialmente la misma. La única diferencia está en su funcionalidad. Entonces, por ejemplo, usar \cs_set...en lugar de \cs_new...hace que la función sea local en lugar de global. Probablemente escribiré una publicación de seguimiento solicitando más detalles sobre qué son las expansiones tipo e y tipo x, pero por ahora creo que es mejor ceñirse al panorama general.

De todos modos, ¿es así hasta ahora?

Bien, sigamos adelante.

Definiciones de variables.

Lo que he logrado descubrir hasta ahora:

Hay bastantes tipos de datos en LaTeX3, pero los principales sonlistas de tokens,instrumentos de cuerda,números enteros,secuencias, ylistas separadas por comas. Cada uno usa sus propias abreviaturas, pero en general, al definir una nueva variable, declaras el tipo y le sigue una palabra clave comonuevooconstantedependiendo de si estás inicializando la variable.

Así, por ejemplo, si quiero declarar, pero no inicializar, unlista de tokensvariable utilizo el código:

\tl_new:N \mytokenList

y luego, en algún momento, puedo almacenar una lista de tokens \mytokenListcon el código:

\tl_set:Nn \mytokenList {<tokens>}

Pero, si sé qué datos quiero almacenar en la variable desde el principio, puedo usar este comando (no se aplica asecuenciasonúmeros enteros)

\tl_const:Nn \mytokenList {<tokens>}

Aparte: noté que incluso las variables tienen "firmas de función". Probablemente facilite la definición de un régimen de análisis.

Esto es lo más general que puedo ser, antes de tener que especificar a qué tipo de datos me refiero, porque cada uno tiene sus propias operaciones asociadas.

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

Eso es lo que tengo hasta ahora. Agradecería cualquier comentario. ¡Esto no es fácil de aprender por tu cuenta! Especialmente con un conocimiento mínimo de TeX, así que me disculpo si algunos de ustedes miran esto y piensan "bueno, obviamente". De todos modos, gracias de nuevo.

Respuesta1

Hay dos formas principales de definir funciones:

\cs_new<restrictions>:Npn

\cs_new<restrictions>:Nn

donde puede estar _protected, _noparo _protected_nopar.

En ambas formas se comprueba que el Nargumento (es decir, un único token) que sigue es una secuencia de control (o carácter activo) que actualmente no está definido yglobalmentedefinir la secuencia de control.

¿Cual es la diferencia? Que la primera familia requiere, después de definir la secuencia de control, un “texto de parámetro” antes de {delimitar el “texto de reemplazo” de la función.

El "texto de parámetro" puede ser cualquier secuencia de tokens, incluido #1, #2y así sucesivamente hasta #9. Sin embargo, para apreciar todo el poder de esta libertad, es necesario familiarizarse con el capítulo 20 del TeXbook y el concepto de "argumento delimitado".

Pero hagámoslo simple. Los dos fragmentos de código siguientes son completamente equivalentes:

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

porque este último proporcionará automáticamente el texto del parámetro #1#2en función de la firma de la función a definir, en este caso :nn.

La firma debe constar de una secuencia (posiblemente vacía) de caracteres ny N.

Tenga en cuenta que los espacios se ignoran cuando \ExplSyntaxOnestá activo, por lo que

\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- }

son todos equivalentes. Podría haber un espacio incluso después #, pero no lo recomendaría.

Las reglas de sintaxis de TeX especifican que cuando se espera un “texto de parámetro” (básicamente, al realizar \defasignaciones o similares y después de haber almacenado el nombre de la macro a definir)todohasta el primero {es parte del texto del parámetro. No hay forma de prever cuál es el texto del parámetro, de ahí el pespecificador de argumento especial que simplemente significa "todo hasta {".

Sólo se puede generar automáticamente texto de parámetro simple como #1, #1#2etc., lo que se hace cuando se utiliza la segunda familia \cs_new<restrictions>:Nn.

¿Dónde te equivocas? Suponiendo que pueda utilizarlo Tcomo especificador en la firma. Los especificadores de argumentos To Fse agregan cuando \prg_new_conditional<restrictions>:Nnnse realiza.

Además, su análisis del texto del parámetro es incorrecto, como se mostró antes.

¿Qué pasa con \cs_set<restrictions>:Npny :Nn? Se aplica todo lo anterior, con la diferencia de que no se verifica que la función a definir esté definida o no y su significado se sobrescribirá silenciosamente, pero el alcance de la declaración coincide con el grupo actual. Normalmente, \cs_set...se utiliza para funciones temporales que necesitan adaptarse al contexto para que su significado no sea fijo.


Las convenciones de nomenclatura para las variables.recomiendaque su nombre comience con l, go c. En realidad, las variables utilizadas en expl3el código deben ajustarse a la convención; Es posible utilizar nombres "normales", como \myTokenListlos de las variables de tipo tl(tal vez también clist) que se utilizarán en el documento.

Las variables que comienzan con lsiempre deben actuar sobre las variables localmente ( \tl_set:Nnpor ejemplo), mientras que las variables que comienzan con gsiempre deben actuar sobre las variables globalmente ( \tl_gset:Nnpor ejemplo).

Las variables que comienzan con csonconstantesy debería sernuncase actúa sobre él después de haberle asignado un valor, pero sólo se utiliza.

Se pueden definir constantes con

\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>}

información relacionada