所以我用listings
代码示例包。但是有一个问题。当我从最终的 PDF 文档中复制代码示例时,它们通常不一样 - 缩进消失了,括号后有随机空格等。有人知道如何确保我从最终文档中复制的代码与我在 LaTeX 文档中编写的代码相同吗?
这就是我的意思。编译此文档:
\documentclass[12pt,oneside]{memoir}
\usepackage{listings}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\usepackage{textcomp}
\definecolor{codebg}{HTML}{EEEEEE}
\definecolor{codeframe}{HTML}{CCCCCC}
\lstset{language=Awk}
\lstset{backgroundcolor=\color{codebg}}
\lstset{frame=single}
\lstset{framesep=10pt}
\lstset{rulecolor=\color{codeframe}}
\lstset{upquote=true}
\lstset{basicstyle=\ttfamily}
\lstset{showstringspaces=false}
\begin{document}
This code example prints out all users on your system:
\begin{lstlisting}[language=c]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LEN 1024
int main() {
char line[MAX_LINE_LEN];
FILE *in = fopen("/etc/passwd", "r");
if (!in) exit(EXIT_FAILURE);
while (fgets(line, MAX_LINE_LEN, in) != NULL) {
char *sep = strchr(line, ':');
if (!sep) exit(EXIT_FAILURE);
*sep = '\0';
printf("%s\n", line);
}
fclose(in);
return EXIT_SUCCESS;
}
\end{lstlisting}
\end{document}
现在编译它,打开它,选择并复制代码示例并将其粘贴到文本编辑器中。这是我得到的结果:
# include <stdio .h>
# include <stdlib .h>
# include <string .h>
# define MAX_LINE_LEN 1024
int main () {
char line [ MAX_LINE_LEN ];
FILE *in = fopen ("/ etc / passwd ", "r");
if (! in) exit ( EXIT_FAILURE );
while ( fgets (line , MAX_LINE_LEN , in) != NULL ) {
char * sep = strchr (line , ':');
if (! sep ) exit ( EXIT_FAILURE );
* sep = '\0 ';
printf ("%s\n", line );
}
fclose (in );
return EXIT_SUCCESS ;
}
天哪!这是什么……缩进不见了。包含的标题中有空格<stdio .h>
,括号后也有空格[ MAX_LINE_LEN ]
。
有人知道如何解决这个问题吗?我希望书中的代码示例可以复制/粘贴到文本编辑器中,以便人们可以轻松尝试它们。
答案1
为了防止从列表复制文本时出现随机空格,您需要使用
\lstset{columns=flexible}
但是你现在会注意到文本不再整齐对齐;为了解决这个问题,你还需要使用
\lstset{keepspaces=true}
这无法解决复制时行首空格消失的问题。以下技巧将产生可见的空格,然后通过将其着色为背景颜色使其不可见:
\makeatletter
\def\lst@outputspace{{\ifx\lst@bkgcolor\empty\color{white}\else\lst@bkgcolor\fi\lst@visiblespace}}
\makeatother
但是,这种技巧并不完美,因为排版的字符实际上是可见空格,而不是空格(因此在 pdf 中搜索char line
将不起作用),并且某些 PDF 阅读器(如 Mac 的预览)会复制可见空格。它在 Acrobat Reader 下工作,能够快速复制/粘贴代码而不会出现问题,这非常令人愉快(也许可以通过编写直接 PDF 代码来告诉它是一个空格来规避这个问题,我从来没有时间尝试)。它也可能不适用于所有打字机字体。
以下是示例的完整代码:
\documentclass[12pt,oneside]{memoir}
\usepackage{listings}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\usepackage{textcomp}
\definecolor{codebg}{HTML}{EEEEEE}
\definecolor{codeframe}{HTML}{CCCCCC}
\lstset{language=Awk}
\lstset{backgroundcolor=\color{codebg}}
\lstset{frame=single}
\lstset{framesep=10pt}
\lstset{rulecolor=\color{codeframe}}
\lstset{upquote=true}
\lstset{basicstyle=\ttfamily}
\lstset{showstringspaces=false}
\lstset{columns=flexible}
\lstset{keepspaces=true}
\makeatletter
\def\lst@outputspace{{\ifx\lst@bkgcolor\empty\color{white}\else\lst@bkgcolor\fi\lst@visiblespace}}
\makeatother
\begin{document}
This code example prints out all users on your system:
\begin{lstlisting}[language=c]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LEN 1024
int main() {
char line[MAX_LINE_LEN];
FILE *in = fopen("/etc/passwd", "r");
if (!in) exit(EXIT_FAILURE);
while (fgets(line, MAX_LINE_LEN, in) != NULL) {
char *sep = strchr(line, ':');
if (!sep) exit(EXIT_FAILURE);
*sep = '\0';
printf("%s\n", line);
}
fclose(in);
return EXIT_SUCCESS;
}
\end{lstlisting}
\end{document}
答案2
你可以使用以下修改
\newlength{\lstcolumnwidth}
\settowidth{\lstcolumnwidth}{\ttfamily M}
\lstset{basicstyle=\ttfamily,basewidth=\lstcolumnwidth,columns=fixed, fontadjust=true}
行首的缩进不是 LaTeX 的问题,这是读者的问题,没有针对这种情况的设置。你可以用以下代码得到一个奇怪的解决方案:
\lstset{showspaces=true}
\makeatletter
\def\lst@visiblespace{\textcolor{codebg}{-}}
\makeatother
使用类似的包attachefile2
您可以附加原始的c文件。
答案3
我的回答不会回答你的问题。:-) 但我有一个很好的方法来管理代码片段的包含,以便读者轻松访问。与其从 pdf 中复制代码,不如让读者通过单击超链接打开底层代码文件。
尝试编译以下代码。我使用 latex-dvips-ps2pdf 编译步骤。当然你也可以使用 pdflatex,但不要忘记删除dvips
中的选项\documentclass
。
为了易于维护,请按如下方式创建您自己的包:
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{xport}[2011/06/05 v0.01 LaTeX package for my own purpose]
\RequirePackage[utf8x]{inputenc}
\RequirePackage{xcolor}
\RequirePackage{caption}
\captionsetup
{%
font={small,rm},
labelfont={color=Maroon,bf},
justification=justified%
}
\RequirePackage{listings}
\AtBeginDocument
{%
\renewcommand*{\lstlistlistingname}{Code List}%
\renewcommand*{\lstlistingname}{Code}%
}
\lstset
{%
%linewidth=\linewidth,
breaklines=true,
tabsize=3,
showstringspaces=false%
}
\lstdefinestyle{Common}
{%
extendedchars=\true,
language={[Sharp]C},
%alsolanguage={PSTricks},
frame=single,
%===========================================================
framesep=3pt,%expand outward.
framerule=0.4pt,%expand outward.
xleftmargin=3.4pt,%make the frame fits in the text area.
xrightmargin=3.4pt,%make the frame fits in the text area.
%===========================================================
rulecolor=\color{Red}%
}
\lstdefinestyle{A}%
{%
style=Common,
backgroundcolor=\color{Yellow!10},
basicstyle=\scriptsize\color{Black}\ttfamily,
keywordstyle=\color{Orange},
identifierstyle=\color{Cyan},
stringstyle=\color{Red},
commentstyle=\color{Green}%
}
\newcommand{\IncludeCSharp}[2][style=A]%
{%
\lstinputlisting[#1,caption={\href{#2}{#2}}]{#2}%
}
%for beamer, use \hypersetup instead.
\RequirePackage[colorlinks=true,bookmarksnumbered=true,bookmarksopen=true]{hyperref}
%to make hyperlinks point to the top of figure or table.
%it must be loaded after hyperref.
\RequirePackage[all]{hypcap}% cannot be used in beamer.
\endinput
在主输入文件中,可以\IncludeCSharp
按如下方式调用:
\documentclass[dvips,dvipsnames,cmyk,12pt]{article}
\usepackage[a4paper,margin=2cm]{geometry}
\usepackage{xport}
\begin{document}
\IncludeCSharp[style=A]{Codes/Program.cs}
\end{document}
导入的C#文件在子目录Program.cs
中命名。Codes/
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");//This is a comment.
/*This is a comment too.*/
}
}
}
答案4
(请参考此帖子:如何制作一个 LaTeX 文档,使其生成 PDF,以便复制粘贴空行和前导空格缩进能够正确进行?,试图将对这个问题的不同部分讨论的所有智慧汇集到一个地方。