Tikz + Verbatim + Sphinx,输出两次绘制,略有偏移。效果很好 Tikz + Verbatim

Tikz + Verbatim + Sphinx,输出两次绘制,略有偏移。效果很好 Tikz + Verbatim

我正在开发一款将 IPython Notebooks 输出为 tex 文档的软件。我的要求之一是能够绘制类似于 Notebook 的 UI 的代码输入输出块。

免责声明:很长一段时间以来,我都使用 MDFRAMED 来绘制单元格。遗憾的是,MDFRAMED 的垂直间距在不同版本之间有所不同,我绝对不能强迫用户使用特定版本的 MDFRAMED。我研究了如何将 MDFRAMED 与软件一起分发,发现如果不对 MDFRAMED 进行修改,就无法做到这一点

所以我下定决心,开始在 TIKz 中编写自己的自定义框架逻辑。我唯一的要求是具有圆边、小边框、支持多页以及支持 pygments 输出(fancyvrb Verbatim)。

几个小时后,我完全实现了我的目标:

良好输出

但是!当我尝试使用 Sphinx 模板来生成输出时:

坏输出

tikz 代码的主要内容如下http://www.texample.net/tikz/examples/framed-tikz/修改示例

编辑:根据戴维的建议:

更接近

编辑:MWE,提供建议的解决方案。产生与上述相同的输出。

% Make sure that the sphinx doc style knows who it inherits from.
\def\sphinxdocclass{article}

% Declare the document class
\documentclass[letterpaper,10pt,english]{/usr/local/lib/python2.7/dist-packages/Sphinx-1.2predev_20130207-py2.7.egg/sphinx/texinputs/sphinxhowto}



\usepackage[Bjarne]{/usr/local/lib/python2.7/dist-packages/Sphinx-1.2predev_20130207-py2.7.egg/sphinx/texinputs/fncychap}


\usepackage{/usr/local/lib/python2.7/dist-packages/Sphinx-1.2predev_20130207-py2.7.egg/sphinx/texinputs/sphinx}



\usepackage{graphicx} % Used to insert images
\usepackage{adjustbox} % Used to constrain images to a maximum size 
\usepackage{color} % Allow colors to be defined
\usepackage{enumerate} % Needed for markdown enumerations to work
\usepackage{geometry} % Used to adjust the document margins
\usepackage{amsmath} % Equations
\usepackage{amssymb} % Equations
\usepackage[utf8]{inputenc} % Allow utf-8 characters in the tex document
\usepackage{ucs} % Extended unicode (utf-8) support
\usepackage{fancyvrb} % verbatim replacement that allows latex
\usepackage{grffile} % extends the file name processing of package graphics 
                 %to support a larger range 

% The hyperref package gives us a pdf with properly built
% internal navigation ('pdf bookmarks' for the table of contents,
% internal cross-reference links, web links for URLs, etc.)
\usepackage{hyperref}


\usepackage{tikz} % Needed to box output/input
\usepackage{scrextend} % Used to indent output
\usepackage{needspace} % Make prompts follow contents
\usepackage{framed} % Used to draw output that spans multiple pages





\definecolor{orange}{cmyk}{0,0.4,0.8,0.2}
\definecolor{darkorange}{rgb}{.71,0.21,0.01}
\definecolor{darkgreen}{rgb}{.12,.54,.11}
\definecolor{myteal}{rgb}{.26, .44, .56}
\definecolor{gray}{gray}{0.45}
\definecolor{lightgray}{gray}{.95}
\definecolor{mediumgray}{gray}{.8}
\definecolor{inputbackground}{rgb}{.95, .95, .85}
\definecolor{outputbackground}{rgb}{.95, .95, .95}
\definecolor{traceback}{rgb}{1, .95, .95}

% new ansi colors
\definecolor{brown}{rgb}{0.54,0.27,0.07}
\definecolor{purple}{rgb}{0.5,0.0,0.5}
\definecolor{darkgray}{gray}{0.25}
\definecolor{lightred}{rgb}{1.0,0.39,0.28}
\definecolor{lightgreen}{rgb}{0.48,0.99,0.0}
\definecolor{lightblue}{rgb}{0.53,0.81,0.92}
\definecolor{lightpurple}{rgb}{0.87,0.63,0.87}
\definecolor{lightcyan}{rgb}{0.5,1.0,0.83}

