Come grep per tutti i pacchetti usati in un file tex

2

Supponendo che voglio grep tutti i pacchetti usati in un file tex:

$ grep usepackage my.tex

farà, con (per quanto posso vedere) un'eccezione: se un pacchetto viene caricato con tante opzioni che l'autore del file ha deciso di inserire interruzioni di riga, come in

\usepackage[option1,
option2,
option3]{thepackage}

Ci sarebbe un modo per dire a grep di continuare ad analizzare il file fino a quando non colpisce } ?

Idealmente otterrei solo il thepackage come output, in modo che io possa eventualmente scorrere su di esso, come ad esempio:

$ for i in 'locate 'my grep command'.sty'
do
grep \\newcommand{\\createstrouble} $i
done

per trovare rapidamente un pacchetto in cui è definito un comando \createstrouble ?

EDIT: Un'ulteriore complicazione: ho un comando \usepackage come segue:

\usepackage[pdftitle={My Title},
 pdfauthor={My Author}]{hyperref}

EDIT: ho capito che questo approccio non funziona per il mio scopo, che era quello di scoprire pacchetti in conflitto. In primo luogo, perché un pacchetto caricato da \usepackage{something} attira più pacchetti attraverso RequirePackage che non si avrà sul proprio radar. Meglio lavorare con il file di log, possibilmente usando \listfiles nel preambolo, producendo un elenco di file caricati e scorrendo attraverso una directory texmf per il nome effettivo del comando usato da diversi pacchetti.

    
posta muk.li 13.08.2015 - 13:05

2 risposte

3

Puoi eseguire partite multilinea in grep normale utilizzando una combinazione di -P (modalità PCRE) e -z flags ad es.

grep -zP '(?s)\usepackage.+?}' file

o con pcregrep

pcregrep -M '(?s)\usepackage.+?}' file

Il modificatore (?s) consente di . di corrispondere a nuove righe.

Per ottenere solo il nome del pacchetto, puoi provare

grep -zPo '(?s)\usepackage.*?{\K.+?(?=})' file

o

pcregrep -Mo '(?s)\usepackage.*?{\K.+?(?=})' file


Provando la semplice espressione di grep su un manoscritto di TeX, ottengo il seguente elenco di pacchetti:

~$ grep -zPo '(?s)\usepackage.*?{\K.+?(?=})' myfile.tex
geometry
changepage
inputenc
textcomp,marvosym
fixltx2e
amsmath,amssymb
cite
nameref,hyperref
lineno
microtype
rotating
setspace
caption
lastpage,fancyhdr,graphicx
epstopdf
    
risposta data steeldriver 13.08.2015 - 13:44
2

Non è semplice scrivere un parser TeX. Pertanto, la seguente soluzione può essere provata solo.

Usando awk due volte e uniq

awk '/usepackage/,/}$/ {gsub(/\/,"\n",$0);printf "%s",$0}' my.tex |\
awk -F{ '{gsub(/}/,"",$NF); if ($NF != "") {print $NF}}' |\
sort -u

Esempio

$ cat foo.tex
\usepackage[pdftitle={My Title},
 pdfauthor={My Author}]{hyperref}
\usepackage{ngerman}
\usepackage[scale=0.85]{geometry}

$ awk '/usepackage/,/}$/ {gsub(/\/,"\n",$0);printf "%s",$0}' foo.tex |\
  awk -F{ '{gsub(/}/,"",$NF); if ($NF != "") {print $NF}}' |\
  sort -u
geometry
hyperref
ngerman
    
risposta data A.B. 13.08.2015 - 14:11

Leggi altre domande sui tag