文本、边距和文本 + 边距宽度浮动,无需使用 tufte 类

文本、边距和文本 + 边距宽度浮动,无需使用 tufte 类

我想使用和类中定义的marginfigurefigure*和环境(分别参见figuretufte-booktufte-handout模板示例)。

这意味着能够使用以下环境:

  • marginfigure页边距中具有宽度的图形\marginparwidth,其标题位于页边距下方;
  • figure正文中带有的图形\textwidth,其标题位于边距之外(且底部对齐);
  • figure*正文和边距上方有一张具有\textwidth + \marginparsep + \marginparwidth宽度的图形,标题位于边距下方。

在此处输入图片描述

但是,由于我的大部分源代码都是用于KOMAscript课程的,所以我不想tufte仅仅因为这个而切换到其中一个课程。

问题:如何模拟tufte课外的环境?


这个问题已经解决了接受的答案,即使用sidenotes-package。但是,为了防止其他人走我走过的弯路/死胡同,我在下面分享了我解决问题的尝试。它将我的问题的先前版本汇总在一起。

内容:

  1. 相关软件包和 TeX.SE 问题,
  2. marginfigure使用包的成功解决方法capt-of
  3. 尝试模拟tufte类源代码之外的环境:
    • 成功(但笨重)marginfigure
    • 失败的figurefigure*

1. 相关软件包和 TeX.SE 问题

我知道floatrow包,但即使它对于figure和来说看起来很棒figure*,我还是找不到如何处理marginfigure

我还发现实现 marginfigure以另一种方式解决问题。

marginfigure2.使用capt-of包的成功解决方法

我找到了一种marginfigure使用capt-of包的解决方法,如下所述这里

\documentclass{scrartcl}
    \usepackage{graphicx}
    \usepackage{showframe}
    \usepackage{capt-of}
\begin{document}
    Some text.
    \marginpar{%
        \includegraphics[width=\marginparwidth]{example-image}%
        \captionof{figure}{My caption}%
    }%
    More text.

    Another paragraph
\end{document}

这很好,但不能解决figure问题figure*

3. 尝试在tufte类源代码之外模拟环境

我已经阅读了源代码,并且由于所有内容都已实现(+管理浮点数等),我的想法是重新实现tufte-common.def可用的命令加拿大运输安全局重现这些环境。

因此,我尝试调整在tufte-common.def以使它们独立。

我成功了,但是当我重新定义和marginfigure时编译失败。figurefigure*

  • marginfigure:我成功复制了tufte-bookclasse的marginfigure环境。

请参阅下文的 MWE。

\documentclass[twoside]{scrartcl}
    \usepackage{showframe}
    \usepackage{graphicx}
    \usepackage{placeins}

    \usepackage[a4paper,left=24.8mm,top=27.4mm,headsep=2\baselineskip,textwidth=107mm,marginparsep=8.2mm,marginparwidth=49.4mm,textheight=49\baselineskip,headheight=\baselineskip]{geometry} % tufte-handout definitions

\makeatletter
        \input{my-tufte-marginfigure}
\makeatother

\begin{document}
    \noindent
    Say what?!

    \begin{marginfigure}%
        \includegraphics[width=\marginparwidth]{example-image-a}
        \caption{My caption}
    \end{marginfigure}
\end{document}

my-tufte-marginfigure以下摘录在哪里tufte-common.def

\usepackage{ragged2e}

\newcommand{\@tufte@marginfont}{\normalfont\footnotesize\sffamily}
\newcommand*{\@tufte@caption@font}{\@tufte@marginfont}
\newcommand*{\@tufte@caption@justification}{\justifying} %% or \RaggedLeft or \RaggedRight 

% Paragraph indentation and separation for marginal text
\newcommand{\@tufte@margin@par}{%
    \setlength{\RaggedRightParindent}{0.5pc}%
    \setlength{\JustifyingParindent}{0.5pc}%
    \setlength{\parindent}{0.5pc}%
    \setlength{\parskip}{0pt}%
}

\newsavebox{\@tufte@margin@floatbox}

