Newsgroup: it.comp.software.tex
Titolo: Comandi senza backslash

Mentre mi arrovellavo per ottenere quello che segue, il mitico Oblomov
proponeva la sua soluzione. Ora la provo, intanto vi propongo cio' che ho
fatto...
Quello che segue e' il tentativo (non completamente riuscito)  di usare i
comand i TeX senza usare \ in modalita' matematica. Ossia scrivere
$int {1 over x} dx= c$ e ottenere
$\int {1 \over x} dx =c$
L'idea e' rendere attivo ogni carattere, associarli una macro che legge la
parola successiva, se e' un comando lo esegue, altrimenti lo scrive cosi'
come e'.
Questo e' il codice
\catcode`\@=11%rende @ usabile come nome
\newif\ifnomacro %flag che decide quando attivare l'espansione
\nomacrofalse %l'espanzione e' attiva
\def\pickup#1@#2#3 {%prende un carattere non attivo e una parola
\def\pre{#2}%assegna il prefisso
\def\word{#3}%assegna il resto senza spazio
\def\words{#3 }%assegna il resto con  spazio
\def\mc{#1}%assegna il carattere non attivo
\ifnomacro %se non e' attivo
  \mc\word %scrivi il carattere non attivo-
\else %altrimenti
  \expandafter\ifx\csname\pre\word\endcsname\relax%controlla se e' un comando
  \nomacrotrue \mc\words \nomacrofalse%se non lo e' riscrivi la parola
% dissattivando momentaneamente l'espansione
  \else  \csname\pre\word\endcsname \fi%altrimenti esegui il comando-
\fi }
Questa macro va associata ad ogni lettera da rendere attiva.
Per ora mi limito alla s
\mathchardef\letteras=\mathcode`s%crea la s non attiva
\def\@@#1 {\pickup \letteras @s#1 }%particolarizza per s \pickup
\let\@@@=\def %quando tutti i caratteri sono attivi serve un alias
\mathcode`\s="8000 %rende attivo in math
\def\attiva{\catcode`\s=13}%attiva s
\def\@@@@@@{\catcode`\s=11}%disattiva-
\attiva
\@@@ s{\@@}%associa ad s attivo la macro particolarizzata
\@@@@@@%disattiva s
\catcode`\@=12
Ecco qualche prova
\def\ss{prova}
$$ sum a star ss $$-
$$ susn $$-
I problemi sono diversi. Innanzitutto rendere il codice piu' leggero ed
elegante. Migliorare la gestione degli spazi che va in conflitto con alcuni
i comandi con argomenti. Infine una buona fase di testing perche' sono sicuro
di tutto tranne che funzioni :-)!
Cosa ne pensate? Avete qualche idea per correggere il tiro?
Riccardo
\end

 come e'.
[SNIP]
Ma ti dà tanto fastidio usare `\'?
Credo che, come passatempo, il tuo esercizio sia utile. Che abbia
una utilità pratica, dubito.
Per esempio, dovresti stare attento che non esistano comandi
il cui nome contiene come tratto iniziale quello di un'altro
comando; esempio: \subset e \subseteq.
Altrimenti devi abituarti a delimitare i comandi `in fondo',
magari con uno spazio (con tutti i problemi che questo dà) oppure,
diciamo con `/'. E a questo punto, che cosa hai ottenuto?
Niente, invece di avere `\' all'inizio, hai messo un delimitatore
alla fine.
Ciao
Enrico

 \@@@@@@%disattiva s
