LuaTeX e \endlinechar

  • Creatore
    Topic
  • #112037
    robitex
    Amministratore del forum
      Up
      0
      Down
      ::


      Ciao.
      Vi sottopongo alcune domande su questo codice:
      `% !TeX program = LuaTeX

      w%
      \begingroup
      \endlinechar=10\relax\directlua{%
      local s = [[
      1

      2

      3
      4
      5

      ]]
      print[[ciao]]

      local t = 0
      for line in string.gmatch(s, [[(.-)]]..string.char(10)) do
      t = t+1
      print(line)
      end
      print(t)
      print[[ciao]]
      }\endgroup%
      w

      \bye`

      In console vedrete stampato:
      `This is LuaTeX, Version 1.0.4 (TeX Live 2017/W32TeX)
      restricted system commands enabled.
      (./r.texciao
      1

      2

      3
      4
      5

      8
      ciao
      [1{c:/texlive/2017/texmf-var/fonts/map/pdftex/updmap/pdftex.map}])
      Output written on r.pdf (1 page, 8448 bytes).
      SyncTeX written on r.synctex.gz.
      Transcript written on r.log.
      `

      Lo scopo del codice è poter leggere una stringa all’interno del sorgente e separarla nelle singole linee.
      Il codice funziona, il ciclo for itera correttamente su tutte le linee della stringa s, anche quelle vuote.
      Infatti il contatore vale alla fine 8.
      Senza la correzione dell’endlinechar invece non funziona perché la macro \directlua espande completamente il suo contenuto prima di passarlo a Lua, perciò la stringa s non ha più i caratteri fine riga.

      Come mai funziona solamente con il numero 10?
      R.

    Visualizzazione 3 filoni di risposte
    • Autore
      Risposte
      • #112038
        OldClaudio
        Partecipante
          Up
          0
          Down
          ::


          Perché il carattere numero 10 della tabella ASCII è qualcosa come o o o qualcosa del genere. Non sono sicuro, ma il fine riga è codificato con sulle macchine Linux, con sulle vecchie macchine Mac, ma ora con SO X, sono uniformati con i sistemi UNIX; nele macchine Windows sono caratterizzati dai due caratteri di seguito . Nel processo di tokenizzazione in entrata questi vari fine riga sono trasformati tutti in un unico codice esadecimale, che probabilmente non è il 10 (continuo a tirare ad indovinare); coì quando \directlua manda il testo a Lua togliendo tutti i fine riga, sostituisce con spazi tutti i fine riga individuati dal codice sostitutivo di luatex, ma non sostituisce il carattere 10; ecco quindi il codice lua che conta correttamente le righe.

          Naturalmente non ho questa visione approfondita; bisognerebbe almeno leggere il libro 5 della Millennium edition del sistema TeX (libro 1: il linguaggio TeX; libro 2: il codice del linguaggio; libro 3: Metafont; libro 4: codice del linguaggio Metafont; Libro 5: l’interprete TeX-the-program fatto di brani di Pascal intercalati con la loro documentazione in linguaggio web. Ci ho provato, ma è troppo difficile per un non-informatico. Forse la cosa è spiegata in modo più comprensibile in TeX by topic; ricordo che c’è scritto qualcosa in merito, ma non me ne ricordo i dettagli.

        • #112039
          robitex
          Amministratore del forum
            Up
            0
            Down
            ::

            OldClaudio” post=112361Perché il carattere numero 10 della tabella ASCII è qualcosa come o o o qualcosa del genere. Non sono sicuro, ma il fine riga è codificato con sulle macchine Linux, con sulle vecchie macchine Mac, ma ora con SO X, sono uniformati con i sistemi UNIX; nele macchine Windows sono caratterizzati dai due caratteri di seguito . Nel processo di tokenizzazione in entrata questi vari fine riga sono trasformati tutti in un unico codice esadecimale, che probabilmente non è il 10 (continuo a tirare ad indovinare); coì quando \directlua manda il testo a Lua togliendo tutti i fine riga, sostituisce con spazi tutti i fine riga individuati dal codice sostitutivo di luatex, ma non sostituisce il carattere 10; ecco quindi il codice lua che conta correttamente le righe.

            Naturalmente non ho questa visione approfondita; bisognerebbe almeno leggere il libro 5 della Millennium edition del sistema TeX (libro 1: il linguaggio TeX; libro 2: il codice del linguaggio; libro 3: Metafont; libro 4: codice del linguaggio Metafont; Libro 5: l’interprete TeX-the-program fatto di brani di Pascal intercalati con la loro documentazione in linguaggio web. Ci ho provato, ma è troppo difficile per un non-informatico. Forse la cosa è spiegata in modo più comprensibile in TeX by topic; ricordo che c’è scritto qualcosa in merito, ma non me ne ricordo i dettagli.

            Ciao Claudio.
            Dopo la tua risposta ho fatto qualche passo avanti.
            Ecco il codice che però non funziona:
            `% !TeX program = LuaLaTeX
            \documentclass{article}

            \long\def\defstring#1{%
            \begingroup
            \endlinechar=10\relax
            \directlua{s = [[#1]]}\endgroup}

            \defstring{1
            2
            3
            4

            5
            6
            7
            8
            }

            \begin{document}

            \directlua{
            tex.print([[\string\begin{verbatim}]])
            local t = 0
            for line in string.gmatch(s, [[(.-)]]..string.char(10)) do
            t = t+1
            tex.print(line)
            end
            print(t)
            print[[ciao]]
            }
            \end{verbatim}
            oo
            \end{document}`

            Dovrebbero venir stampate le linee date come argomento di \defstring.
            Questo perché la stringa multilinea subisce tokenizzazione prima di essere passata come argomento al comando che trova una stringa di una riga soltanto perché i codici di categoria non passano a Lua.

            Idee?
            R.

          • #112040
            robitex
            Amministratore del forum
              Up
              0
              Down
              ::


              Ciao.
              Ho tentato questa macro:
              `\newcommand\sourcecode[1]{%
              \toks255{%
              local from_file = sourcecodelib._from_file;
              local from_lines = sourcecodelib._from_lines;
              local from_string = sourcecodelib._from_string;
              local res =}
              \begingroup
              % catcode corrections
              % endlinechar correction (eventually)
              \toksapp255{#1; res:_typeset()}
              \endgroup
              \edef\x{\the\toks255}
              \directlua{\x}}
              `

              L’idea è questa: espandere l’argomento della macro in un gruppo dove si è preventivamente corretto i codici di categoria per i caratteri spazio graffe eccetera, e per il carattere \n di fine riga.
              Una volta che l’argomento #1 è stato letto nel modo “giusto” da TeX, lo espando nella macro \directlua per eseguire il codice.
              Non funziona.
              Vorrei scrivere una macro che accetti normale codice Lua. Ma non posso inserirlo direttamente in \directlua perché la trasformazione in token altera sia gli spazi, sia il carattere di fine riga.
              Normalmente non è un problema. Questa volta invece si perché il codice Lua deve rimanere come se lo si leggesse in un file perché, verrà elaborato per essere inserito verbatim.

              Così facendo, troverò sotto il codice composto in syntax highlighting, il suo output.
              Un po’ intricato da spiegare…
              R.

            • #112041
              OldClaudio
              Partecipante
                Up
                0
                Down
                ::


                Capisco che tu voglia risolvere il problema con lua, ma quello che vuoi fare, se ho ben capito il tuo problema, lo fa già il pacchetto fancyvrb.
                Tuttavia questo problema dei caratteri spazio e fine riga non dipende né da TeX né da Lua, ma da come è implementato directlua. OK, bisogna imbrogliare directlua;TeX dispone di trucchi vari epr sostituire i caratteri, ma non li userei in questo caso; quello che puoi fare è attribuire charcode e i corrispondenti catcode allo spazio e al fine riga. In questo modo puoi, per esempio, atribuire allo spazio il charcode della tilde a cui associ un catcode 11; al fine riga il charcode delle doppie virgolette diritte e il catcode 11. Ovviamente, quando rileggi devi ritrasformare la tilde e le doppie virgolette nei caratteri originali, prima di comporre verbatim; magari questa operazione la fai fare a lua invece che a tex.
                Forse devi fare queste cose attraverso i comandi \detokenize e \scantokens. Per questi devi leggerti bene la documentazione nel file etex.pdf (texdoc etex); io li ho usati qualche volta, ma non li trovo per niente user friendly e quindi da una vola all’altra mi dimentico come si usano, specialmente le loro sottigliezze che me li rendono difficili da usare bene. anche L3 ha macro apposite per usare questi comandi nativi di etex (nativi da una decina di anni, non nativi del TeX del 1978). Però L3 mi pare ancor più difficile da usare di etex… Colpa mia che non ci arrivo con la testa, tuttavia…

            Visualizzazione 3 filoni di risposte
            • Devi essere connesso per rispondere a questo topic.

            Go to top