2010-04-28 29 views
9

Para introducir un poco de diálogo utilizando el paquete screenplay, tengo que usarcomando personalizado para ' begin {entorno} ... end {entorno}'

\begin{dialogue}{Johnny} Some dialogue. \end{dialogue} 
\begin{dialogue}{Jane} I see. \end{dialogue} 

Se vuelve un poco tedioso después de una mientras. ¿Es posible especificar un comando personalizado para que pueda usar algo como

\dialogue{Johnny} Some dialogue. 
\dialogue{Jane} I see. 

en su lugar?

+0

dependiendo del editor que use, es posible que también desee buscar en un paquete de fragmentos de código. – Mica

+0

+1 Esta es una pregunta realmente interesante – Geoff

Respuesta

8

Prueba esto:

\newcommand{\dialogueline}[2]{\begin{dialogue}{#1} #2 \end{dialogue}} 

% Usage example: 
\dialogueline{Johnny}{Some dialogue.} 
\dialogueline{Jane}{I see.} 
+0

Eso funciona perfectamente. ¡Muchas gracias! – njt

+1

Esta es una buena respuesta, pero si alguien sabe cómo replicar el formato exacto solicitado por el póster original, sería agradable de ver. – Geoff

+1

Creo que es lo más cercano que se puede llegar a lo que el afiche quiere. Tiene que haber llaves alrededor del texto, así que LaTeX sabe dónde poner '\ begin {dialogue}' y '\ end {dialogue}' correctamente. Además, utilicé '\ dialogueline' en caso de que ya haya otro comando llamado' \ dialogue', pero si ese no es el caso, entonces el póster puede reemplazar '\ dialogueline' con' \ dialogue' en su lugar si no causa errores. –

12

Puede, de hecho, conseguir exactamente lo que quiere:

\newcommand{\dialogueline}{\begingroup\catcode`\^^M=12 \[email protected]} 
{\catcode`\^^M=12\gdef\[email protected]#1#2^^M{\begin{dialogue}{#1}#2\end{dialogue}\endgroup}} 

Este código tiene que ser \makeatletter-protected — ya sea rodeado de \makeatletter/\makeatother (edición: este significa que pone \makeatletter antes de la definición, y \makeatother después de ella), o en un archivo .sty. Tenga en cuenta que un entorno denominado dialogue define un comando llamado \dialogue, por lo que necesita un nombre diferente. ¡No cambie el formato!

La forma en que funciona es que \dialogueline es un comando que no toma argumentos, sino que se expande a múltiples secuencias. Primero, un token de apertura de grupo, para poner lo que sigue en su propio alcance. En segundo lugar, la secuencia \catcode`^^M=12. LaTeX asigna a cada letra un catcode: un número que dice de qué tipo es. Por ejemplo, la barra diagonal inversa es catcode 0, el constructor del nombre de comando; las letras son catcode 11; y los caracteres de impresión que no son letras, como el signo at, son catcode 12. Esta secuencia hace ^^M, el carácter de nueva línea, tiene catcode 12, por lo que podemos interactuar con él. Finalmente, escribimos el comando \[email protected], que hace el trabajo pesado.

A continuación, definimos \[email protected]. Lo hacemos dentro de un grupo donde el carácter de nueva línea es catcode 12, tal como será donde se expande \dialogueline. Tenga en cuenta que esta es la razón por la que no puede dividir la segunda línea con una nueva línea — que se interpretaría como texto. Luego, definimos \[email protected] para tomar dos argumentos, finalizando con una nueva línea; se expande tomando el primer argumento (que pasa entre llaves) y pasándolo como un argumento al entorno dialogue, y pasando el segundo argumento (todo después del primero y antes del final de la línea) como el cuerpo del entorno. Finalmente, \[email protected] finaliza el grupo abierto en \dialogueline, por lo que el cambio al código de cat de ^^M no está visible en ningún otro lado. Dado esto, puede escribir

\dialogueline{Johnny} Some dialogue. 
\dialogueline{Jane} I see. 

y todo debería funcionar.

+0

¡Muy buena respuesta! (+1) – topskip

+1

Eso es bastante inteligente. Hasta ahora no sabía nada de '\ catcode'. Si bien mi solución funcionará para cualquier cosa que se coloque entre llaves, la suya funcionará para frases sencillas y está más cerca de la sintaxis solicitada por el solicitante. –

+0

El truco es en realidad menos acerca de los códigos catcodes y más sobre la coincidencia de patrones en '\ def': también puedes hacer algo como' \ gdef \ dialogueline @ EOL # 1: # 2 ^^ M' para poder escribir '\ dialogueline Johnny: Un poco de diálogo. El interruptor de catcode es para que el final de una línea no solo se trate como un carácter de espacio y se ignore, sino que se trate como un carácter compatible. Tienes razón en que esto puede prohibir algunas cadenas válidas (aunque algunas pueden permitirse ocultando la cadena correspondiente con llaves, por ejemplo, '\ dialogueline {Alexander: the Great}: Die!'), Pero es bueno para los atajos y DSL incorporados. –

3

Si se supone que cada diálogo ocupa un párrafo (por lo general, comienza y termina con un salto de párrafo de línea doble), entonces no hay otra manera de tener \dialogue poner un solo argumento:

 
\newif\indialog \indialogfalse 
\def\dialogue#1{\ifindialog \end{dialogue}#1\begin{dialog}\else 
       \everypar={\end{dialogue}\indialogfalse \everypar={}}#1\indialogtrue\begin{dialogue} 
       \fi} 

Eso el código es algo sucio y no-Latexy — establece \everypar sin importar su contenido existente — y Latex tiene abstracciones más limpias para hacerlo, que he olvidado, pero el principio debe ser claro.

+0

Eso es inteligente, no había visto esta técnica antes. –

Cuestiones relacionadas