Quando userai la macro per più lettere, scoprira che usare \@@@s{\@@} 
manderà tutto a quel paese perché \@@ sarà ridefinito per l'ultima 
lettera definita. Meglio allora :
\let\@@@\let
e poi
\@@@s\@@
. Il problema con gli spazi potrebbe essere risolto dalla versione di 
costruzione della catena da me proposta; più in generale, invece di 
far sì che pickup prenda subito il token successivo, lascia che il 
token successivo vegna assegnato ad una macro prefissata 
(\prossimotoken):
\def\@@{\afterassignment\usaprossimotoken\let\prossimotoken= }
Nota lo spazio dopo l'=: assicura che il prossimo token NON venga 
saltato anche se è uno spazio. Dopodicché definisci \usaprossimotoken 
come vuoi. Nel tuo caso potresti quindi cambiare \pickup in modo che 
legga due e non tre parametri, (usando \prossimotoken invece #3) e 
definisci:
\def\@@{\afterassignment\pickup\afterassignment\letteras%
        \afterassignment @\afterassignment s%
        \let\prossimotoken= }
-- 
Giuseppe "Oblomov" Bilotta
Axiom I of the Giuseppe Bilotta
theory of IT:
Anything is better than MS

`/'.
Perche'?
Ciao
Riccardo

 
Non riesco a farlo funzionare, va in loop sulla lettera s e non procede.
Inoltre ho problemi a creare la catena. Il primo problema dovrebbe dipendere
dal fatto che invece di assegnare s a pickup come carattere non attivo espande
la macro. Non capisco come mai questo avvenga perche' al tempo della defizione
di @@ s non e' attiva.
\catcode`\@=11%rende @ usabile come nome
\newif\ifnomacro %flag che decide quando attivare l'espansione
\nomacrofalse %l'espanzione e' attiva
\newtoks\catena %crea un registro
\def\assegnaacatena{% non riesco a definirla cosi' credo sia sbagliata
\ifcat a\prossimotoken
\catena\expandafter\expandafter\expandafter{\expandafter\catena\prossimotoken}%
\assegnaacatena \fi
}
\def\pickup#1#2{%prende un carattere non attivo e l'iniziale di una parola
\def\pre{#2}%assegna il prefisso
%dovrebbre esserci una macro che legge e mette in catena e poi associ a \word
%\the\catena
\def\word{\prossimotoken}%facciamo conto che ci basti la lettera
%successiva-
\def\mc{#1}%assegna il carattere non attivo
\ifnomacro %se non e' attivo
  \mc\word %scrivi il carattere non attivo
\else %altrimenti
  \expandafter\ifx\csname\pre\word\endcsname\relax%controlla se e' un comando
    \nomacrotrue \mc\word \nomacrofalse%se non lo e' riscrivi la parola
% dissattivando momentaneamente l'espansione
  \else  \csname\pre\word\endcsname \fi%altrimenti esegui il comando-
\fi }
\mathchardef\letteras=\mathcode`s%crea la s non attiva
\def\@@{\afterassignment\pickup\letteras\afterassignment s
\let\prossimotoken= }%ho tolto da qui @ e dalla definizione di pickup
%credo sia superfluo
\let\@@@\let %quando tutti i caratteri sono attivi serve un alias
\mathcode`\s="8000 %rende attivo in math
\def\attiva{\catcode`\s=13}%attiva s
\def\@@@@@@{\catcode`\s=11}%disattiva-
\attiva
\@@@ s\@@%associa ad s attivo la macro particolarizzata
\@@@@@@%disattiva s
\catcode`\@=12
Ecco qualche prova
$$ sum $$
\end

 costruzione della catena da me proposta;
Forse ho risolto il problema, sarebbe causato dal fatto che il comando
viene eseguito tra due if, quindi se ha argomenti, questi associati agli
if successivi. Ho risolto facendo eseguire il comando se esite per
ultimo:
\ifnomacro 
  \mc\words 
\else 
  \expandafter\ifx\csname\pre\word\endcsname\relax
    \let\go=\relax  
    \nomacrotrue \mc\words \nomacrofalse
  \else 
    \expandafter\let\expandafter\go\csname\pre\word\endcsname 
  \fi
\fi \go}
Ora sembra funzionare

 Funziona, ma \let non aveva bisogno di = ?
No. È comodo NON metterlo per risparmiare spazio e tokens; ci sono 
però alcune circostanze in cui è necessario usarlo (ad esempio nel 
trucchetto \let\prossimotoken=  con lo spazio dopo: se non metti 
l'uguale, lo spazio viene mangiato comunque.
Ok, ecco del codice funzionante. ATTENZIONE: per funzionare 
correttamente TUTTI i caratteri alfabetici devono essere definiti 
attivi in mathmode!
\catcode`\@=11%rende @ usabile come nome
\newtoks\catena %crea un registro
\def\usaprossimotoken#1{%
    \catena\expandafter{\the\catena#1}%
    \ifcat a\prossimotoken%
       \expandafter\prossimotoken%
    \else\expandafter\eseguicatena\expandafter\prossimotoken\fi}
\def\eseguicatena{
    \message{Esecuzione della catena \the\catena}%
    \expandafter\ifx\csname\the\catena\endcsname\relax%
       \message{Attenzione: \the\catena non definito!}
       \mathop{\hbox{\the\catena}}%
    \else%
      \expandafter\csname\the\catena\endcsname%
      \catena{}%
    \fi%
}
\let\@@@\let %quando tutti i caratteri sono attivi serve un alias
\def\@@{\afterassignment\controllaletteras%
\let\prossimotoken= }
\def\controllaletteras{\usaprossimotoken s}
\mathcode`\s="8000 %rende attivo in math
\def\attiva{\catcode`\s=13}%attiva s
\def\@@@@@@{\catcode`\s=11}%disattiva-
\attiva\relax
\@@@s\@@%associa ad s attivo la macro particolarizzata
\@@@@@@%disattiva s
\def\@@{\afterassignment\controllaletterau%
\let\prossimotoken= }
\def\controllaletterau{\usaprossimotoken u}
\mathcode`\u="8000 %rende attivo in math
\def\attiva{\catcode`\u=13}%attiva u
\def\@@@@@@{\catcode`\u=11}%disattiva-
\attiva\relax
\@@@u\@@%associa ad u attivo la macro particolarizzata
\@@@@@@%disattiva u
\def\@@{\afterassignment\controllaletteram%
\let\prossimotoken= }
\def\controllaletteram{\usaprossimotoken m}
\mathcode`\m="8000 %rende attivo in math
\def\attiva{\catcode`\m=13}%attiva u
\def\@@@@@@{\catcode`\m=11}%disattiva-
\attiva\relax
\@@@m\@@%associa ad u attivo la macro particolarizzata
\@@@@@@%disattiva u
\catcode`\@=12
%\tracingall
Ecco qualche prova
$$ sum_{mus}^{smu} $$
\end


 in mathmode!
 
Sei un grande!
Rimangono pero' dei problemi. Il primo e' facile e riguarda il fatto che
se un comando ha argomenenti, la prima cosa che vede e' \fi. Ho risolto
rimandando l'esecutione di \the\catena alla fine.
def\eseguicatena{
      \message{Esecuzione della catena \the\catena}%
      \expandafter\ifx\csname\the\catena\endcsname\relax%
        \message{Attenzione: \the\catena non definito!}
        \mathop{\hbox{\the\catena}}%
        \let\go=\relax 
      \else%
        \let\go\expandafter\csname\the\catena\endcsname%
        \catena{}%
      \fi%-
     \go% 
}
Il secondo problema riguarda il fatto che mi perdo il carattere
matematico associato alle lettere. Per risolverlo volevo provare come
nella mia versione, cioe' disabilitare e riabilitare l'espansione
In pratica dopo aver definito 
\mathchardef\letteras=\mathcode`s
e \newif\ifnomacro \nomacrofalse
piazzare da qualche parte
\ifnomacro \letteras
\else ...
\fi
Il problema e' che non saprei dove piazzarlo ora. Essendo la catena fatta
di caratteri attivi, non posso metterlo alla fine come avevo fatto in
precedenza, quindi va posto all'inizio, ma se lo metto qui:
\mathchardef\letteras=\mathcode`s
\def\@@{\ifnomacro \letteras
\else
\afterassignment\controllaletteras%
\let\prossimotoken= \relax\fi}
Qualcosa si rompe, inoltre l'espansione che nella mia versione funzionava
\nomacrotrue \the\catena \nomacrofalse
ora stranamente non funziona piu' andando in loop
Il terzo problema e' un comportamento curioso che si ha con \vec.
Guarda cosa accade con
\def\sss{\vec{m}}
$$sss$$ 
Il quarto problema e' che sei una forza della natura :-)
Riccardo

 $$sss$$ 
Fammi sapere se ci sono ulteriori punti da discutere.


 dovrebbe risolvere anche il terzo problema (credo):
Se tolgo il mathop, ma soprattutto il \hbox entra in loop in quanto 
la catena contiene lettere che vengono espanse in quanto siamo in mmode 
e quindi si ricomincia. Il motivo per cui ho messo il flag no macro serve
proprio a permettere al contenuto della catena a non espandere generando
un carattere non attivo. In teoria si potrebbe mettere un \hbox{\it ...}
se si tratta di una sola lettera, ma \vec si offende credo perche' trova
un box e non un carattere matematico.
Riccardo

 e quindi si ricomincia.
Giusto. Fai allora due macro:
\disattivacaratteri
che porta tutti i \mathcode delle lettere al loro stato originale 
("7100 + valore hex della lettera) ed una
\attivacaratteri
che porta tutti i \mathcode delle lettere ad "8000. Dopodicché 
sostiuisci \mathop{\hbox{\the\catena}} con 
\distattivacaratteri\the\catena\attivacaratteri.


 \distattivacaratteri\the\catena\attivacaratteri.
 
Trovo questa soluzione poco efficiente, preferisco cambiare due flag 
come in 
 \nomacrotrue \the\catena \nomacrofalse
Ho pensato un modo in cui cambiare \@@ per adattarla alla nuova 
situazione e sembra funzionare 
\def\procedi{\afterassignment\controllaletteras\let\prossimotoken= }
e' la vecchia \@@
\def\@@{
\ifnomacro\letteras \let\vai\relax \else
\let\vai\procedi\fi\vai}
In questo modo se \nomacrofalse \@@ dovrebbe essere proprio come \@@
vecchia e quindi non cambiare niente.
Il problema dei comandi con argomenti continua ad esserci. Ho cambiato 
\esegicatena usando \edef
\def\eseguicatena{
      \message{Esecuzione della catena \the\catena}%
      \expandafter\ifx\csname\the\catena\endcsname\relax%controlla se
%la catena contiene un comando
        \message{Attenzione: \the\catena non definito!}
        \nomacrotrue \the\catena \nomacrofalse% disattiva momentaneamente
%l'espansione per eseguire la catena come sequenza di lettere
        \let\go=\relax %non esegue comandi alla fine
      \else%
        \edef\go{\noexpand\csname\the\catena\endcsname}%associa a \go
%il comando, tuttavia se il comando ha argomenti il primo viene
%associato a \prossimotoken
        \catena{}% \svuota la catena
      \fi%-
     \go% \esegue il comando o \relax
}
In questo modo \go contiene {\csname comando\endcsname} tuttavia il
prossimo token e' \prossimotoken che ha dentro uno spazio o nulla
\def\usaprossimotoken#1{%
    \catena\expandafter{\the\catena#1}%
    \ifcat a\prossimotoken%
       \expandafter\prossimotoken%
    \else\expandafter\eseguicatena\expandafter\prossimotoken\fi}
Non ho idea di come spostare alla fine di \@@ in definitiva il comando
da eseguire
Riccardo

Riccardo de Maria continua a "rompere" ;-) quindi diamo la risposta 
definitiva.
ATTENZIONE: Come sempre quando si usano caratteri attivi, bisogna ora 
mettere le lettere tra graffe quando le si usa come argomento di un 
comando!!!
\catcode`\@=11%rende @ usabile come nome
\newtoks\catena %crea un registro per la catena
\newtoks\ordcatena %ed uno per la catena di mathord
\def\usaprossimotoken#1#2{%
  \catena\expandafter{\the\catena#1}%
  \ordcatena\expandafter\expandafter\expandafter%
    {\expandafter\the\expandafter\ordcatena\expandafter\mathchar#2}%
    \ifcat a\prossimotoken%
       \expandafter\prossimotoken%
    \else\expandafter\eseguicatena\expandafter\prossimotoken\fi}
\def\eseguicatena{
  \message{\space Esecuzione della catena \the\catena\space}%
  \expandafter\ifx\csname\the\catena\endcsname\relax%
     \message{\space Attenzione: \the\catena\space
                     non definito!\space}%
     \the\ordcatena%
     \catena{}%
     \ordcatena{}%
     \let\go=\relax 
  \else%
     \expandafter\let\expandafter\go\csname\the\catena\endcsname%
     \catena{}%
     \ordcatena{}%
  \fi%
  \go% 
}
\let\@@@\let %quando tutti i caratteri sono attivi serve un alias
\let\prossimotoken\relax
\def\mattiva#1{%
  \expandafter\edef\csname c@ntr@ll@#1\endcsname{%
      \noexpand\usaprossimotoken#1{\the\mathcode`#1}%
  }%
  \edef\@@{\noexpand\afterassignment%
    \expandafter\noexpand\csname c@ntr@ll@#1\endcsname%
    \noexpand\let\noexpand\prossimotoken= % lo spazio \`e importante!
  }
  \def\attiva{\catcode`#1=13}%
  \def\@@@@@@{\catcode`#1=11}%
  \attiva\relax
  \faiaux
}
\def\faiaux#1{%
    \@@@#1\@@
    \@@@@@@
    \mathcode`#1="8000\relax
}
% Due palle di tabelle per attivare tutti
% i caratteri ...
\mattiva A A
\mattiva B B
\mattiva C C
\mattiva D D
\mattiva E E
\mattiva F F
\mattiva G G
\mattiva H H
\mattiva I I
\mattiva J J
\mattiva K K
\mattiva L L
\mattiva M M
\mattiva N N
\mattiva O O
\mattiva P P
\mattiva Q Q
\mattiva R R
\mattiva S S
\mattiva T T
\mattiva U U
\mattiva V V
\mattiva W W
\mattiva X X
\mattiva Y Y
\mattiva Z Z
\mattiva a a
\mattiva b b
\mattiva c c
\mattiva d d
\mattiva e e
\mattiva f f
\mattiva g g
\mattiva h h
\mattiva i i
\mattiva j j
\mattiva k k
\mattiva l l
\mattiva m m
\mattiva n n
\mattiva o o
\mattiva p p
\mattiva q q
\mattiva r r
\mattiva s s
\mattiva t t
\mattiva u u
\mattiva v v
\mattiva w w
\mattiva x x
\mattiva y y
\mattiva z z
Ed ecco qualche prova
$$ sum_{m}^{s} vec{g} $$
\end


 % Due palle di tabelle per attivare tutti % i caratteri ...
Va bene che sono scarso, ma questa tortura potevi lasciarla a me :-)
Grazie di tutto, non sarei riuscito ad imparare cosi' tanto senza il tuo
aiuto.
Riccardo

 Va bene che sono scarso, ma questa tortura potevi lasciarla a me :-)