% Define a nice break command that doesn't care if a line doesn't already
% exist.
\def\br{\hspace*{\fill} \\* }

% Document parameters
\title{simpletest}




% Pygments definitions

\makeatletter
\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax%
    \let\PY@ul=\relax \let\PY@tc=\relax%
    \let\PY@bc=\relax \let\PY@ff=\relax}
\def\PY@tok#1{\csname PY@tok@#1\endcsname}
\def\PY@toks#1+{\ifx\relax#1\empty\else%
    \PY@tok{#1}\expandafter\PY@toks\fi}
\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{%
    \PY@it{\PY@bf{\PY@ff{#1}}}}}}}
\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}}

\expandafter\def\csname PY@tok@gd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}}
\expandafter\def\csname PY@tok@gu\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}}
\expandafter\def\csname PY@tok@gt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.25,0.82}{##1}}}
\expandafter\def\csname PY@tok@gs\endcsname{\let\PY@bf=\textbf}
\expandafter\def\csname PY@tok@gr\endcsname{\def\PY@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
\expandafter\def\csname PY@tok@cm\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@vg\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@m\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@mh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@go\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.50,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@ge\endcsname{\let\PY@it=\textit}
\expandafter\def\csname PY@tok@vc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@il\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@cs\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@cp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.74,0.48,0.00}{##1}}}
\expandafter\def\csname PY@tok@gi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
\expandafter\def\csname PY@tok@gh\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\expandafter\def\csname PY@tok@ni\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.60,0.60,0.60}{##1}}}
\expandafter\def\csname PY@tok@nl\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.00}{##1}}}
\expandafter\def\csname PY@tok@nn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@no\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}}
\expandafter\def\csname PY@tok@na\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.49,0.56,0.16}{##1}}}
\expandafter\def\csname PY@tok@nb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@nc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@nd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}}
\expandafter\def\csname PY@tok@ne\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.82,0.25,0.23}{##1}}}
\expandafter\def\csname PY@tok@nf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@si\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}}
\expandafter\def\csname PY@tok@s2\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@vi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@nt\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@nv\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@s1\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@sh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@sc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@sx\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@bp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@c1\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@kc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@c\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@mf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@err\endcsname{\def\PY@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}
\expandafter\def\csname PY@tok@kd\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@ss\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@sr\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}}
\expandafter\def\csname PY@tok@mo\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@kn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@mi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@gp\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\expandafter\def\csname PY@tok@o\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@kr\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@s\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@kp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@w\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}}
\expandafter\def\csname PY@tok@kt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.69,0.00,0.25}{##1}}}
\expandafter\def\csname PY@tok@ow\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}}
\expandafter\def\csname PY@tok@sb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@k\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@se\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.13}{##1}}}
\expandafter\def\csname PY@tok@sd\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}

\def\PYZbs{\char`\\}
\def\PYZus{\char`\_}
\def\PYZob{\char`\{}
\def\PYZcb{\char`\}}
\def\PYZca{\char`\^}
\def\PYZam{\char`\&}
\def\PYZlt{\char`\<}
\def\PYZgt{\char`\>}
\def\PYZsh{\char`\#}
\def\PYZpc{\char`\%}
\def\PYZdl{\char`\$}
\def\PYZti{\char`\~}
% for compatibility with earlier versions
\def\PYZat{@}
\def\PYZlb{[}
\def\PYZrb{]}
\makeatother


% NB prompt colors
\definecolor{nbframe-border}{rgb}{0.867,0.867,0.867}
\definecolor{nbframe-bg}{rgb}{0.969,0.969,0.969}
\definecolor{nbframe-in-prompt}{rgb}{0.0,0.0,0.502}
\definecolor{nbframe-out-prompt}{rgb}{0.545,0.0,0.0}

% NB prompt lengths
\newlength{\inputpadding}
\setlength{\inputpadding}{0.5em}
\newlength{\cellleftmargin}
\setlength{\cellleftmargin}{0.15\linewidth}
\newlength{\borderthickness}
\setlength{\borderthickness}{0.4pt}
\newlength{\smallerfontscale}
\setlength{\smallerfontscale}{9.5pt}

% NB prompt font size
\def\smaller{\fontsize{\smallerfontscale}{\smallerfontscale}\selectfont}

