在文档中插入代码的时候,我希望
如下是我使用 minted 的尝试,结果是跨页和题注都没有实现。MWE.tex
如下。
\documentclass[a4paper,12pt]{ctexart}
\usepackage{minted}
\usepackage{float}
\usepackage{caption}
\begin{document}
\begin{center}
床前明月光,\\
疑是地上霜。\\
举头望明月,\\
低头思故乡。\\
\end{center}
% TODO: 让代码从当前页继续,但如果当前页空间不足时自动换页
\begin{listing}[htbp]
% TODO: caption 位于代码上方
\caption{代码}
\label{code:besselj1}
\inputminted{c}{besselj1.txt}
\end{listing}
\end{document}
失败的排版效果如下。
代码 besselj1.txt
的内容随意,但保证一页 A4 放不下。
建议不要用「让代码就像文字一样,从当前页继续,但如果当前页空间不足时自动换页」这种表述,而是用「breakable listings」
太困了,只给例子,个人觉得tcb是比较好的实践了...
tcolorbox
和listings
的文档几个关键的option为:
listing remove caption=false
caption={Rust is Genshin Impact of coding}
captionpos=t
(这是默认值,可调)label={mycode}
\documentclass{article}
\usepackage[margin=1in]{geometry}
\usepackage{lipsum}
\usepackage[most]{tcolorbox}
\usepackage{hyperref}
\tcbuselibrary{listings}
\newtcbinputlisting{\mylisting}[2][]{%
enhanced jigsaw,sharp corners,title={example~code},empty,left=1cm,breakable,%
listing file={#2},listing only,listing remove caption=false,
listing options={numbers=left,breaklines,basicstyle=\ttfamily,caption={Rust is Genshin Impact of coding},captionpos=t,label={mycode}},#1%
}
\begin{filecontents*}[overwrite]{temp.rs}
use std::sync::{mpsc, Arc, Mutex};
use std::thread;
use std::time::Duration;
struct ThreadPool {
workers: Vec<Worker>,
sender: mpsc::Sender<Message>,
}
impl ThreadPool {
fn new(size: usize) -> Result<ThreadPool, PoolCreationError> {
if size == 0 {
return Err(PoolCreationError::InvalidSize);
}
let (sender, receiver) = mpsc::channel();
let receiver = Arc::new(Mutex::new(receiver));
let mut workers = Vec::with_capacity(size);
for id in 0..size {
workers.push(Worker::new(id, Arc::clone(&receiver)));
}
Ok(ThreadPool { workers, sender })
}
fn execute<F>(&self, f: F)
where
F: FnOnce() + Send + 'static,
{
let job = Box::new(f);
self.sender.send(Message::NewJob(job)).unwrap();
}
}
struct Worker {
id: usize,
thread: Option<thread::JoinHandle<()>>,
}
impl Worker {
fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Message>>>) -> Worker {
let thread = thread::spawn(move || loop {
let message = receiver.lock().unwrap().recv().unwrap();
match message {
Message::NewJob(job) => {
job();
}
Message::Terminate => break,
}
});
Worker {
id,
thread: Some(thread),
}
}
}
enum Message {
NewJob(Box<dyn FnOnce() + Send + 'static>),
Terminate,
}
#[derive(Debug)]
enum PoolCreationError {
InvalidSize,
}
fn is_prime(n: u64) -> bool {
if n <= 1 {
return false;
}
for i in 2..=(n as f64).sqrt() as u64 {
if n % i == 0 {
return false;
}
}
true
}
fn main() {
}
\end{filecontents*}
\begin{document}
I want to ref code \ref{mycode} here.
\lipsum[1]
\mylisting{temp.rs}
\lipsum[2]
\end{document}
受到 @u70550 的启发,最后做出来满意的结果。目前的方案如下。
\documentclass{ctexart}
\usepackage[margin=3cm]{geometry}
\usepackage{listings}
\usepackage{xcolor}
\usepackage[colorlinks=true]{hyperref}
\definecolor{codegreen}{rgb}{0,0.5,0}
\definecolor{codeblue}{rgb}{0,0,0.8}
\definecolor{codegray}{rgb}{0.5,0.5,0.5}
\definecolor{codepurple}{rgb}{0.58,0,0.82}
% Set listing style
\lstdefinestyle{mystyle}{
backgroundcolor=\color{white!95!black},
commentstyle=\color{codegreen},
keywordstyle=\color{codeblue},
numberstyle=\tiny\color{codegray},
stringstyle=\color{codepurple},
basicstyle=\ttfamily\footnotesize,
breakatwhitespace=false,
breaklines=true,
captionpos=t,
keepspaces=true,
numbers=left,
numbersep=5pt,
showspaces=false,
showstringspaces=false,
showtabs=false,
tabsize=2,
frame=single,
belowcaptionskip=10pt
}
\lstset{style=mystyle}
\begin{filecontents*}[overwrite]{PackedFileDemo.c}
/* This is the main file for the Packed File Demo program
which writes an Igor Pro 3.x packed experiment file.
See Igor Pro Tech Note PTN#003 for details.
*/
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stddef.h> // For offsetof macro.
#include "PackedFile.h"
#include "Variables.h"
#include "IgorBin.h"
#include "CrossPlatformFileIO.h"
#include "IgorSupport.h"
#include "PackedFileDemo.h"
static int
GetNextCommand(char* filePath)
{
char input[1024];
int command;
int i;
*filePath = 0;
while(1) {
printf("Command: ");
if (fgets(input, sizeof(input)-1, stdin) != NULL) {
char* p = strchr(input, '\n'); // Find new line character.
if (p != NULL)
*p = 0; // Remove new line character.
for(i=0; i<5; i++)
input[i] = toupper(input[i]); // Convert command to upper case.
if (strncmp(input, "READ ", 5) == 0) {
command = 1;
strcpy(filePath, input+5);
break;
}
if (strncmp(input, "WRITE ", 6) == 0) {
command = 2;
strcpy(filePath, input+6);
break;
}
if (strncmp(input, "QUIT", 4) == 0) {
command = 3;
break;
}
}
printf("\n\n");
}
return command;
}
int
main(void)
{
int command;
char filePath[1024];
char fullPathSample[32];
char partialPathSample[32];
int err;
#ifdef WIN32
strcpy(fullPathSample, "C:\\FolderA\\Test Packed File.pxp");
strcpy(partialPathSample, ".\\Test Packed File.pxp");
#else
strcpy(fullPathSample, "hd:FolderA:Test Packed File");
strcpy(partialPathSample, ":SamplesMac:Test Packed File");
#endif
printf("This program illustrates reading and writing Igor packed experiment files.\n\n");
printf("To read a file, enter the following: Read <file path>\n\n");
printf("To write a file, enter the following: Write <file path>\n\n");
printf("<file path> can be either a full path (%s)\n", fullPathSample);
printf("or a partial path relative to the folder containing this program (%s)\n", partialPathSample);
printf("\n");
printf("Here are some sample commands:\n");
#ifdef WIN32
printf(" Read Test Packed File.pxp\n");
printf(" Read .\\Test Packed File.pxp\n");
printf(" Write Test Packed File.pxp\n");
#else
printf(" Read Test Packed File\n");
printf(" Read :Test Packed File\n");
printf(" Write Test Packed File\n");
#endif
#ifdef WIN32
printf("To quit the program, type Quit\n");
#else
printf("To quit the program, choose Quit from the file menu.\n");
#endif
while(1) {
printf("\n");
command = GetNextCommand(filePath);
if (command == 1)
err = ReadPackedFile(filePath);
if (command == 2)
err = WritePackedFile(filePath);
if (command == 3) {
#ifndef WIN32
printf("Now you must choose Quit from the File menu to quit.\n");
#endif
break;
}
}
return 0;
}
\end{filecontents*}
\begin{document}
\begin{center}
静夜思\\[0.5em]
〔唐代〕李白\\[0.5em]
床前明月光,疑是地上霜。\\
举头望明月,低头思故乡。\\
\end{center}
我想在此处引用代码 \ref{lst:maincode}。
\lstinputlisting[language=C,caption={这是一段示例代码},label={lst:maincode}]{PackedFileDemo.c}
我想唱歌。
\begin{center}
凉州词二首·其一\\[0.5em]
〔唐代〕王之涣\\[0.5em]
黄河远上白云间,一片孤城万仞山。\\
羌笛何须怨杨柳,春风不度玉门关。\\
\end{center}
\end{document}
效果图如下。
