LaTeX: Lstlisting автоматически распознает прохождение кода - PullRequest
5 голосов
/ 12 октября 2010

Я пишу программу (на C, но, я полагаю, это не так актуально) в связи с небольшим документальным материалом на LaTeX.Я хочу, чтобы документальный материал содержал фрагменты кода из моего исходного кода.

Чтобы включить исходный код и поддерживать его в актуальном состоянии, я делаю следующее в своем документе:

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

Это автоматически загружает строки 200 до 210 (которые содержат, например, функцию) из ../src/source.c в мой документ.

Однако, если я добавлю несколько строк перед строкой 200, это означает, что строка 200 «блуждает по некоторым строкам», поэтому мне нужно отрегулировать ее, чтобы получить исходную функцию.

Итаквот мой вопрос: кто-нибудь знает о возможности, как динамически сказать lstinputlisting (или любой адекватный заменитель), чтобы сказать, какие строки взять?

Я представляю что-то вроде следующего: я добавляю специальные комментарии к моему Cисходный код, который будет распознан lstinputlisting, например

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

Затем lstlisting сканирует файл и просто включает строки между BEGIN и END.

Ответы [ 4 ]

14 голосов
/ 07 мая 2011

Я отвечаю через несколько месяцев после вашего поста, но функция списков рассылки, которую я опишу ниже, была в этом пакете в течение нескольких лет.

Ключевым словом, которое нужно искать, является также опция linerangeкак, для удобства, rangeprefix и rangesuffix.

Вот полный пример.

\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}

, затем сохраните следующее в 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----------------

Это хорошее решение, потому что человек неизбежно редактирует код, а затем становится утомительным обновлять номера строк в файлах TeX.Использование символов решает эту проблему, но также оставляет след в самом коде: если количество строк изменяется или ширина меняется слишком сильно, необходимо подтвердить, что вывод набора по-прежнему выглядит разумным.

Наконец, после редактирования кода вам нужно будет снова набирать латексные файлы, только если вы вставили / удалили внутри отмеченных блоков.

1 голос
/ 12 октября 2010

Единственный разумный способ добиться этого, о котором я могу подумать, - это создать make-файл, который должен отвечать за создание правильного вывода.

Предполагая, что sourcefile.c находится в ./src, а файлы LaTeX находятся в ./tex, тогда ./tex/Makefile может выглядеть примерно так:

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>

И тогда lstlistings в doc.tex будет указывать на ./src/sourcefile.grep

1 голос
/ 16 декабря 2010

Как-то так обсуждалось на TeX SE некоторое время назад, и в одном ответе использовался пакет catchfilebetweentags.Это не решит вашу проблему напрямую, но, возможно, вы можете использовать это для подачи фрагмента, который вы хотите \lstlistings, возможно, снова с временным файлом.

1 голос
/ 12 октября 2010

Было бы проще использовать #include в C?

Это не идеальное, но достаточно хорошее решение.

Вот пример (не могу скомпилировать, я бынаписано в последний раз что-то в C 5 лет назад):

Основная C Программа:

    #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;
    }

fun_x.c Файл:

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

calc.c файл:

d = 99;
d = fun_x(d);

Источник LaTeX:

\begin{document}
...

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

...

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

...

\end{document}
...