Perché? Con VIM si fanno in quattro e quattr'otto.


 > Ma ti dà tanto fastidio usare `\'?

Rispondo solo oggi, sono stato a Praga e preferivo visitare la città
e bermi una sana birra (dopo aver lavorato, si intende :-) che leggere
il newsgroup.
"int" si usa spesso parlando di serie di Fourier, ad esempio.
Scrivere e^{i n t} mi parrebbe veramente orribile.
E poi, come risolvi il fatto che "i" è il nome di un comando?
E che "t" pure lo è, e di quelli complicati che hanno a che fare
con le codifiche dei caratteri (OT1,T1, eccetera).
Non potremmo più usare comandi di una sola lettera, se non definendoli
in modo diverso nel caso si voglia usare la lettera in modo matematico.
Ripeto, se lo prendi come esercizio, affari tuoi. Che possa essere
utile, lo nego recisamente! Che differenza vedi fra Hv e \Hv?
Anzi, basta abituarsi ad usare TeX e le formule le vedi direttamente.
Un utente esperto usa cose come:
\newcommand{\myvec}[1]{\vec{#1}}
\newcommand{\vH}{\myvec{H}}
In questo modo, se poi decide che i vettori gli piacciono di più
scritti in nero, basta che cambi una riga. Naturalmente, se usa un solo
vettore in tutto l'articolo, scrive quella volta \vec{H} e pace.
Ciao
Enrico