% Define a background layer, in which the nb prompt shape is drawn
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}
\usetikzlibrary{calc}

% define styles for the normal border and the torn border
\tikzset{
normal border/.style={draw=nbframe-border, fill=nbframe-bg,
rectangle, rounded corners=2.5pt, line width=\borderthickness},
torn border/.style={draw=white, fill=white, line width=\borderthickness}}

% Macro to draw the shape behind the text, when it fits completly in the
% page
\def\notebookcellframe#1{%
\tikz{%
\node[inner sep=\inputpadding] (A) {#1};% Draw the text of the node
\begin{pgfonlayer}{background}% Draw the shape behind
\fill[normal border]%
    (A.south east) -- ($(A.south west)+(\cellleftmargin,0)$) -- 
    ($(A.north west)+(\cellleftmargin,0)$) -- (A.north east) -- cycle;
\end{pgfonlayer}}}%

% Macro to draw the shape, when the text will continue in next page
\def\notebookcellframetop#1{%
\tikz{%
\node[inner sep=\inputpadding] (A) {#1};    % Draw the text of the node
\begin{pgfonlayer}{background}    
\fill[normal border]              % Draw the ``complete shape'' behind
    (A.south east) -- ($(A.south west)+(\cellleftmargin,0)$) -- 
    ($(A.north west)+(\cellleftmargin,0)$) -- (A.north east) -- cycle;
\fill[torn border]                % Add the torn lower border
    ($(A.south east)-(0,.1)$) -- ($(A.south west)+(\cellleftmargin,-.1)$) -- 
    ($(A.south west)+(\cellleftmargin,.1)$) -- ($(A.south east)+(0,.1)$) -- cycle;
\end{pgfonlayer}}}

% Macro to draw the shape, when the text continues from previous page
\def\notebookcellframebottom#1{%
\tikz{%
\node[inner sep=\inputpadding] (A) {#1};   % Draw the text of the node
\begin{pgfonlayer}{background}   
\fill[normal border]             % Draw the ``complete shape'' behind
    (A.south east) -- ($(A.south west)+(\cellleftmargin,0)$) -- 
    ($(A.north west)+(\cellleftmargin,0)$) -- (A.north east) -- cycle;
\fill[torn border]               % Add the torn upper border
    ($(A.north east)-(0,.1)$) -- ($(A.north west)+(\cellleftmargin,-.1)$) -- 
    ($(A.north west)+(\cellleftmargin,.1)$) -- ($(A.north east)+(0,.1)$) -- cycle;
\end{pgfonlayer}}}

% Macro to draw the shape, when both the text continues from previous page
% and it will continue in next page
\def\notebookcellframemiddle#1{%
\tikz{%
\node[inner sep=\inputpadding] (A) {#1};   % Draw the text of the node
\begin{pgfonlayer}{background}   
\fill[normal border]             % Draw the ``complete shape'' behind
    (A.south east) -- ($(A.south west)+(\cellleftmargin,0)$) -- 
    ($(A.north west)+(\cellleftmargin,0)$) -- (A.north east) -- cycle;
\fill[torn border]               % Add the torn lower border
    ($(A.south east)-(0,.1)$) -- ($(A.south west)+(\cellleftmargin,-.1)$) -- 
    ($(A.south west)+(\cellleftmargin,.1)$) -- ($(A.south east)+(0,.1)$) -- cycle;
\fill[torn border]               % Add the torn upper border
    ($(A.north east)-(0,.1)$) -- ($(A.north west)+(\cellleftmargin,-.1)$) -- 
    ($(A.north west)+(\cellleftmargin,.1)$) -- ($(A.north east)+(0,.1)$) -- cycle;
\end{pgfonlayer}}}

