我想使用和类中定义的marginfigure
、figure*
和环境(分别参见figure
tufte-book
tufte-handout
模板示例)。
这意味着能够使用以下环境:
marginfigure
:页边距中具有宽度的图形\marginparwidth
,其标题位于页边距下方;figure
:正文中带有的图形\textwidth
,其标题位于边距之外(且底部对齐);figure*
:正文和边距上方有一张具有\textwidth + \marginparsep + \marginparwidth
宽度的图形,标题位于边距下方。
但是,由于我的大部分源代码都是用于KOMAscript
课程的,所以我不想tufte
仅仅因为这个而切换到其中一个课程。
问题:如何模拟tufte
课外的环境?
这个问题已经解决了接受的答案,即使用
sidenotes
-package。但是,为了防止其他人走我走过的弯路/死胡同,我在下面分享了我解决问题的尝试。它将我的问题的先前版本汇总在一起。内容:
- 相关软件包和 TeX.SE 问题,
marginfigure
使用包的成功解决方法capt-of
,- 尝试模拟
tufte
类源代码之外的环境:
- 成功(但笨重)
marginfigure
;- 失败的
figure
和figure*
1. 相关软件包和 TeX.SE 问题
我知道floatrow
包,但即使它对于figure
和来说看起来很棒figure*
,我还是找不到如何处理marginfigure
。
我还发现实现 marginfigure以另一种方式解决问题。
figure
和figure*
:然后,我在被阻止时查看了 TeX.SE,并发现了几个相关的线程:- 跨越文本宽度和边距的浮点数:不处理页边距中的标题
- 使用 \MarginFigure 命令:
- 如何确保图像正确浮动在边距上?: 一路顺利。
- 我终于找到了边注/标题建议使用
tufte
课程。
marginfigure
2.使用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
时编译失败。figure
figure*
marginfigure
:我成功复制了tufte-book
classe的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*
做同样的事情。figure
figure*
但是,编译失败。
\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}