![\marginpar을 페이지 상단이나 하단으로 보내기 (및 스택)](https://rvso.com/image/254706/%5Cmarginpar%EC%9D%84%20%ED%8E%98%EC%9D%B4%EC%A7%80%20%EC%83%81%EB%8B%A8%EC%9D%B4%EB%82%98%20%ED%95%98%EB%8B%A8%EC%9C%BC%EB%A1%9C%20%EB%B3%B4%EB%82%B4%EA%B8%B0%20(%EB%B0%8F%20%EC%8A%A4%ED%83%9D).png)
\topmarginpar{<text>}
나는 본질적으로 를 생성\marginpar{<text>}
하고 그 상단을 현재 페이지의 상단과 정렬하는 과 같은 것을 정의하려고 합니다 .또한 이러한 개체를 겹치게 하는 대신 여러 번
\topmarginpar
호출하여 이러한 개체를 쌓고 싶습니다 .\marginpar
그리고 마지막으로 비슷한 명령을 만들고 싶습니다
\bottommargin
.
이 기능을 제공하는 기존 패키지가 있습니까, 아니면 제가 여기에 있습니까(저는 LaTeX에 능숙하지만 원시 TeX에서는 쓸모가 없습니다)?
어떤 제안이라도 감사드립니다...
답변1
이 솔루션은 비동기 출력 루틴을 다룹니다.
페이지는 절대 페이지 번호로 식별되며 레이블을 사용하여 두 번째 LaTeX 실행에서 올바른 페이지 번호를 사용할 수 있습니다.
각 페이지에는 상단과 하단의 여백 메모를 수집하는 두 개의 수집 상자가 있습니다. 배송 시 절대 페이지 번호가 알려지고 페이지의 컬렉터 박스가 페이지의 "marginpar" 영역에 출력됩니다.
박스 레지스터는 동적으로 할당되고 풀에서 관리됩니다. 페이지 배송 후 해당 컬렉터 박스 레지스터가 해제되어 풀에 다시 배치됩니다.
\topskip
그리고\maxdepth
"marginpar" 영역이 존중됩니다.한 페이지에 너무 많은 여백 메모가 가득 차 있다는 경고로 보고됩니다
\vbox
.LaTeX는
\marginpar
지원되지 않습니다. 서로 다른 종류의 여백 메모는 서로 알지 못하며 서로 중복 인쇄됩니다.
예제 문서:
\documentclass{article}
\usepackage{atbegshi}
\usepackage{zref-abspage}
\usepackage{picture}
\makeatletter
\providecommand*{\c@zabspage}{\c@abspage}
% * User macros for configuring
%
% \tbmparItemSep is inserted between marginal notes
% \tbmparMiddleSep is inserted between top and bottom marginal notes.
\newcommand*{\tbmparItemSep}{%
\vspace{1ex minus .5ex}%
\hrule
\vspace{1ex minus .5ex}%
}
\newcommand*{\tbmparMiddleSep}{%
\vspace*{0pt plus 1fil}%
}
% * Debug messages
%
\newcommand*{\tbmparDebug}[1]{%
\typeout{[tbmpar] #1}%
}
% * Label management to remember absolute page number
%
% \tbmpar@PageByLabel stores and loads absolute page number from
% label and defines \tbmpar@page with absolute page number or
% zero if the label is not yet available.
\newcount\c@tbmpar@item
\c@tbmpar@item\z@
\newcommand*{\tbmpar@PageByLabel}{%
\global\advance\c@tbmpar@item\@ne
\zref@labelbyprops{tbmpar\the\c@tbmpar@item}{abspage}%
\edef\tbmpar@page{%
\zref@extractdefault{tbmpar\the\c@tbmpar@item}{abspage}{0}%
}%
\zref@refused{tbmpar\the\c@tbmpar@item}%
\tbmparDebug{Item \the\c@tbmpar@item\space on page \tbmpar@page}%
}
% * Box register management
\newcount\c@tbmpar@box
\c@tbmpar@box\z@
\let\tbmpar@boxfreelist\@empty
% Get a new free box register either from the free list or,
% if the free list is empty, allocate a new box register.
\newcommand*{\tbmpar@NextBox}[1]{%
\@next#1\tbmpar@boxfreelist{%
\tbmparDebug{Reused box: #1}%
}{%
\global\advance\c@tbmpar@box\@ne
\expandafter\newbox\csname tbmpar@box\the\c@tbmpar@box\endcsname
\edef#1{\csname tbmpar@box\the\c@tbmpar@box\endcsname}%
\tbmparDebug{New box: #1}%
}%
}
% Put free box in free list.
\newcommand*{\tbmpar@FreeBox}[1]{%
\begingroup
\let\@elt\relax
\xdef\tbmpar@boxfreelist{%
\tbmpar@boxfreelist
\@elt#1%
}%
\tbmparDebug{Free box: #1}%
\endgroup
}
\newsavebox{\tbmpar@box}
% Each marginpar is put in a box that is initialized as
% parbox/minipage.
\newcommand*{\tbmparBoxSetup}{}
\newcommand{\tbmpar@VBox}[1]{%
\vbox{%
\color@begingroup
\hsize\marginparwidth
\edef\tbmpar@restore@ifminipage{%
\if@minipage
\noexpand\@minipagetrue
\else
\noexpand\@minipagefalse
\fi
}%
\@parboxrestore
\@marginparreset
\tbmparBoxSetup
#1%
\tbmpar@restore@ifminipage
\color@endgroup
}%
}
% Macro \tbmpar@marginpar looks for the page, where the margin note
% belongs to, stores the note in a box and appends the box to the
% note collector register of the page.
% Each page is assigned a box collector registers that collect
% the top notes and a register that collect the bottom notes.
% The name of the box register is \tbmpar@<top|bot>box<page>.
\newcommand{\tbmpar@marginpar}[4]{%
\ifhmode
\@bsphack
\fi
\tbmpar@PageByLabel
\ifnum\tbmpar@page>\z@
\setbox\tbmpar@box\tbmpar@VBox{#4}%
\@ifundefined{tbmpar@#1box\tbmpar@page}{%
\tbmpar@NextBox\tbmpar@currbox
\global\expandafter\let
\csname tbmpar@#1box\tbmpar@page\endcsname
\tbmpar@currbox
\global\setbox\tbmpar@currbox=\vbox{%
\unvbox\tbmpar@box
}%
}{%
\tbmparDebug{Use box: \tbmpar@currbox}%
\expandafter\let\expandafter\tbmpar@currbox
\csname tbmpar@#1box\tbmpar@page\endcsname
\global\setbox\tbmpar@currbox\tbmpar@VBox{%
\unvbox#2%
\par
\begingroup
\tbmparItemSep
\endgroup
\unvbox#3%
}%
}%
\fi
\ifhmode
\@esphack
\fi
}
\newcommand*{\topmarginpar}{%
\tbmpar@marginpar{top}\tbmpar@currbox\tbmpar@box
}
\newcommand*{\botmarginpar}{%
\tbmpar@marginpar{bot}\tbmpar@box\tbmpar@currbox
}
% At shipout time we look for the box collector registers of this
% page and set these boxes in the marginpar box with respecting
% \topskip and \maxdepth.
\AtBeginShipout{%
\AtBeginShipoutUpperLeft{%
\put(%
\dimexpr 1in+\oddsidemargin+\textwidth+\marginparsep\relax,%
-\dimexpr 1in+\topmargin+\headheight+\headsep+\textheight\relax
){%
\begingroup
\global\let\tbmpar@inuse=N%
\setbox\tbmpar@box=\tbmpar@VBox{%
\penalty-\@M
\edef\tbmpar@tmp{tbmpar@topbox\the\value{zabspage}}%
\@ifundefined{\tbmpar@tmp}{%
}{%
\expandafter\let\expandafter\tbmpar@currbox
\csname\tbmpar@tmp\endcsname
\unvbox\tbmpar@currbox
\tbmpar@FreeBox\tbmpar@currbox
\global\let\tbmpar@inuse=Y%
}%
\endgraf
\tbmparMiddleSep
\edef\tbmpar@tmp{tbmpar@botbox\the\value{zabspage}}%
\@ifundefined{\tbmpar@tmp}{%
}{%
\expandafter\let\expandafter\tbmpar@currbox
\csname\tbmpar@tmp\endcsname
\unvbox\tbmpar@currbox
\tbmpar@FreeBox\tbmpar@currbox
\global\let\tbmpar@inuse=Y%
}%
}%
\ifx\tbmpar@inuse Y%
\splittopskip=\topskip
\setbox0=\vsplit\tbmpar@box to\z@
\boxmaxdepth=\maxdepth
\setbox\tbmpar@box=\vbox to\textheight{%
\unvbox\tbmpar@box
}%
\box\tbmpar@box
\fi
\endgroup
}%
}%
}
\makeatother
% Testing
\usepackage[
a5paper,
left=10mm,
right=10mm,
marginparwidth=40mm,
includemp,
]{geometry}
\usepackage{microtype}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\clubpenalty=10000
\flushbottom
\settodepth\maxdepth{g}
\setlength{\fboxsep}{1ex}
\usepackage{lipsum}
\usepackage{color}
\newcommand*{\shortlipsum}[1]{%
\begingroup
\long\def\y##1. ##2\@nil{##1.}%
\edef\x{\csname lipsum@\romannumeral#1\endcsname}%
\expandafter\y\x. \@nil
\endgroup
}
\begin{document}
\topmarginpar{\color{blue}\shortlipsum{1}}
\lipsum[1]
\botmarginpar{%
Show effect of \texttt{\textbackslash maxdepth}:
$\displaystyle\sum_{\textstyle i=\frac{a}{g}}^\infty i = x$}
\lipsum[2]
\topmarginpar{\shortlipsum{3}}%
\botmarginpar{Second bottom marginal note}%
\lipsum[3-4]
\noindent a\botmarginpar{a} b\botmarginpar{b} c \botmarginpar{c} d\\
e\\f\par
\topmarginpar{\fbox{\shortlipsum{5}}}
\lipsum[5]
Text with footnote and marginal note\footnote{Marginal note X}.
\topmarginpar{This is marginal note X}
\lipsum[6]
\botmarginpar{\shortlipsum{7}}
\lipsum[7]
\end{document}
답변2
다음은마틴 샤러님의 패키지tikzpagenodes. remember picture, overlay
옵션을 사용하므로TikZ, 제대로 작동하려면 두 번 컴파일해야 합니다. 이는 두 가지 명령을 제공하며 \marpartop
둘 \marparbot
다 내용과 텍스트 색상이라는 두 가지 인수를 취하므로 더 쉽게 사용자 정의할 수 있도록 확장할 수 있습니다.
암호
\documentclass{scrartcl}
\usepackage[left=15mm,top=40mm,bottom=40mm,right=50mm,a4paper]{geometry}
\usepackage{tikzpagenodes}
\usepackage{xifthen}
\usepackage{lipsum}
\setlength{\marginparwidth}{40mm}
\pagestyle{empty}
\def\myyshifttop{0}
\def\mypagetop{0}
\newcommand{\marpartop}[2]% content, color
{ \begin{tikzpicture}[remember picture, overlay]
\ifthenelse{\thepage=\mypagetop}{}{\xdef\myyshifttop{0}}
\xdef\mypagetop{\thepage}
\node[below right, yshift=\myyshifttop, text width=\marginparwidth-4pt, inner sep=2pt, #2] (tempnode) at (current page marginpar area.north west) {#1};
\path (current page marginpar area.north west);
\pgfgetlastxy{\tempxone}{\tempyone}
\path (tempnode.south west);
\pgfgetlastxy{\tempxtwo}{\tempytwo}
\pgfmathsetmacro{\diffy}{(\tempytwo-\tempyone)}
\xdef\myyshifttop{\diffy}
\end{tikzpicture}
}
\def\myyshiftbot{0}
\def\mypagebot{0}
\newcommand{\marparbot}[2]% content, color
{ \begin{tikzpicture}[remember picture, overlay]
\ifthenelse{\thepage=\mypagebot}{}{\xdef\myyshiftbot{0}}
\xdef\mypagebot{\thepage}
\node[above right, yshift=\myyshiftbot, text width=\marginparwidth-4pt, inner sep=2pt, #2] (tempnode) at (current page marginpar area.south west) {#1};
\path (current page marginpar area.south west);
\pgfgetlastxy{\tempxone}{\tempyone}
\path (tempnode.north west);
\pgfgetlastxy{\tempxtwo}{\tempytwo}
\pgfmathsetmacro{\diffy}{(\tempytwo-\tempyone)}
\xdef\myyshiftbot{\diffy}
\end{tikzpicture}
}
\begin{document}
\marpartop{On a journey to find the cure for a Tatarigami's curse, Ashitaka finds himself in the middle of a war between the forest gods and Tatara, a mining colony.}{red}
\marparbot{What begins as an open and shut case of murder soon becomes a mini-drama of each of the jurors' prejudices and preconceptions about the trial, the accused, and each other.}{orange!50!gray}
\lipsum[1-3]
\marparbot{The defense and the prosecution have rested and the jury is filing into the jury room to decide if a young Spanish-American is guilty or innocent of murdering his father.}{green!50!gray}
\marpartop{In this quest he also meets San, the Mononoke Hime.}{blue}
\lipsum[4-7]
\marpartop{On a journey to find the cure for a Tatarigami's curse, Ashitaka finds himself in the middle of a war between the forest gods and Tatara, a mining colony.}{red}
\marparbot{What begins as an open and shut case of murder soon becomes a mini-drama of each of the jurors' prejudices and preconceptions about the trial, the accused, and each other.}{orange!50!gray}
\lipsum[8]
\marpartop{In this quest he also meets San, the Mononoke Hime.}{blue}
\marparbot{The defense and the prosecution have rested and the jury is filing into the jury room to decide if a young Spanish-American is guilty or innocent of murdering his father.}{green!50!gray}
\lipsum[9-12]
\end{document}
결과
답변3
(참고: 원래 아이디어는 Tom Bombadil의 것이므로 커뮤니티 답변입니다.)
다음은 몇 가지 개선 사항이 포함된 Tom Bombadil의 답변 변형입니다.
두 매크로의 이름은
\topmarginpar
요청\botmarginpar
된 대로 지정됩니다.그들의 첫 번째 주장(선택 과목기본적으로 비어 있음)은 TikZ 노드에 대한 일부 옵션입니다(채우기, 테두리 그리기 등 허용). 두 번째 주장은 단락의 내용입니다.
tikzpagenodes
짝수 페이지 의 버그를 수정하기 위한 몇 가지 계산이 있습니다 (편집: Martin Scharer는 매우 반응이 좋습니다. 버그가 수정된 버전이 CTAN에 출시될 예정입니다.).코드는
let
작업(및calc
TikZ 라이브러리)을 사용합니다. 내 생각엔 PGF 호출보다 더 읽기 쉽다고 생각합니다.
제한:
\botmarginpar
문단을 역순으로 쌓아야 합니다!- 스택이 가득 차면 다음 페이지로 넘어가지 않습니다. 페이지 위나 아래로 넘칩니다.
\topmarginpar
페이지의 마지막 단락에서 (또는 )을 호출 하면\bormarginpar
여백 단락이 올바른 순서가 아닌 다음 페이지에 나타날 수 있습니다.
다음은 두 페이지입니다(홀수 페이지와 짝수 페이지).
코드(내 의견 포함):
\documentclass[twoside]{report}
\usepackage{tikzpagenodes}
\usepackage{xifthen}
\usetikzlibrary{calc}
\def\myyshifttop{0}
\def\mypagetop{0}
\newcommand{\topmarginpar}[2][]{% tikz options of node, content
\begin{tikzpicture}[remember picture, overlay]
% reset position on new page
\ifthenelse{\thepage=\mypagetop}{}{\xdef\myyshifttop{0}\xdef\mypagetop{\thepage}}
% a big path with many actions
\path let
% patch for bug in tikzpagenodes with even pages
\p1=(current page marginpar area.north west),
\p2=(current page marginpar area.north east)
in \pgfextra{
\pgfmathsetmacro{\xw}{\x1<\x2?\x1:\x2}
\pgfmathsetmacro{\yw}{\y1<\y2?\y1:\y2}
\edef\coord{\xw pt,\yw pt}
}
% draw topmarginpar
node[below right, yshift=\myyshifttop, text width=\marginparwidth-4pt, inner sep=2pt, #1]
(tempnode) at (\coord) {#2}
% next position
let \p1=(\coord), \p2=(tempnode.south west) in \pgfextra{
\pgfmathsetmacro{\diffy}{(\y2-\y1)}
\xdef\myyshifttop{\diffy}
};
\end{tikzpicture}%
}
\def\myyshiftbot{0}
\def\mypagebot{0}
\newcommand{\botmarginpar}[2][]{% tikz options of node, content
\begin{tikzpicture}[remember picture, overlay]
% reset position on new page
\ifthenelse{\thepage=\mypagebot}{}{\xdef\myyshiftbot{0}\xdef\mypagebot{\thepage}}
% a big path with many actions
\path let
% patch for bug in tikzpagenodes with even pages
\p1=(current page marginpar area.south west),
\p2=(current page marginpar area.south east)
in \pgfextra{
\pgfmathsetmacro{\xw}{\x1<\x2?\x1:\x2}
\pgfmathsetmacro{\yw}{\y1<\y2?\y1:\y2}
\edef\coord{\xw pt,\yw pt}
}
% draw botmarginpar
node[above right, yshift=\myyshiftbot, text width=\marginparwidth-4pt, inner sep=2pt, #1]
(tempnode) at (\coord) {#2}
% next position
let \p1=(\coord), \p2=(tempnode.north west) in \pgfextra{
\pgfmathsetmacro{\diffy}{(\y2-\y1)}
\xdef\myyshiftbot{\diffy}
};
\end{tikzpicture}%
}
\usepackage{lipsum}
\begin{document}
\topmarginpar[red,fill=yellow!30]{On a journey to find the cure for a
Tatarigami's curse, Ashitaka finds himself in the middle of a war
between the forest gods and Tatara, a mining colony.}%
\botmarginpar{What begins as an open and shut case of murder soon
becomes a mini-drama of each of the jurors' prejudices and
preconceptions about the trial, the accused, and each other.}%
\lipsum[1-3]%
\botmarginpar[font=\itshape\footnotesize,text=green!50!black]{The
defense and the prosecution have rested and the jury is filing into
the jury room to decide if a young Spanish-American is guilty or
innocent of murdering his father.}%
\topmarginpar[blue]{In this quest he also meets San, the Mononoke
Hime.}%
\lipsum[4-7]%
\topmarginpar[red]{On a journey to find the cure for a Tatarigami's
curse, Ashitaka finds himself in the middle of a war between the
forest gods and Tatara, a mining colony.}%
\botmarginpar[orange!50!gray]{What begins as an open and shut case of
murder soon becomes a mini-drama of each of the jurors' prejudices and
preconceptions about the trial, the accused, and each other.}%
\lipsum[8]%
\topmarginpar[blue]{In this quest he also meets San, the Mononoke
Hime.}%
\botmarginpar[green!50!gray]{The defense and the prosecution have rested
and the jury is filing into the jury room to decide if a young
Spanish-American is guilty or innocent of murdering his father.}%
\lipsum[9-12]
\end{document}
답변4
나는 간단한 해킹을 marginfit
패키지로 만들어 간단한 해결책을 얻었습니다.
\documentclass[11pt,a4paper]{article}
%% Needs marginfit package to be loaded before:
\RequirePackage{marginfit}
\makeatletter
%% Top marginpar:
\def\marginfit@writepost#1{%
\write\@auxout{\string\@newl@bel{label@marginfit}{#1}{47040224}}% %% Note it from aux file entry with @t
}
\def\marginpart{%
\global\advance\c@marginfit@w\@ne%
\expandafter\marginfit@writepost\expandafter{\the\c@marginfit@w @m}%
\@ifnextchar[\marginfit@mpar@ii\marginfit@mpar@i%
}
%% Bottom marginpar:
\def\marginfit@writeposb#1{%
\write\@auxout{\string\@newl@bel{label@marginfit}{#1}{0}}% %% Minimum is 0
}
\def\marginparb{%
\global\advance\c@marginfit@w\@ne%
\expandafter\marginfit@writeposb\expandafter{\the\c@marginfit@w @m}%
\@ifnextchar[\marginfit@mpar@ii\marginfit@mpar@i%
}
\makeatother
\begin{document}
\marginpar{OM O MO M M M M M M}
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
\marginpar{OM O MO M M M M M M\par\medskip\hrule}
ABC
\marginpart{To be Top OM O MO M M M M M M}
\newpage %--------------------------------------------------------------------
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
\marginpart{Top OM O MO M M M M M M}
\marginparb{Bottom OM O MO M M M M M M}
ABC
ABC
ABC
ABC
\end{document}
\marginpart
위쪽 marginpar 및 \marginparb
아래쪽 marginpar에 대한 두 가지 새로운 명령을 제공합니다 . 그 안에 있는 숫자 47040224는 \pdflastypos
가장 높은 마진을 나타냅니다. 이 숫자는 여전히 더 높을 수 있으며 marginfit
상단 가장자리를 교차하지 않도록 최종 배치에서 위치를 설정합니다. 페이지 크기에 따라 더 높은 값을 시도해 보세요. 알아내는 가장 좋은 방법은 먼저 문서의 시작 부분에 단일 여백을 만들어 가장 위에 오도록 하고 aux 파일의 해당 항목을 살펴보는 것입니다.
작동 방식은 다음과 같습니다. marginfit
패키지는 할당된 레이블을 사용하여 모든 marginpar의 y 위치를 저장합니다. 방금 현재 marginpar의 ypos를 aux 파일에 쓰는 코드를 빌려서 ypos를 최대(하단 marginpar의 경우 최소 0)로 설정하도록 만들었습니다.