LaTeX Beamer 中方程式和文本的彩色下划线

LaTeX Beamer 中方程式和文本的彩色下划线

之前有一个问题问过如何用颜色给方程式加下划线(1)。然而,建议的许多解决方案在 LaTeX Beamer 中不起作用。我也很难找到简单的自定义方法,例如调整下划线的粗细。Beamer 中彩色下划线的有希望的努力已经做出(2),但我还没有看到满足以下所有主要标准的解决方案:

  1. 在 LaTex Beamer 中用彩色下划线显示文本和公式
  2. 可调整下划线粗细
  3. 与 Beamer 叠加兼容,具体而言,叠加下划线不会改变幻灯片内的垂直间距
  4. 长下划线表达式不会强制提前换行,而是下划线会延伸到两行文本。

以下是示例幻灯片的代码

\documentclass{beamer}

\useinnertheme{default}
\beamertemplatenavigationsymbolsempty

\begin{document}

\begin{frame}{Coloured Underlining}

  Different parts of text can be underlined, using colours
  such as green, red. The thickness of the underline can be set.

  \vfill

  Underlining is consistent with Beamer overlays.

  \vfill

  Underlining works as well in equations such
  as $f(x) = \lambda\, e^x$ and

  \begin{align*}
    \mu = \frac{1}{2} \int_0^1 x f_{P_{ij}}(x)\,dx
    + \frac{1}{2} \int_0^1 f_{P_{ij}}(x)
    \int_0^1 y \,f_{P_{ji}\vert P_{ij}}(y \mid x) \,dy \, dx.
  \end{align*}

  \vfill

  Underlining longer expressions doesn't lead to lines
  breaking early, but rather the underline stretches
  across two lines of text.

\end{frame}
\end{document}

如何实现下划线命令,使幻灯片中的下划线尽可能接近下图?

在此处输入图片描述


答案1

正如您所发现的,有几种实现下划线的技术,但没有一种(我所知道的)能够满足您的所有要求。

因此,我编写了一个包装器\myul,它根据上下文(数学模式或正常模式)选择一种技术用于此情况。使用可选参数,您可以手动指定颜色、厚度、深度和技术。您可以使用命令更改整个当前组的这些设置\setmyul。对于某些选项,可以为数学模式或文本模式指定不同的值。有关更多详细信息,请参阅代码中的注释。

有时需要运行两次。

\documentclass{beamer}

\usepackage{soul}
\usepackage{pgfkeys}
\usepackage{mathstyle}
\usepackage{transparent}

\makeatletter

% ---------- key=value options ----------

\newif\if@myul@math@usedistance@
\newif\if@myul@text@usedistance@

\newcommand\@myul@text@depth{\SOUL@uldepth}
\newcommand\@myul@math@depth{\SOUL@uldepth}

