2013-01-04 26 views
5

sto cercando di creare un sistema di compilazione per knitr/Sweave in Sublime Text 2. Il mio attuale, semplice (e di lavoro) costruire il sistema è il seguente:accedere a un sistema di generazione da un altro sistema di compilazione in Sublime Text 2

{ 
    "cmd": ["bash", "-c", "/usr/bin/R64 CMD Sweave '${file_name}' && pdflatex '${file_base_name}.tex' -interaction=nonstopmode -synctex=1 %S -f -pdf && /Applications/Skim.app/Contents/MacOS/Skim '${file_base_name}.pdf'"], 
    "path": "$PATH:/usr/texbin:/usr/local/bin", 
    "selector": "text.tex.latex.sweave","shell":false, 
    "file_regex": "^(...*?):([0-9]+): ([0-9]*)([^\\.]+)" 
} 

(il text.text.latex.sweave contesto è definito nel bundle Sweave TextMate, che tipo di opere in Sublime Text)

il sistema di compilazione prende un file .Rnw, lo converte in TeX, e quindi corre pdflatex su di esso. Questo sistema di build funziona, ma è piuttosto limitato nel modo in cui apre Skim (apre solo il PDF, tutto qui). Il pacchetto LaTeXTools Sublime Text è molto più robusto e apre/aggiorna Skim evidenziando le linee modificate e fornendo la ricerca inversa magica di Skim.

Non voglio riscrivere il sistema di build LaTeXTools, specialmente perché fa la maggior parte del sollevamento pesante (e della magia di Skim) con uno script Python separato. Tuttavia, mi piacerebbe davvero poterlo usare per costruire un file TeX generato da Sweave.

Idealmente, mi piacerebbe in qualche modo nidificare un sistema di compilazione-convertire un file .Rnw in TeX e quindi eseguire immediatamente il sistema di build LaTeXTools già esistente. In pseudocodice:

{ 
    [CONVERT RNW TO ${file_name}.tex && RUN THE LATEXTOOLS BUILD SYSTEM ON ${file_name}.tex] 
} 

E 'possibile accedere ad un sistema di generazione da all'interno di un altro sistema di compilazione (o, in alternativa, accedere ad un sistema di generazione da bash)?

+0

almeno la parte di ricerca inversa potrebbe essere difficile, ed è qui che RStudio ha messo una buona quantità di sforzi per farlo funzionare; per la parte 'knitr', forse questo funziona:' "cmd": ["Rscript", "-e", "knitr :: knit ('$ {file_name}')"] 'e il resto del lavoro è tuo domanda: come chiamare LaTeXTools? Non uso Sublime Text, quindi non so ... –

+0

Sì, sto cercando di allontanarmi da RStudio (tanto quanto lo adoro), poiché Sublime Text è un editor di qualità superiore. Ho anche una definizione della lingua e un sistema di compilazione per knitr, ma ha lo stesso problema: come posso costruire il file TeX compilato (realizzato da Sweave o knitr) usando il sistema di build più robusto di LaTeXTools? – Andrew

+0

