如何对齐框架的顶线?

如何对齐框架的顶线?

我想对齐左右框架的顶线。该怎么做?

在此处输入图片描述

\documentclass[12pt]{book}
\usepackage[a4paper,margin=25mm,showframe=true]{geometry}
\usepackage{xcolor}

\usepackage{accsupp}
\newcommand*{\noaccsupp}[1]{\BeginAccSupp{ActualText={}}#1\EndAccSupp{}}

\usepackage{showexpl}

\lstset
{
    language={[LaTeX]TeX},
    alsolanguage={PSTricks},
    numbers=left,
    numbersep=1em,
    numberstyle=\tiny\color{red}\noaccsupp,
    frame=single,
    framesep=\fboxsep,
    framerule=\fboxrule,
    rulecolor=\color{red},
    xleftmargin=\dimexpr\fboxsep+\fboxrule\relax,
    xrightmargin=\dimexpr\fboxsep+\fboxrule\relax,
    breaklines=true,
    basicstyle=\small\tt,
    keywordstyle=\color{blue},
    %identifierstyle=\color{magenta},
    commentstyle=\color[rgb]{0.13,0.54,0.13},
    backgroundcolor=\color{yellow!10},
    tabsize=2,
    columns=flexible,
    explpreset={pos=r},
    morekeywords={
        graphicspath,
        includegraphics,
    },
}




\begin{document}
\LTXexample
How to align the top lines of frames?\\
How to align the top lines of frames?
\endLTXexample
How to align the top lines of frames?
\LTXexample
How to align the top lines of frames?\\
How to align the top lines of frames?
\endLTXexample
\end{document}

注意:仅当使用或accsupp编译此输入文件时才有效。使用 编译后跟和将不会生成允许我们不复制行号的 PDF 输出。xelatexpdflatexlatexdvipsps2pdf

答案1

我将尝试解释问题所在,以及可能的解决方法。请注意,解决方法非常丑陋!

问题位于showexpllistings包(listingsshowexpl)的代码中的不同位置。

该包的工作方式如下:它将代码输出到中间文件中,然后使用listings包输入代码并将其排版为格式良好,带有列表选项(在您的例子中,周围有一个红色框)。最后,它将通过 TeX “执行”该代码的结果存储到临时框中,并将该框也输出,与 创建的框并排listings

因此,问题是如何对齐由listings(红色框)创建的框和由乳胶创建的框(在您的示例中用黑色框)。

该包showexpl使用 parbox 来创建两个框,因此显然在适当的位置插入 [t] 就足够了,这样就可以获得“顶部对齐”的 parbox。因此,第一个猜测是将以下内容添加到您的序言中(在包含showexpl包之后):

\makeatletter
 \renewcommand\SX@CodeArea[2]{%
   \parbox[t]{#1}{#2}
   \rlap{\parbox[t]{#1}{\SX@attachfile}}}
\renewcommand\SX@ResultArea[2]{%
  \SX@justification%
  \parbox[t]{#1}{#2}%
}
\makeatother

但是,仅此还不行。现在两个 parbox 是“顶部”对齐的,但“顶部”对齐仅意味着“将 parbox 的基线移动到 parbox 第一行的基线”。

不起作用的示例

问题在于,左框(红色框)和右框(黑色框)对于“第一行”的概念不同。我们必须\hbox{}在两个 parbox 的开头插入一个空的第一行(“空框”或),以便它们正确对齐。

为了\hbox{}在左侧框的开头插入,我们必须listings在呈现列表之前插入该命令。这可以使用listings basicstyle选项完成:(basicstyle=\small\tt\hbox{},呸!)

为了\hbox{}在右侧框的开头插入一个,我们必须修改showexpl构建该框的代码(称为\SX@ResBox)。不幸的是,该代码深埋在宏定义(\SX@put@code@result)中,因此我们必须重写整个宏(63 行代码!)才能更改其中的两行。

因此最终完整的代码是:

\documentclass[12pt]{book}
\usepackage[a4paper,margin=25mm,showframe=true]{geometry}
\usepackage{xcolor}

\usepackage{accsupp}
\newcommand*{\noaccsupp}[1]{\BeginAccSupp{ActualText={}}#1\EndAccSupp{}}

\usepackage{showexpl}
\makeatletter

% Add [t] to the parbox
\renewcommand\SX@CodeArea[2]{%
   \parbox[t]{#1}{#2}
   \rlap{\parbox[t]{#1}{\SX@attachfile}}}

% Add [t] to the parbox
\renewcommand\SX@ResultArea[2]{%
  \SX@justification%
  \parbox[t]{#1}{#2}%
}

% Add \hbox{} at the creation of \SX@ResBox, look up the comment
\renewcommand*\SX@put@code@result{%
  \begingroup
    \expandafter\lstset\expandafter{\SX@explpreset}%
    \let\lst@float=\relax\let\SX@float=\relax
    \expandafter\lstset\expandafter{\SX@@explpreset}%
    \ifx\lst@float\relax\else
      \let\SX@float=\lst@float\let\lst@float=\relax
      \g@addto@macro\SX@@explpreset{,float=false}%
      \edef\@tempa{\noexpand\lst@beginfloat{lstlisting}[\SX@float]}%
      \expandafter\@tempa
    \fi
    \ifx\lst@caption\@empty
      \lstset{nolol=true}%
    \fi
    \if@SX@wide\def\SX@overhang{\marginparwidth+\marginparsep}\fi
    \trivlist\item\relax
      \stepcounter{ltxexample}\label{\SX@IDENT}%
      \SX@defaultWD\SX@width{\SX@width}%
      \ifdim\SX@width<\z@
        \@tempswatrue
        \def\@tempa{t}%
        \ifx\@tempa\SX@pos\@tempswafalse\fi
        \def\@tempa{b}%
        \ifx\@tempa\SX@pos\@tempswafalse\fi
        \setlength\@tempdima{\linewidth+\SX@overhang}%
        \if@tempswa\@tempdima=.5\@tempdima\fi%
        \edef\SX@width{\the\@tempdima}%
      \fi
      \ifx\SX@rframe\@empty
        \long\def\SX@frame##1{##1}%
      \else
        \let\SX@frame\fbox
        \setlength\@tempdima{\SX@width-2\fboxsep-2\fboxrule}%
        \edef\SX@width{\the\@tempdima}%
      \fi
      \isSX@odd{\def\@tempa{l}}{\def\@tempa{r}}%
      \makebox[\linewidth][\@tempa]{%
        \parbox{\linewidth+\SX@overhang}{%
          \let\@addtofilelist\@gobble
          \let\lst@ifdisplaystyle=\iftrue
          \SX@KillAboveCaptionskip\lst@MakeCaption{t}%
          \lst@belowskip=\z@
          \let\SX@MakeCaption\lst@MakeCaption
          \let\lst@MakeCaption\@gobble
          \setbox\SX@ResBox\vtop{\hbox{}\hbox{%    <---- HERE, modified line
            \SX@frame{%
              \@nameuse{\if@SX@varwidth varwidth\else minipage\fi}%
                \SX@width\relax\SX@resultInput%
                \@nameuse{end\if@SX@varwidth varwidth\else minipage\fi}}}}% <-- Also here, to close a brace
          \edef\SX@width{\the\wd\SX@ResBox}%
          \@ifundefined{SX@put@\SX@pos}%
            {\@latex@error{Parameter `\SX@pos' undefined}\@ehd}%
          {\@nameuse{SX@put@\SX@pos}%
            {\SX@width}{\box\SX@ResBox}{\SX@codeInput}}%
          \let\lst@MakeCaption\SX@MakeCaption
          \lst@MakeCaption{b}\SX@KillBelowCaptionskip
        }%
      }%
    \endtrivlist
    \ifx\SX@float\relax\else\expandafter\lst@endfloat\fi
    \gdef\SX@@explpreset{}%
  \endgroup
}
\makeatother

\lstset
{
    language={[LaTeX]TeX},
    alsolanguage={PSTricks},
    numbers=left,
    numbersep=1em,
    numberstyle=\tiny\color{red}\noaccsupp,
    frame=single,
    framesep=\fboxsep,
    framerule=\fboxrule,
    rulecolor=\color{red},
    xleftmargin=\dimexpr\fboxsep+\fboxrule\relax,
    xrightmargin=\dimexpr\fboxsep+\fboxrule\relax,
    breaklines=true,
    basicstyle=\small\tt\hbox{},  % <--- Add \hbox{} here too
    keywordstyle=\color{blue},
    %identifierstyle=\color{magenta},
    commentstyle=\color[rgb]{0.13,0.54,0.13},
    backgroundcolor=\color{yellow!10},
    tabsize=2,
    columns=flexible,
    explpreset={pos=r},
    morekeywords={
        graphicspath,
        includegraphics,
    },
}


\begin{document}
\LTXexample
How to align the top lines of frames?\\
How to align the top lines of frames?
\endLTXexample
How to align the top lines of frames?
\LTXexample
How to align the top lines of frames?\\
How to align the top lines of frames?
\endLTXexample
\end{document}

哪个能正常工作

工作结果

答案2

使用 TikZ 的“简单”解决方法:

\documentclass[12pt]{book}
\usepackage[a4paper,showframe=true]{geometry}
\usepackage{xcolor}
\usepackage{tikz}
\usepackage{accsupp}
\newcommand*{\noaccsupp}[1]{\BeginAccSupp{ActualText={}}#1\EndAccSupp{}}
\usepackage{showexpl}

\makeatletter
\renewcommand*\SX@put@r[3]{%
  \setlength\@tempdimc{\linewidth-#1-\SX@hsep}%
  \begin{tikzpicture}[baseline={(expl.north)}]
    \node[draw=red,anchor=base west,line width=1pt,inner sep=1pt,fill=yellow!10]
    (expl){\SX@CodeArea{\@tempdimc}{#3}};
  \end{tikzpicture}%
  \hfill%
  \tikz[baseline={(expl.north)}]\node[inner sep=0pt]%
  (expl){\SX@ResultArea{#1}{#2}};
}
\makeatother

\lstset
{
      language={[LaTeX]TeX},
      alsolanguage={PSTricks},
      numbers=left,
      numbersep=1em,
      numberstyle=\tiny\color{red}\noaccsupp,
      rulecolor=\color{red},
      breaklines=true,
      basicstyle=\small\tt,
      keywordstyle=\color{blue},
      %identifierstyle=\color{magenta},
      commentstyle=\color[rgb]{0.13,0.54,0.13},
      tabsize=2,
      columns=flexible,
      explpreset={pos=r},
      morekeywords={
          graphicspath,
          includegraphics,
      },
}

\begin{document}
\begin{LTXexample}
How to align the top lines of frames?\\
How to align the top lines of frames?
\end{LTXexample}
How to align the top lines of frames?
\begin{LTXexample}
How to align the top lines of frames?\\
How to align the top lines of frames?
\end{LTXexample}
\end{document}

答案3

加载包后定义showexpl

\makeatletter
\renewcommand\SX@CodeArea[2]{%
  \setlength\@tempdima{#1}%
  \sbox\@tempboxa{\parbox\@tempdima{#2}}%
  \@tempdima=\dp\@tempboxa\raisebox{\dimexpr -\baselineskip-\fboxsep-\fboxrule-2pt}{\usebox\@tempboxa}
  \rlap{\raisebox{-\@tempdima}[0pt][0pt]{\SX@attachfile}}}
\makeatother

2pt 是跨行

在此处输入图片描述

相关内容