\pgfqkeys{/myul}{
    % thickness of the rule
    thickness/.code={\setul{}{#1}},
    %
    % distance from baseline where to place the top of the rule
    depth/.style={%
        math depth=#1,
        text depth=#1,
    },
    math depth/.code={%
        \@myul@math@usedistance@false
        \def\@myul@math@depth{#1}%
    },
    text depth/.code={%
        \@myul@text@usedistance@false
        \setul{#1}{}%
    },
    %
    % distance from bottom edge of box where to place the top of the rule
    % works only with command = box
    distance/.style={%
        math distance=#1,
        text distance=#1,
    },
    math distance/.code={%
        \@myul@math@usedistance@true
        \def\@myul@math@distance{#1}%
    },
    text distance/.code={%
        \@myul@text@usedistance@true
        \def\@myul@text@distance{#1}%
    },
    %
    % color in which to draw the rule (not the text)
    color/.code={\setulcolor{#1}},
    %
    % which implementation technique to use
    command/.style={%
        text command=#1,
        math command=#1,
    },
    %
    text command/.is choice,
    text command/soul/.code     ={\let\@myul@text@do=\@myul@soul},
    text command/box/.code      ={\let\@myul@text@do=\@myul@box},
    text command/primitive/.code={\let\@myul@text@do=\@myul@primitive},
    %
    math command/.is choice,
    math command/soul/.code     ={\let\@myul@math@do=\@myul@soul},
    math command/box/.code      ={\let\@myul@math@do=\@myul@box},
    math command/primitive/.code={\let\@myul@math@do=\@myul@primitive},
    %
    % what to do if key is none of the above defined
    .unknown/.code={%
        % only process keys for which no full path has been provided
        % TikZ documentation, page 900
        \ifpgfkeysaddeddefaultpath
            \let\@myul@currentname=\pgfkeyscurrentname
            \pgfkeysalso{%
                command/\@myul@currentname/.try,
                color/.lastretry=\@myul@currentname,
            }%
        \else
            \def\pgfutilnext{\pgfkeysvalueof {/handlers/.unknown/.@cmd}#1\pgfeov}%
            \pgfutilnext
        \fi
    },
}


% ---------- user interface ----------

\newcommand{\setmyul}[1]{%
    \pgfqkeys{/myul}{#1}%
}

\newcommand<>{\myul}[2][black]{%
    \begingroup
        \setmyul{#1}%
        \ifmmode
            \expandafter \@myul@math@do
        \else
            \expandafter \@myul@text@do
        \fi
        #3{#2}%
    \endgroup
}

% for auto completion in TeXstudio
\providecommand{\myul}[1]{}


% ---------- using soul package ----------
% based on soul package
% supports line break
% the text to be underlined can *not* be arbitrary TeX code
% see soul package documentation [November 17, 2003] page 5
% does *not* work in math mode

\newcommand<>{\@myul@soul}[1]{%
    %https://tex.stackexchange.com/a/41693/120953
    \let\set@color=\beamerorig@set@color
    \let\reset@color=\beamerorig@reset@color
    \alt#2{%
        \ul{#1}%
    }{%
        \def\SOUL@ulcolor{\texttransparent{0.0}}%
        \ul{#1}%
    }%
}


% ---------- using boxes ----------
% based on:
% https://tex.stackexchange.com/a/9472/120953
% https://tex.stackexchange.com/a/1236/120953
% does *not* support line breaks

\newsavebox\@myul@box@tmpbox

\newcommand<>{\@myul@box}[1]{%
    \ifmmode
        \sbox\@myul@box@tmpbox{$\m@th \currentmathstyle #1$}%
        \if@myul@math@usedistance@
            \def\@myul@box@useddepth{\dimexpr-\dp\@myul@box@tmpbox-\@myul@math@distance-\SOUL@ulthickness}%
        \else
            \def\@myul@box@useddepth{\dimexpr-\@myul@math@depth-\SOUL@ulthickness}%
        \fi
    \else
        \sbox\@myul@box@tmpbox{#1}%
        \if@myul@text@usedistance@
            \def\@myul@box@useddepth{\dimexpr-\dp\@myul@box@tmpbox-\@myul@text@distance-\SOUL@ulthickness}%
        \else
            \def\@myul@box@useddepth{\dimexpr-\@myul@text@depth-\SOUL@ulthickness}%
        \fi
    \fi
    \usebox\@myul@box@tmpbox%
    \alt#2{%
        \llap{%
            % \SOUL@ulcolor = \textcolor{<color>}
            \SOUL@ulcolor{%
                \rule[\@myul@box@useddepth]{\wd\@myul@box@tmpbox}{\SOUL@ulthickness}%
            }%
        }%
    }{%
        \rule[\@myul@box@useddepth]{0pt}{\SOUL@ulthickness}%
    }%
}


% ---------- using TeX primitive ----------
% In plain TeX \underline is a primitive 
% which can be used in math mode only.
% In LaTeX \underline is overridden 
% so that it can be used outside of math mode, too.
% Either way, it does *not* support line breaks.
% Thickness and depth are *not* freely adjustable.
% thickness = $\theta$, distance to underline = $3\theta$
% where $\theta=\xi_8$ default rule thickness
% [The TeXbook, page 443, rule 10]
% default rule thickness can be changed with:
% \fontdimen8\textfont3=5pt
% default rule thickness is 0.4pt
% https://tex.stackexchange.com/a/167957/25264
% Changing the default rule thickness 
% changes the thickness of fraction bars, too.
% Therefore this command ignores the thickness and depth options.
% You should avoid this method to avoid inconsistencies.

% based on https://gist.github.com/lucaswerkmeister/3f7672ee522f7e823cec63fdc85fd7aa
\newcommand<>{\@myul@primitive}[1]{%
    % colored underline: https://tex.stackexchange.com/a/9477/25264
    % transparent underline: https://tex.stackexchange.com/a/45601/25264
    % switch between colored and transparent: http://mirrors.ibiblio.org/CTAN/macros/latex/contrib/beamer/doc/beameruserguide.pdf sections 9.3 and 9.6.1
    % \SOUL@ulcolor = \textcolor{<color>}
    \let\textcolor=\color
    \alt#2%
        {\SOUL@ulcolor\underline{{\color{black}#1}}\color{black}}%
        {\transparent{0.0}\underline{{\transparent{1.0}#1}}\transparent{1.0}}%
}

\makeatother


% ---------- default settings ----------

\setmyul{
    text command=soul,
    math command=box,
}



% ---------- test ----------

\setmyul{math distance=.5ex}

\useinnertheme{default}
\beamertemplatenavigationsymbolsempty


% based on https://tex.stackexchange.com/questions/14821/whats-the-proper-way-to-typeset-a-differential-operator
\newcommand{\dif}{\ensuremath{\operatorname{d}\!}}


\begin{document}

\begin{frame}{Coloured Underlining}

    Different parts of text can be underlined, using colours such as \myul[color=green]{green}, \myul[red]{red}. 
    The \myul[thickness=2pt]{thickness} of the underline can be set.
    Additionally, the \myul[depth=1pt]{depth} of the underline can be set, too.

    \vfill

    Underlining is consistent with \myul<2->{Beamer} \myul<3->[thickness=5pt]{overlays}.

    \vfill

    Underlining works as well in equations such
    as $f(x) = \lambda\, e^x$ and


    \begin{align*}
        \mu = \myul<2->[red]{\frac{1}{2} \int_0^1 x \, f_{P_{ij}}(x) \dif x} 
            + \frac{1}{2} \int_0^1 f_{P_{ij}}(x) 
              \int_0^1 \myul<3->[red, thickness=5pt]{y \,f_{P_{ji}\vert P_{ij}}(y \mid x)} \dif y \dif x.
    \end{align*}

    \vfill


    Underlining longer expressions doesn't lead to \myul{lines breaking early, but rather the underline} stretches across two lines of text.

\end{frame}
\end{document}

在此处输入图片描述

答案2

尽管我使用框作为逻辑的一部分,但通过我最近的编辑,这一切都完成了包括非常重要的自动换行。它还可以无缝处理数学与文本模式。语法是

\bunderline[<color>][<thickness>]{content}

\buonslide[<color>][<thickness>]<<beamer-slide-spec>>{content}

事实上,对于文本模式\bunderline,我将下划线的底部设置在相同的位置( a 的底部\strut),并随着厚度的增加而向上增长。(如果它从那里向下增长,它会弄乱行距)

2pt对于数学模式下划线,内容和下划线之间有一个恒定的间隙。数学模式下划线可以嵌套,并且还可以保留当前的数学样式:

在此处输入图片描述

编辑:感谢 Jakun 提醒添加\m@th到数学模式中\setbox0,以关闭任何\mathsurround,以防它被设置为除之外的其他内容0pt

妇女权利委员会:

\documentclass{beamer}
\usepackage{scalerel,stackengine}
\def\buthickness{1pt}
\def\budefaultcolor{black}
\makeatletter
\newcommand\bunderline[1][\budefaultcolor]{\def\bucolor{#1}\bunderlineaux}
\newcommand\bunderlineaux[2][\buthickness]{%
  \ThisStyle{%
  \ifmmode%
    \setbox0=\hbox{\m@th$\SavedStyle#2$}
    \stackunder[2pt]{\copy0}{\textcolor{\bucolor}{\rule{\wd0}{#1}}}%
  \else%
    \xdef\butmpthickness{#1}%
    \prebunderlinewords#2 \endarg%
  \fi%
}}
\def\prebunderlinewords#1 #2\endarg{%
  \ifx\endarg#2\endarg\def\wdaugment{0pt}\else\def\wdaugment{.8ex}\fi%
  \bunderlinewords#1 #2\endarg%
}
\def\bunderlinewords#1 #2\endarg{%
    \setbox0=\hbox{#1\strut}%
    \stackengine{0pt}{\copy0}{\textcolor{\bucolor}{%
      \smash{\rule{\dimexpr\wd0+\wdaugment\relax}{\butmpthickness}}}}{U}{c}{F}{T}{S}% 
    \ifx\endarg#2\endarg\def\next{}\else\ \def\next{\bunderlinewords#2\endarg}\fi\next%
}
\newcommand\buonslide[1][black]{\def\butmpcolor{#1}\buonslideauxA}
\newcommand\buonslideauxA[1][\buthickness]{\def\butmpthickness{#1}\buonslideauxB}
\def\buonslideauxB<#1>#2{\onslide<#1>{%
  \rlap{\bunderline[\butmpcolor][\butmpthickness]{\phantom{#2}}}}#2}
\makeatother
\useinnertheme{default}
\beamertemplatenavigationsymbolsempty

\begin{document}

\begin{frame}{Coloured Underlining}
\setlength\mathsurround{2pt}
  Different parts of text can be \bunderline{underlined}, using colours
  such as \bunderline[green]{green}, \bunderline[red]{red}. 
  The \bunderline[black][3pt]{thickness} of the underline can be set.

  \vfill

  Underlining is consistent with \buonslide[red]<2->{Beamer}
    \buonslide[red][2pt]<3->{overlays}.

  \vfill

  Underlining works as well in equations such
  as $f(x) = \lambda\, e^x$ and

  \begin{align*}
    \mu = \bunderline[red]{\frac{1}{2} \int_0^1 x f_{P_{ij}}(x)\,dx}
    + \frac{1}{2} \int_0^1 f_{P_{ij}}(x)
    \int_0^1 \bunderline[red]{
      y \,f_{P_{\bunderline[cyan]{ji}}\vert P_{ij}}(y \mid x)} \,dy \, dx.
  \end{align*}

  \vfill

  Underlining longer expressions doesn't \bunderline{lead to lines
  breaking early, but rather the underline} stretches
  across two lines of text.

\end{frame}
\end{document}

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述

相关内容