2010-10-12 37 views
4

J'écris un programme (en C, mais je suppose que ce n'est pas si pertinent) en rapport avec un petit documentaire dans LaTeX. Je veux que le documentaire contienne des extraits de code de mon code original.LaTeX: Lstlisting reconnaissant automatiquement le passage de code

Afin d'inclure le code source et le maintenir à jour, je fais ce qui suit dans mon document:

\lstinputlisting[firstline=200, lastline=210]{../src/source.c) 

Cette charge les lignes 200 à 210 automatiquement (qui contiennent par exemple une fonction) de ../src/source.c en mon document.

Cependant, si j'ajoute quelques lignes avant la ligne 200, cela signifie que la ligne 200 "dérive quelques lignes", donc je dois l'ajuster pour obtenir ma fonction d'origine.

Alors, voici ma question: Quelqu'un sait-il une possibilité de dire dynamiquement lstinputlisting (ou un substitut adéquat) pour dire quelles lignes à prendre?

J'imagine quelque chose comme ceci: J'ajoute des commentaires spéciaux à mon code source C qui seront reconnus par lstinputlisting, par exemple.

/// lstinputlisting "myfunc" BEGIN 
int myFunction(int x){ 
    return x+2; 
} 
/// lstinputlisting "myfunc" END 

Ensuite, lstlisting analyse le fichier et utilise seulement les lignes entre les BEGIN et les END choses.

Répondre

0

La seule façon raisonnable de faire cela arrive que je peux penser à du haut de ma tête, est de créer un makefile et ont cette responsabilité de produire la sortie correcte .

En supposant sourcefile.c est dans les fichiers ./src et LATEX sont en ./tex alors ./tex/Makefile pourrait ressembler à ceci:

doc.tex: sourcefile.grep 
     <command to compile doc.tex> 
sourcefile.grep: 
     <command to grep/whatever to dump from 
     ../src/sourcefile.c to ./tex/sourcefile.grep> 

Et les lstlistings en doc.tex serait alors le point ./src/sourcefile.grep

+0

Oui, j'ai pensé à ça aussi, mais ça m'a paru un peu trop compliqué. Vu votre edit: 'grep' pourrait être une option. – phimuemue

1

Ne serait pas plus facile à utiliser #include dans C?

Ce n'est pas parfait, mais assez bon, solution.

Voici un exemple (ne pouvait pas compiler, je y avais écrit quelque chose la dernière fois en C 5 ans):

principal C programme:

#include <stdio.h> 

    //function included from separate file -- will be included in LaTeX too 
    #include "fun_x.c"   

    int main() 
    { 
     int d = 0; 
     printf("%d", fun_x(d)); 

    //code included from separate file -- will be included in LaTeX too 
    #include "calc.c" 

     return 0; 
    } 

fichier fun_x.c:

int fun_x(int c) 
{ 
    c++; 
    return c; 
} 

calc.c fichier:

d = 99; 
d = fun_x(d); 

source LaTeX:

\begin{document} 
... 

\lstinputlisting{../src/fun_x.c) 

... 

\lstinputlisting{../src/calc.c) 

... 

\end{document} 
+0

Je ne suis pas sûr, mais je pense que vous m'avez mal compris. Je veux inclure le code C dans LaTeX. – phimuemue

+1

Je voulais garder chaque fragment de code C que vous devez inclure dans LaTeX dans un fichier séparé (ce problème de résolution de ligne), qui sera inclus dans le fichier C avec '# include'. –

1

Quelque chose comme ceci était discussed on the TeX SE un peu en arrière et une réponse a utilisé un paquet catchfilebetweentags. Cela ne résout pas votre problème directement, mais peut-être vous pouvez l'utiliser pour alimenter le fragment que vous voulez \lstlistings, peut-être encore avec un fichier temporaire.

11

Je réponds quelques mois après votre post, mais la fonctionnalité de lstlistings que je décris ci-dessous est dans ce paquet depuis plusieurs années.

Le mot-clé à rechercher est l'option linerange, ainsi que, pour plus de commodité, rangeprefix et rangesuffix.

Voici un exemple complet.

\documentclass{article} 
\usepackage{fullpage,times,listings} 
\lstloadlanguages{C++} 

\lstset{language=C++,keywordstyle=\bfseries,commentstyle=\itshape, 
    rangeprefix=//----------------,rangesuffix=----------------, 
    includerangemarker=false,columns=spaceflexible} 

\begin{document} 
We first show the main function. 
\lstinputlisting[linerange=main0-main1]{code.cpp} 
Then we show the implementation. 
\lstinputlisting[linerange=fact0-fact1]{code.cpp} 
\end{document} 

puis enregistrez ce qui suit dans code.cpp:

#include <cassert> 

//----------------fact0---------------- 
// A recursive implementation of factorial 
int factorial(int i) 
{ 
    if(i) 
     return i * factorial(i-1); 
    else 
     return 1; 
} 
//----------------fact1---------------- 

//----------------main0---------------- 
// Test the implementation. 
int main() 
{ 
    assert(factorial(5) == 120); 
} 
//----------------main1---------------- 

Ceci est une bonne solution parce que l'on édite inévitablement le code, puis il devient fastidieux de mettre à jour les numéros de ligne tout au long de ses fichiers TeX. L'utilisation de symboles résout ce problème, mais laisse également une trace dans le code lui-même que si le nombre de lignes change, ou si la largeur change trop, il faut confirmer que la sortie du jeu de caractères semble toujours raisonnable.

Enfin, après avoir modifié le code, vous devez réécrire les fichiers latex uniquement si vous avez inséré/effacé dans les blocs marqués.

+0

Wahoo, merci! Même si votre solution est arrivée en retard, elle devrait être choisie! –