Vorrei [amore] (https://github.com/yihui/knitr/issues/449) per conoscere anche una soluzione :) –

risposta

4

Questa è una patch a due file nel plugin LatexTools per gestire i file Rnw e una patch al plug-in Latex per fare in modo che i file Rnw si comportino come file LaTeX.

prima la patch per il plug-in lattice, in particolare al file LaTeX.tmLanguage:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
<plist version="1.0"> 
<dict> 
    <key>fileTypes</key> 
    <array> 
     <string>tex</string> 
     <string>Rnw</string> 
    </array> 

osservare come ho aggiunto un elemento alla matrice al fine di affrontare con le estensioni RNW.

Ora la patch per makePDF.py

sguardo per la linea aa come questo

if self.tex_ext.upper() != ".TEX": 
    sublime.error_message("%s is not a TeX source file: cannot compile." % (os.path.basename(view.file_name()),)) 
    return 

e sostituirlo con

if (self.tex_ext.upper() != ".TEX") and (self.tex_ext.upper() != ".RNW"): 
    sublime.error_message("%s is not a TeX or Rnw source file: cannot compile." % (os.path.basename(view.file_name()),)) 
    return 

Quindi cercare una linea come

os.chdir(tex_dir) 
CmdThread(self).start() 
print threading.active_count() 

e sostituire con

os.chdir(tex_dir) 
if self.tex_ext.upper() == ".RNW": 
    # Run Rscript -e "library(knitr); knit('" + self.file_name + "')" 
    os.system("Rscript -e \"library(knitr); knit('"+ self.file_name +"')\"") 
    self.file_name = self.tex_base + ".tex" 
    self.tex_ext = ".tex" 
CmdThread(self).start() 
print threading.active_count() 

L'ultima patch è al file jumpToPDF.py

look per una linea

if texExt.upper() != ".TEX": 
    sublime.error_message("%s is not a TeX source file: cannot jump." % (os.path.basename(view.fileName()),)) 
    return 

e sostituirlo con

if (texExt.upper() != ".TEX") and (texExt.upper() != ".RNW"): 
    sublime.error_message("%s is not a TeX or Rnw source file: cannot jump." % (os.path.basename(view.fileName()),)) 
    return 

Buona fortuna!

+0

Santo schifo! Questo è perfetto! Grazie! – Andrew

+0

Ti spiace se pulisco un po 'questo (cioè combino con la mia definizione del linguaggio knitr, ecc.) E lo invio come richiesta pull al repository LaTeX Tools? – Andrew

+0

Niente affatto, ho un'altra aggiunta per far sì che la sintassi sia evidenziata e riconosciuta. –

1

Grazie per la descrizione dettagliata delle modifiche richieste Herberto!

Ho appena proseguito e ho cambiato i file menzionati. Tutto funziona come un fascino! Una cosa è però, non sono sicuro se è necessario, ma ho ricompilato entrambi i file python in .pyc dopo averli modificati.

python -m py_compile makePDF.py 

fa il lavoro. Se qualcuno incorrere in un "errore di sintassi non valida" nella riga di

print threading.active_count() 

mentre la ricompilazione, basta sostituirlo con:

print(threading.active_count()) 

Inoltre, dato che il parser registro di LaTeXTools visualizza solo gli errori dai file di log , potremmo essere interessati a vedere anche l'output di knitr. È possibile memorizzare in un file di registro separato sostituendo:

os.system("Rscript -e \"library(knitr); knit('"+ self.file_name +"')\"") 

con:

knitcmd = "/usr/bin/Rscript -e \"library(knitr); knit('"+ self.file_name +"')\"" 
    process = subprocess.Popen(knitcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 
    #Launch the shell command: 
    knit_output, knit_error = process.communicate() 
    #store results in a log 
    knit_log = open(self.tex_base + "_knitrbuild.log", "w") 
    knit_log.write(knit_output) 
    knit_log.write(knit_error) 
    knit_log.close() 

Prima usavo un semplice script bash per costruire i documenti (Mac specifico):

#!/bin/bash 
[ $# -eq 0 ] && { echo "Usage: $0 file.Rnw for knitting"; exit 1; } 
rnw="library(knitr);knit("\'"$1.Rnw"\'")" 
echo "Rscript executing:" $rnw 
tex="$1.tex" 
pdf="$1.pdf" 
Rscript -e $rnw && pdflatex $tex && pdflatex $tex && open -a Preview $pdf 

retval=$? 
[ $retval -eq 0 ] && echo "$rnw knitted and $pdf ready" 

ma essere in grado di personalizzare LaTeXTools ed eseguirlo direttamente da ST2 con il supporto di Skim è molto bello.

Ci sono motivi per cui non si desidera aggiungere le modifiche che sono state evidenziate direttamente nella sorgente del pacchetto? (forse è solo la mia versione che è troppo vecchia.)

+0

Non riesco a inserire le modifiche direttamente nel pacchetto ST perché trattano tutti con il pacchetto LaTeXTools, di cui non ho alcun controllo. Nel [pacchetto ST reale] (https://github.com/andrewheiss/SublimeKnitr) spiego il processo di patching manuale (per ST 2 e 3, ora). Inoltre, puoi usare un nuovo pacchetto chiamato [latexing] (http://www.latexing.com/) che ha il supporto integrato per knitr e Skim. – Andrew

+0

Oh, e ST dovrebbe compilare automaticamente i file su '.pyc'. – Andrew

Problemi correlati