% Define the environment which puts the frame
% In this case, the environment also accepts an argument with an optional
% title (which defaults to ``Example'', which is typeset in a box overlaid
% on the top border
\newenvironment{notebookcell}[1][0]{%
\def\FrameCommand{\notebookcellframe}%
\def\FirstFrameCommand{\notebookcellframetop}%
\def\LastFrameCommand{\notebookcellframebottom}%
\def\MidFrameCommand{\notebookcellframemiddle}%
\par\vspace{1\baselineskip}%
\MakeFramed {\FrameRestore}%
\noindent\tikz\node[inner sep=0em] at ($(A.north west)-(0,0)$) {%
\begin{minipage}{\cellleftmargin}%
\hfill%
{\smaller%
\tt%
\color{nbframe-in-prompt}%
In [#1]:}%
\hspace{\inputpadding}%
\hspace{2pt}%
\hspace{3pt}%
\end{minipage}%%
}; \par}%
{\endMakeFramed}




\sloppy % Prevent overflowing lines due to hard-to-break entities

% Setup hyperref package
\hypersetup{
breaklinks=true,  % so long urls are correctly broken across lines
colorlinks=true,
urlcolor=blue,
linkcolor=darkorange,
citecolor=darkgreen,
}

% Slightly bigger margins than the latex defaults

\geometry{verbose,tmargin=1in,bmargin=1in,lmargin=1in,rmargin=1in}



% Override to specify your own logo
\newcommand{\sphinxlogo}{}

% Make the index page of the document.
\makeindex



\begin{document}

\maketitle


This is a \emph{simple} notebook

% Add contents below.

{\par%
\vspace{-1\baselineskip}%
\needspace{4\baselineskip}}%
\begin{notebookcell}[1]%
\begin{addmargin}[\cellleftmargin]{0em}% left, right
{\smaller%
\par%
%
\vspace{-1\smallerfontscale}%
\begin{Verbatim}[commandchars=\\\{\}]
\PY{k}{print}\PY{p}{(}\PY{l+s}{"}\PY{l+s}{Which has a simple task}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{Seriously...}\PY{l+s}{"}\PY{p}{)}
\PY{k}{print}\PY{p}{(}\PY{l+s}{"}\PY{l+s}{Cool!}\PY{l+s}{"}\PY{p}{)}
\end{Verbatim}
%
\par%
\vspace{-1\smallerfontscale}}%
\end{addmargin}
\end{notebookcell}

\par\vspace{1\smallerfontscale}%
% Only render the prompt if the cell is pyout.  Note, the outputs prompt 
% block isn't used since we need to check each indiviual output and only
% add prompts to the pyout ones.
%
%
\begin{addmargin}[\cellleftmargin]{0em}% left, right
{\smaller%
\vspace{-1\smallerfontscale}%

\begin{Verbatim}[commandchars=\\\{\}]
Which has a simple task
Seriously...
Cool!
\end{Verbatim}
}%
\end{addmargin}%
% Add contents below.

{\par%
\vspace{-1\baselineskip}%
\needspace{4\baselineskip}}%
\begin{notebookcell}[2]%
\begin{addmargin}[\cellleftmargin]{0em}% left, right
{\smaller%
\par%
%
\vspace{-1\smallerfontscale}%
\begin{Verbatim}[commandchars=\\\{\}]
\PY{l+s}{"}\PY{l+s}{To print hello world}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{Multiple lines}\PY{l+s}{"}
\end{Verbatim}
%
\par%
\vspace{-1\smallerfontscale}}%
\end{addmargin}
\end{notebookcell}

\par\vspace{1\smallerfontscale}%
% Only render the prompt if the cell is pyout.  Note, the outputs prompt 
% block isn't used since we need to check each indiviual output and only
% add prompts to the pyout ones.

{\par%
\vspace{-1\smallerfontscale}%
\noindent%
\begin{minipage}{\cellleftmargin}%
\hfill%
{\smaller%
\tt%
\color{nbframe-out-prompt}%
Out[2]:}%
\hspace{\inputpadding}%
\hspace{0em}%
\hspace{3pt}%
\end{minipage}%%
}%
%
%
\begin{addmargin}[\cellleftmargin]{0em}% left, right
{\smaller%
\vspace{-1\smallerfontscale}%



\begin{verbatim}
'To print hello world\nMultiple lines'
\end{verbatim}


}%
\end{addmargin}%

\end{document}

答案1

正如注释中所述,代码在行尾缺少几个“%,这将被解释为单词空格,从而导致水平偏移

所以

\def\notebookcellframe#1{

应该

\def\notebookcellframe#1{%

垂直跳跃周围的代码也非常脆弱。

\needspace{4\baselineskip}%    
\begin{notebookcell}[((( cell.prompt_number )))]
\begin{addmargin}[\cellleftmargin]{0em} % left, right
\smaller%
\vspace{-1\baselineskip}%
\vspace{-1\borderthickness}%
((( cell.input | highlight2latex )))%
\vspace{-1\baselineskip}%
\end{addmargin}

我没有看到定义,addmargin但我认为内容以垂直模式开始。

\needsspace测试使用 baselineskip 的外部(较大)值。

\smaller是字体更改,因此会(立即)更改字体大小,并且 baselineskip 也会立即更改,尽管用于文本的有效值取决于段落是否在当前范围内结束(即 的定义\endaddmargin

\smmaller

\def\smaller{\fontsize{9.5pt}{9.5pt}\selectfont}

将 9.5pt 字体设置为 9.5pt 目标基线,因此通常这是不可能的,因此\baselineskip实际上将不会被使用,而是\lineskip会被使用,通常基线空间比字体大小大约大约 10-12%。

假设addmargin以垂直模式启动,那么

\vspace{-1\baselineskip}%
\vspace{-1\borderthickness}%

现在将添加负空间(使用 9.5pt \baselineskip)/如果addmargin以水平模式启动,则这些空间将保持在\vadjust节点中并添加下列的下一行文本。您可以将\par它们放在前面,以确保您处于 vmode 中。

然后将文本设置为小字体

\vspace{-1\baselineskip}%

以水平模式解释,因此在 vadjust 节点中保存直到段落结束,大概在某个地方的定义中\enddaddmargin。同样,您可能希望将\par其放在 之前\vskip

如果你得到这些空间周围的不同布局,原因可能是addmarginnotebookcell

  • 在开头添加一个框或写入节点或某种特殊内容

或者

  • 重新定义事物以便addmargin从水平模式开始

或者

  • 重新定义事物,因此有一个额外的组层,并且该组在小文本段落之前结束,因此它与原始较大的基线一起设置。

答案2

导致您出现问题的主要原因是 Sphinx Verbatim 使用自身framed.styframed.sty引入了垂直空间,而您的代码根本没有尝试控制这些空间。此外,如果框架以水平模式启动,情况会非常复杂。我使用当前的 Sphinx 尝试解决了您的问题。

删除每次使用环境时积累的所有垂直空间notebookcell,再加上In[1]:不进入段落模式(也不使用令人困惑的 TikZ)绘制,只剩下\smallskipSphinx 始终将其插入框架顶部的。然后我们使用条件来告诉 verbatim 它已经在框架环境中(然后必须在 minipage 内完成);此条件仅在较新的 Sphinx 版本中存在(在较早的版本中没有理由这样做,因为没有 Verbatim 会在另一个 Verbatim 内结束……但较新的 Sphinx 用于framed其他用途)。

结果:

在此处输入图片描述

该规则是为了显示一致性。

代碼notebookcell

\newenvironment{notebookcell}[1][0]{\sphinxverbatimwithminipagetrue
\def\FrameCommand{\notebookcellframe}%
\def\FirstFrameCommand{\notebookcellframetop}%
\def\LastFrameCommand{\notebookcellframebottom}%
\def\MidFrameCommand{\notebookcellframemiddle}%
\par\MakeFramed {\FrameRestore}%
\vspace{\baselineskip}%
\hbox{{\smash{\makebox[\cellleftmargin][r]{%
\smaller
       \tt\color{nbframe-in-prompt}In [#1]:%
\hspace{\inputpadding}\hspace{5pt}}%
}}\hss}%
\vspace{-\baselineskip}%
\vspace{-\smallskipamount}%
}%
{\endMakeFramed}


\def\x{\llap{\rule{2cm}{0.1pt}}\rlap{\rule{3cm}{0.1pt}}}

使用代码notebookcell(各种垂直跳跃均已被移除):

\begin{notebookcell}[1]%
\begin{addmargin}[\cellleftmargin]{0em}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\x\PYG{k}{print}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{Which has a simple task}\PYG{l+s+se}{\PYGZbs{}n}\PYG{l+s}{Seriously...}\PYG{l+s}{"}\PYG{p}{)}
\PYG{k}{print}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{Cool!}\PYG{l+s}{"}\PYG{p}{)}
\end{sphinxVerbatim}
\end{addmargin}
\end{notebookcell}

另一个也类似。除此之外,您还需要获得最近的一份,sphinx.sty并且其中一份获得上述内容。

相关内容