Re: [C++] Da $ a \(

Messaggioda apatriarca » 29/08/2022, 11:02

Alcuni commenti:
  • Non è possibile modificare una stringa con un'altra più lunga "in-place". È quindi sempre necessario avere un input e output separati in operazioni come queste.
  • Le classi stringa sono raramente ottimizzate per operazioni come questa. In C++ sarebbe meglio fare uso di stringstream. In Python esistono classi simili come StringIO.
  • Se si desidera che questo strumento funzioni correttamente è necessario considerare alcune situazioni particolari. Prima di tutto se il dollaro è preceduto da '\' allora va ignorato. TeX supporta poi anche '\$\$' per indicare una formula in una riga indipendente. Scopro ora che in realtà non è ufficialmente supportato in LaTeX ma ho l'impressione abbia sempre funzionato lo stesso. Almeno in teoria è poi necessario assicurarsi che il paragrafo non finisca all'interno dell'ambiente matematico perché indicherebbe un file LaTeX non corretto. Ovviamente non ha importanza se si tratta di un esercizio.

In Python puoi scrivere qualcosa del genere (non l'ho testato):
Codice:
from io import StringIO

def latex2e_fy(s):
    output = StringIO()
    met_dollar = False

    # Iterate over the string an write the desired output to the StringIO object
    for c in s:
        if c != '$':
            output.write(c)
        else:
            output.write(r'\)' if met_dollar else r'\(')
            met_dollar = not met_dollar

    if met_dollar:
        # There is an odd number of dollars
        # You may want to handle an invalid input differently but I am lazy here
        return None

    result = output.getvalue()
    output.close()
    return result

Puoi scrivere anche meno codice di così (usando accumulate/reduce e join per esempio) ma ho cercato di renderlo leggibile. In C++ il codice sarebbe abbastanza simile.
apatriarca
Moderatore
Moderatore
 
Messaggio: 5686 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [C++] Da $ a \(

Messaggioda kaspar » 29/08/2022, 12:02

Testo nascosto, perché contrassegnato dall'autore come fuori tema. Fai click in quest'area per vederlo.
Era stato menzionato Haskell. La cosa bella è che non hai bisogno di espressioni regolari o librerie assurde; ad esempio:
Codice:
-- L'uso è lo stesso dello script Perl sopra...

main :: IO ()
main = interact change_delims

change_delims :: String -> String
change_delims = helper '('
  where
    helper :: Char -> String -> String
    helper c ('\\':'$':str) = '\\':'$':helper c str
    helper c ('$':str) =
      (\d -> '\\':c:helper d str)
        (if c == '(' then ')' else '(')
    helper c (s:ss) = s:helper c ss
    helper _ "" = ""

Probabilmente la cosa si può ottimizzare considerando ByteString... ma già va bene.

Come lo script in Perl sopra, pensa a non trattare il dollaro escappato, cioè \$.
kaspar
Junior Member
Junior Member
 
Messaggio: 255 di 495
Iscritto il: 17/11/2019, 09:58

Re: [C++] Da $ a \(

Messaggioda kaspar » 15/01/2023, 18:09

Non so se la cosa interessa ancora, o se tu usi *nix.
Codice:
$ perl -i.bak -lpe 's/\$([^\$]+)\$/\\($1\\)/g' hello.tex

È una soluzione molto breve ma funzionante se non hai dollari pendenti sul tuo sorgente TeX né dollari escappati. (La soluzione in Perl che ho dato prima non si scrive in una riga, ma almeno si cura di questi due aspetti.) Per sicurezza viene creata una copia di backup con estensione ".bak"

Esempio:
Codice:
$ cat <<"EOF" > hello.tex
A formula: $E = mc^2$. Some text. Another formula $a^2 + b^2 = c^2$.
Yet another formula $\lambda x . x$. Blah blah blah...
EOF

$ perl -i.bak -lpe 's/\$([^\$]+)\$/\\($1\\)/g' hello.tex

$ cat hello.tex
A formula: \(E = mc^2\). Some text. Another formula \(a^2 + b^2 = c^2\).
Yet another formula \(\lambda x . x\). Blah blah blah...


Vedi questa documentazione di Perl.
kaspar
Junior Member
Junior Member
 
Messaggio: 270 di 495
Iscritto il: 17/11/2019, 09:58

Precedente

Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite