如何将输入列表填充为双列格式的两列,且其末尾不从页面上截断?

如何将输入列表填充为双列格式的两列,且其末尾不从页面上截断?

我需要添加一堆代码来显示我让参与者解决的问题的整个 CPP 文件,但无论我将其定义为哪种样式,代码都会一直截断页面。我正在使用 overleaf,并被要求用这个来格式化我的论文模板。这是带有模板的 MWE。我只是使用了 std::mutex 示例中的一些虚拟代码,因为我希望文档中包含一长段代码。

\documentclass[pageno]{jpaper}

\newcommand{\asplossubmissionnumber}{XXX}
\usepackage[normalem]{ulem}

\usepackage[toc,page]{appendix}
\usepackage{listings}
\usepackage{courier}
\usepackage{adjustbox}
\usepackage[justification=centering]{caption}
\usepackage{lipsum}
\usepackage{float}


\lstdefinestyle{fullStyle}{%
%   framerule=1pt,
  basicstyle=\ttfamily\footnotesize,
  breaklines=true,
  columns=fullflexible
}



\begin{document}

\title{
Some Title is here}

\date{}
\maketitle



\section{Some section}
\lipsum[50]

\section{Another section}
\lipsum[50]

\begin{lstlisting}[language=C++,style=fullStyle, captionpos=b, caption=Testing Listing Placement,float=*]
#include <mutex>
#include <thread>
#include <iostream>
#include <vector>
#include <functional>
#include <chrono>
#include <string>
 
struct Employee {
    Employee(std::string id) : id(id) {}
    std::string id;
    std::vector<std::string> lunch_partners;
    std::mutex m;
    std::string output() const
    {
        std::string ret = "Employee " + id + " has lunch partners: ";
        for( const auto& partner : lunch_partners )
            ret += partner + " ";
        return ret;
    }
};
 
void send_mail(Employee &, Employee &)
{
    // simulate a time-consuming messaging operation
    std::this_thread::sleep_for(std::chrono::seconds(1));
}
 
void assign_lunch_partner(Employee &e1, Employee &e2)
{
    static std::mutex io_mutex;
    {
        std::lock_guard<std::mutex> lk(io_mutex);
        std::cout << e1.id << " and " << e2.id << " are waiting for locks" << std::endl;
    }
 
    // use std::lock to acquire two locks without worrying about 
    // other calls to assign_lunch_partner deadlocking us
    {
        std::lock(e1.m, e2.m);
        std::lock_guard<std::mutex> lk1(e1.m, std::adopt_lock);
        std::lock_guard<std::mutex> lk2(e2.m, std::adopt_lock);
// Equivalent code (if unique_locks are needed, e.g. for condition variables)
//        std::unique_lock<std::mutex> lk1(e1.m, std::defer_lock);
//        std::unique_lock<std::mutex> lk2(e2.m, std::defer_lock);
//        std::lock(lk1, lk2);
// Superior solution available in C++17
//        std::scoped_lock lk(e1.m, e2.m);
        {
            std::lock_guard<std::mutex> lk(io_mutex);
            std::cout << e1.id << " and " << e2.id << " got locks" << std::endl;
        }
        e1.lunch_partners.push_back(e2.id);
        e2.lunch_partners.push_back(e1.id);
    }
    send_mail(e1, e2);
    send_mail(e2, e1);
}
 
int main()
{
    Employee alice("alice"), bob("bob"), christina("christina"), dave("dave");
 
    // assign in parallel threads because mailing users about lunch assignments
    // takes a long time
    std::vector<std::thread> threads;
    threads.emplace_back(assign_lunch_partner, std::ref(alice), std::ref(bob));
    threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(bob));
    threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(alice));
    threads.emplace_back(assign_lunch_partner, std::ref(dave), std::ref(bob));
 
    for (auto &thread : threads) thread.join();
    std::cout << alice.output() << '\n'  << bob.output() << '\n'
              << christina.output() << '\n' << dave.output() << '\n';
              
    // assign in parallel threads because mailing users about lunch assignments
    // takes a long time
    std::vector<std::thread> threads;
    threads.emplace_back(assign_lunch_partner, std::ref(alice), std::ref(bob));
    threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(bob));
    threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(alice));
    threads.emplace_back(assign_lunch_partner, std::ref(dave), std::ref(bob));
}
\end{lstlisting}


\section{Another section Goes Here}
\lipsum[50]

\section{Acknowledgements}
Thanks to people who participated and advised
on certain things

\bibliographystyle{plain}
\bibliography{references}



\end{document}


我如何才能让此代码正确格式化为列表,以便它能够正确拆分到它所包含的页面中,而不会在内容不适合页面时被截断?我一直在查看列表文档几天,似乎没有什么可以阻止它被切断。不幸的是,multicol解决方案这里对我来说没用。任何帮助我都会很感激。

答案1

tcolorbox一个建议是与listings和库一起使用breakable

笔记:您不必担心手动破坏跨多个页面的代码。tcolorbox为我们做这件事。除非您有充分的理由,否则我认为没有必要将代码限制在单个页面上,无论您是否有多个列。

\documentclass{article}
\usepackage[hmargin=0.75in,vmargin=0.75in]{geometry}
\usepackage{listings}
\usepackage{multicol}
\usepackage[breakable,listings]{tcolorbox}


\lstdefinestyle{fullStyle}{%
    %   framerule=1pt,
    basicstyle=\ttfamily\footnotesize,
    breaklines=true,
    columns=fullflexible,
    language=C++
}



\begin{document}    
\begin{multicols}{2}
\begin{tcblisting}{listing only,breakable,listing options={style=fullStyle}}
#include <mutex>
#include <thread>
#include <iostream>
#include <vector>
#include <functional>
#include <chrono>
#include <string>

struct Employee {
    Employee(std::string id) : id(id) {}
    std::string id;
    std::vector<std::string> lunch_partners;
    std::mutex m;
    std::string output() const
    {
        std::string ret = "Employee " + id + " has lunch partners: ";
        for( const auto& partner : lunch_partners )
        ret += partner + " ";
        return ret;
    }
};

void send_mail(Employee &, Employee &)
{
    // simulate a time-consuming messaging operation
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

void assign_lunch_partner(Employee &e1, Employee &e2)
{
    static std::mutex io_mutex;
    {
        std::lock_guard<std::mutex> lk(io_mutex);
        std::cout << e1.id << " and " << e2.id << " are waiting for locks" << std::endl;
    }
    
    // use std::lock to acquire two locks without worrying about 
    // other calls to assign_lunch_partner deadlocking us
    {
        std::lock(e1.m, e2.m);
        std::lock_guard<std::mutex> lk1(e1.m, std::adopt_lock);
        std::lock_guard<std::mutex> lk2(e2.m, std::adopt_lock);
        // Equivalent code (if unique_locks are needed, e.g. for condition variables)
        //        std::unique_lock<std::mutex> lk1(e1.m, std::defer_lock);
        //        std::unique_lock<std::mutex> lk2(e2.m, std::defer_lock);
        //        std::lock(lk1, lk2);
        // Superior solution available in C++17
        //        std::scoped_lock lk(e1.m, e2.m);
        {
            std::lock_guard<std::mutex> lk(io_mutex);
            std::cout << e1.id << " and " << e2.id << " got locks" << std::endl;
        }
        e1.lunch_partners.push_back(e2.id);
        e2.lunch_partners.push_back(e1.id);
    }
    send_mail(e1, e2);
    send_mail(e2, e1);
}

int main()
{
    Employee alice("alice"), bob("bob"), christina("christina"), dave("dave");
    
    // assign in parallel threads because mailing users about lunch assignments
    // takes a long time
    std::vector<std::thread> threads;
    threads.emplace_back(assign_lunch_partner, std::ref(alice), std::ref(bob));
    threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(bob));
    threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(alice));
    threads.emplace_back(assign_lunch_partner, std::ref(dave), std::ref(bob));
    
    for (auto &thread : threads) thread.join();
    std::cout << alice.output() << '\n'  << bob.output() << '\n'
    << christina.output() << '\n' << dave.output() << '\n';
    
    // assign in parallel threads because mailing users about lunch assignments
    // takes a long time
    std::vector<std::thread> threads;
    threads.emplace_back(assign_lunch_partner, std::ref(alice), std::ref(bob));
    threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(bob));
    threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(alice));
    threads.emplace_back(assign_lunch_partner, std::ref(dave), std::ref(bob));
}
\end{tcblisting}
\end{multicols}
\end{document}

在此处输入图片描述

相关内容