\newenvironment{@tufte@margin@float}[2][-1.2ex]%
{\FloatBarrier% process all floats before this point so the figure/table numbers stay in order.
    \begin{lrbox}{\@tufte@margin@floatbox}%
        \begin{minipage}{\marginparwidth}%
            \@tufte@caption@font% %%some font definition%%
            \def\@captype{#2}%
            \hbox{}\vspace*{#1}%
            \@tufte@caption@justification%
            \@tufte@margin@par%
            \noindent%
        }
        {\end{minipage}%
    \end{lrbox}%
    \marginpar{\usebox{\@tufte@margin@floatbox}}%
}


%%
% Margin figure environment

\newenvironment{marginfigure}[1][-1.2ex]%
    {\begin{@tufte@margin@float}[#1]{figure}}%
    {\end{@tufte@margin@float}}

%%
% Margin table environment

\newenvironment{margintable}[1][-1.2ex]%
{\begin{@tufte@margin@float}[#1]{table}}
    {\end{@tufte@margin@float}}
  • figure和:我尝试对和figure*做同样的事情。figurefigure*

但是,编译失败。

\documentclass[twoside]{scrartcl}
    \usepackage{showframe}
    \usepackage{graphicx}
    \usepackage{placeins}
    \usepackage{lipsum}

    \usepackage[a4paper,left=24.8mm,top=27.4mm,headsep=2\baselineskip,textwidth=107mm,marginparsep=8.2mm,marginparwidth=49.4mm,textheight=49\baselineskip,headheight=\baselineskip]{geometry}

\makeatletter
        %\input{my-tufte-marginfigure} %% cf. hereinabove
        \input{my-tufte-figure}
\makeatother

\begin{document}

    \begin{figure}
        \includegraphics[width=\linewidth]{example-image-b}
        \caption{My long caption is not \emph{that} long!}
        \setfloatalignment{b}
    \end{figure}

%   \begin{figure*}[h]
%       \includegraphics[width=\linewidth]{example-image-c}%
%       \caption{Some caption!}%
%   \end{figure*}

\end{document}

my-tufte-figure以下摘录在哪里tufte-common.def。(我知道它很长,但我确信它非常接近最小形式!)

\usepackage{ifthen}
\usepackage{optparams}
\usepackage{fullwidth}
\usepackage{changepage}

%%
% `symmetric' option -- puts marginpar space to the outside edge of the page
%   Note: this option forces the twoside option (see the .cls files)
\newboolean{@tufte@symmetric}
%%\DeclareOptionX[tufte]<common>{symmetric}{
    \setboolean{@tufte@symmetric}{true}
    %%%\@tufte@info@noline{The `symmetric' option implies `twoside'}
    %%%\ExecuteOptionsX[tufte]<common>{twoside}
%%}

%DEBUT
%%
% A collection of macros to be used with the new Tufte-style float environments.
% \setfloatalignment forces the caption placement to be treated as top, bottom, etc.
% \forcerectofloat forces the float to be treated as if it were appearing on a recto page.
% \forceversofloat does the same, but for verso pages.

\newcommand{\@tufte@float@debug@info}{}% contains debug info generated as the float is processed
\newcommand{\@tufte@float@debug}[1]{% adds debug info to the queue for output
    \ifthenelse{\equal{\@tufte@float@debug@info}{}}%
    {\def\@tufte@float@debug@info{#1}}%
    {\g@addto@macro\@tufte@float@debug@info{\MessageBreak#1}}%
}

\newcommand{\floatalignment}{x}% holds the current float alignment (t, b, h, p)
\newcommand{\setfloatalignment}[1]{\global\def\floatalignment{#1}\@tufte@float@debug{Forcing position: [#1]}}% manually sets the float alignment
\newboolean{@tufte@float@recto}
\newcommand{\forcerectofloat}{\gsetboolean{@tufte@float@recto}{true}\@tufte@float@debug{Forcing page: [recto]}}
\newcommand{\forceversofloat}{\gsetboolean{@tufte@float@recto}{false}\@tufte@float@debug{Forcing page: [verso]}}

% Boxes to temporarily store our float and caption
\newsavebox{\@tufte@figure@box}
\newsavebox{\@tufte@caption@box}

    %MANDATORY
% Save original LaTeX float environment
\let\@tufte@orig@float\@float
\let\@tufte@orig@endfloat\end@float
    %MANDATORY/
% New length for tweaking float captions
\newlength{\@tufte@caption@vertical@offset}
\setlength{\@tufte@caption@vertical@offset}{0pt}

% Store the caption and label contents
\newcommand{\@tufte@stored@shortcaption}{}
\newcommand{\@tufte@stored@caption}{}
\newcommand{\@tufte@stored@label}{}

\long\def\@tufte@caption[#1][#2]#3{%
    \ifthenelse{\isempty{#1}}%
    {\gdef\@tufte@stored@shortcaption{#3}}%
    {\gdef\@tufte@stored@shortcaption{#1}}%
    \gsetlength{\@tufte@caption@vertical@offset}{-#2}% we want a positive offset to lower captions
    \gdef\@tufte@stored@caption{#3}%
}

\newcommand{\@tufte@label}[1]{%
    \gdef\@tufte@stored@label{#1}%
}

\newcommand{\@tufte@fps}{}

\newboolean{@tufte@float@star}
\newlength{\@tufte@float@contents@width}
%FIN

%%
% Compute lengths used for full-width displays

\newlength{\@tufte@overhang}% used by the fullwidth environment and the running heads
\newlength{\@tufte@fullwidth}
\newlength{\@tufte@caption@fill}

\newcommand{\TufteRecalculate}{%
    \setlength{\@tufte@overhang}{\marginparwidth}
    \addtolength{\@tufte@overhang}{\marginparsep}

    \setlength{\@tufte@fullwidth}{\textwidth}
    \addtolength{\@tufte@fullwidth}{\marginparsep}
    \addtolength{\@tufte@fullwidth}{\marginparwidth}

    \setlength{\@tufte@caption@fill}{\textwidth}
    \addtolength{\@tufte@caption@fill}{\marginparsep}
}

\AtBeginDocument{\TufteRecalculate}

%%
% Globally sets a boolean

\newcommand*{\gsetboolean}[2]%
    {% based on code from ifthen pkg
        \lowercase{\def\@tempa{#2}}%
        \@ifundefined{@tempswa\@tempa}%
        {\PackageError{ifthen}{You can only set a boolean to `true' or `false'}\@ehc}%
        {\@ifundefined{#1\@tempa}%
            {\PackageError{ifthen}{Boolean #1 undefined}\@ehc}%
            {\global\csname#1\@tempa\endcsname}%
        }%
    }

%%
% Detect if the subfigure package has been loaded

\newboolean{@tufte@packages@subfigure}
\setboolean{@tufte@packages@subfigure}{false}
\AtBeginDocument{%
    \@ifpackageloaded{subfigure}
    {\gsetboolean{@tufte@packages@subfigure}{true}}
    {\gsetboolean{@tufte@packages@subfigure}{false}}%
}

% Write our own aliases for the \checkoddpage and \ifoddpage or \ifcpoddpage commands
\newboolean{@tufte@odd@page}
\setboolean{@tufte@odd@page}{true}
\newcommand*{\@tufte@checkoddpage}%
    {%
        \checkoddpage%
        \ifthenelse{\boolean{@tufte@changepage}}%
            {%
                \ifoddpage%
                    \setboolean{@tufte@odd@page}{true}%
                \else%
                    \setboolean{@tufte@odd@page}{false}%
                \fi%
            }{%
                \ifcpoddpage%
                    \setboolean{@tufte@odd@page}{true}%
                \else%
                    \setboolean{@tufte@odd@page}{false}%
                \fi%
            }%
    }


%%
% Define a float environment to place the captions in the margin space

\newenvironment{@tufte@float}[3][htbp]%
{% begin @tufte@float
    % Should this float be full-width or just text-width?
    \ifthenelse{\equal{#3}{star}}%
        {\gsetboolean{@tufte@float@star}{true}}%
        {\gsetboolean{@tufte@float@star}{false}}%
    %   
    % Check page side (recto/verso) and store detected value -- can be overriden in environment contents
    \@tufte@checkoddpage%
    \ifthenelse{\boolean{@tufte@odd@page}}%
        {\gsetboolean{@tufte@float@recto}{true}%%%\@tufte@float@debug{Detected page: [recto/odd]}
            }%
        {\gsetboolean{@tufte@float@recto}{false}%%%\@tufte@float@debug{Detected page: [verso/even]}
            }%
    % If the float placement specifier is 'b' and only 'b', then bottom-align the mini-pages, otherwise top-align them.
    \renewcommand{\@tufte@fps}{#1}%
    %%%\@tufte@float@debug{Allowed positions: [#1]}%
    \ifthenelse{\equal{#1}{b}\OR\equal{#1}{B}}%
        {\renewcommand{\floatalignment}{b}%%%\@tufte@float@debug{Presumed position: [bottom]}
            }%
        {\renewcommand{\floatalignment}{t}%%%\@tufte@float@debug{Presumed position: [top]}
            }%
    % Capture the contents of the \caption and \label commands to use later
    \global\let\@tufte@orig@caption\caption%
    \global\let\@tufte@orig@label\label%
    \renewcommand{\caption}{\optparams{\@tufte@caption}{[][0pt]}}%
        %QUESTION: is ##1 ok?
    \renewcommand{\label}[1]{\@tufte@label{##1}}% 
    % Handle subfigure package compatibility
    \ifthenelse{\boolean{@tufte@packages@subfigure}}%
        {% don't move the label while inside a \subfigure or \subtable command
        \global\let\label\@tufte@orig@label%
        }{%
        }% subfigure package is not loaded
    \@tufte@orig@float{#2}[#1]%
    \ifthenelse{\boolean{@tufte@float@star}}%
        {\setlength{\@tufte@float@contents@width}{\@tufte@fullwidth}}%
        {\setlength{\@tufte@float@contents@width}{\textwidth}}%
    \begin{lrbox}{\@tufte@figure@box}%
        \begin{minipage}[\floatalignment]{\@tufte@float@contents@width}\hbox{}%
}
{% end @tufte@float
            \par\hbox{}\vspace{-\baselineskip}\ifthenelse{\prevdepth>0}{\vspace{-\prevdepth}}{}% align baselines of boxes
        \end{minipage}%
    \end{lrbox}%
    % build the caption box
    \begin{lrbox}{\@tufte@caption@box}%
        \begin{minipage}[\floatalignment]{\marginparwidth}\hbox{}%
            \ifthenelse{\NOT\equal{\@tufte@stored@caption}{}}%
                {\@tufte@orig@caption[\@tufte@stored@shortcaption]{\@tufte@stored@caption}}%
                {}%
            \ifthenelse{\NOT\equal{\@tufte@stored@label}{}}%
                {\@tufte@orig@label{\@tufte@stored@label}}%
                {}%
            \par\vspace{-\prevdepth}%% TODO: DOUBLE-CHECK FOR SAFETY
        \end{minipage}%
    \end{lrbox}%
    % now typeset the stored boxes
    \begin{fullwidth}%
        \begin{minipage}[\floatalignment]{\linewidth}%
            \ifthenelse{\boolean{@tufte@float@star}}%
            {\@tufte@float@fullwidth[\@tufte@caption@vertical@offset]{\@tufte@figure@box}{\@tufte@caption@box}}%
            {\@tufte@float@textwidth[\@tufte@caption@vertical@offset]{\@tufte@figure@box}{\@tufte@caption@box}}%
        \end{minipage}%
    \end{fullwidth}%
    \@tufte@orig@endfloat% end original LaTeX float environment
    % output debug info
%   \ifthenelse{\boolean{@tufte@debug}}%
%       {%
%           \typeout{^^J^^J----------- Tufte-LaTeX float information ----------}%
%           \ifthenelse{\equal{\@tufte@stored@label}{}}%
%           {\typeout{Warning: Float unlabeled!}}%
%           {\typeout{Float label: [\@tufte@stored@label]}}%
%           \typeout{Page number: [\thepage]}%
%           \def\MessageBreak{^^J}%
%           \typeout{\@tufte@float@debug@info}%
%           \ifthenelse{\boolean{@tufte@symmetric}}%
%           {\typeout{Symmetric: [true]}}%
%           {\typeout{Symmetric: [false]}}%
%           \typeout{----------------------------------------------------^^J^^J}%
%       }{%
%       }%
    % reset commands and temp boxes and captions
    %%\gdef\@tufte@float@debug@info{}%
    \let\caption\@tufte@orig@caption%
    \let\label\@tufte@orig@label%
    \begin{lrbox}{\@tufte@figure@box}\hbox{}\end{lrbox}%
    \begin{lrbox}{\@tufte@caption@box}\hbox{}\end{lrbox}%
    \gdef\@tufte@stored@shortcaption{}%
    \gdef\@tufte@stored@caption{}%
    \gdef\@tufte@stored@label{}%
    \gsetlength{\@tufte@caption@vertical@offset}{0pt}% reset caption offset
}

\newcommand{\@tufte@float@textwidth}[3][0pt]%
    {%
        \ifthenelse{\NOT\boolean{@tufte@symmetric}\OR\boolean{@tufte@float@recto}}
            {% asymmetric or page is odd, so caption is on the right
                \hbox{%
                    \usebox{#2}%
                    \hspace{\marginparsep}%
                    \smash{\raisebox{#1}{\usebox{#3}}}%
                }%
                \@tufte@float@debug{Caption position: [right]}%
            }{% symmetric pages and page is even, so caption is on the left
                \hbox{%
                    \smash{\raisebox{#1}{\usebox{#3}}}%
                    \hspace{\marginparsep}%
                    \usebox{#2}%
                }%
                \@tufte@float@debug{Caption position: [left]}%
            }%
    }

\newcommand{\@tufte@float@fullwidth}[3][0pt]%
    {%
        \ifthenelse{\equal{\floatalignment}{b}}%
            {% place caption above figure
                \ifthenelse{\NOT\boolean{@tufte@symmetric}\OR\boolean{@tufte@float@recto}}%
                    {\hfill\smash{\raisebox{#1}{\usebox{#3}}}\par\usebox{#2}\@tufte@float@debug{Caption position: [above right]}}% caption on the right
                    {\smash{\raisebox{#1}{\usebox{#3}}}\hfill\par\usebox{#2}\@tufte@float@debug{Caption position: [above left]}}% caption on the left
            }{% place caption below figure
                \ifthenelse{\NOT\boolean{@tufte@symmetric}\OR\boolean{@tufte@float@recto}}%
                    {\usebox{#2}\par\hfill\smash{\raisebox{#1}{\usebox{#3}}}\@tufte@float@debug{Caption position: [below right]}}% caption on the right
                    {\usebox{#2}\par\smash{\raisebox{#1}{\usebox{#3}}}\hfill\@tufte@float@debug{Caption position: [below left]}}% caption on the left
            }%
    }

%%
% Redefine the figure environment to place the captions in the margin space

\renewenvironment{figure}[1][htbp]%
    {%
        \begin{@tufte@float}[#1]{figure}{}%
    }{%
        \end{@tufte@float}%
    }


%%
% Redefine the table environment to place the captions in the margin space

\renewenvironment{table}[1][htbp]%
    {%
        \begin{@tufte@float}[#1]{table}{}%
    }{%
        \end{@tufte@float}%
    }

%%
% Full-width figure

\renewenvironment{figure*}[1][htbp]%
    {%
        \begin{@tufte@float}[#1]{figure}{star}%
    }{%
        \end{@tufte@float}%
    }


%%
% Full-width table

\renewenvironment{table*}[1][htbp]%
    {%
        \begin{@tufte@float}[#1]{table}{star}%
    }{%
        \end{@tufte@float}%
    }

答案1

您可以使用sidenotes-package:

\documentclass[twoside]{scrartcl}
    \usepackage{showframe}
    \usepackage{graphicx}
    \usepackage{placeins}
    \usepackage{sidenotes}
    \usepackage{kantlipsum}
    \usepackage[a4paper,left=24.8mm,top=27.4mm,headsep=2\baselineskip,textwidth=107mm,marginparsep=8.2mm,marginparwidth=49.4mm,textheight=49\baselineskip,headheight=\baselineskip]{geometry} % tufte-handout definitions


\begin{document}
    \begin{marginfigure}%
        \caption{My caption}
        \includegraphics[width=\marginparwidth]{example-image-a}
    \end{marginfigure}

    \kant[1]
    \begin{figure}[h]
        \sidecaption{My caption}
        \includegraphics[width=\textwidth]{example-image-a}
    \end{figure}

    \begin{figure*}
        \sidecaption{My caption}
        \includegraphics[width=\linewidth]{example-image-a}
    \end{figure*}

\end{document}

在此处输入图片描述 在此处输入图片描述

答案2

我参加这个聚会已经有点晚了,但最近可能还有另一个值得一试的选择,即kaobook课程。风格有点不同,但它吸收了许多来自tufte并且正在积极开发中(截至 2021 年)。

相关内容