%% gyoudori.sty %% 見出し・ディスプレイ数式・フロートを行取り(行ドリ)で配置する. %% %% Author: Yuwsuke Kieda %% Copyright (c) 2020–2026 Yuwsuke Kieda %% This file is part of the gyoudori package, released under the MIT License: %% %% Permission is hereby granted, free of charge, to any person obtaining a copy %% of this software and associated documentation files (the "Software"), to deal %% in the Software without restriction, including without limitation the rights %% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell %% copies of the Software, and to permit persons to whom the Software is %% furnished to do so, subject to the following conditions: %% %% The above copyright notice and this permission notice shall be included in all %% copies or substantial portions of the Software. %% %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE %% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE %% SOFTWARE. %% \NeedsTeXFormat{LaTeX2e}[2022/06/01] \ProvidesPackage{gyoudori} [2026/10/26 v20261026.0 style file ``gyoudori.sty''^^J by Yuwsuke Kieda] % pLaTeX/upLaTeXとLuaLaTeX(LuaTeX-ja)で動く. % パッケージオプションにカーネルのkey-value機能(\DeclareKeys,\ProcessKeyOptions)を % 使うので,LaTeX 2022-06-01以降が必要 \@ifl@t@r\fmtversion{2022/06/01}{}{% \PackageError{gyoudori}{LaTeX 2022-06-01 or later is required}{}} %% パッケージオプション(key-value) % displaymath=true|false: ディスプレイ数式環境を自動的に行取りする(既定はfalse) % displaymathextra=整数: ディスプレイ数式が要する行数に足す行数(既定は1).行取りの % 行数は,要する行数にこの数を足したもの(2行以上) % float=true|false: フロートを行取りで配置する(既定はfalse) % floatsep,textfloatsep,intextsep,dblfloatsep,dbltextfloatsep: フロートまわりの % アキ.指定しなければクラスファイルの値を使う % overflow=warning|error: gyoudori環境・\gyoudoriareaの内容が領域に収まらないときに % 警告するか(既定),エラーにするか % indent=true|false: gyoudori環境・\gyoudoriareaの内容の段落を字下げするか(既定はfalse) % 真偽値のオプションは,キーだけを書くとtrueになる \newif\ifgyoudori@displaymath \newif\ifgyoudori@float \newif\ifgyoudori@indent \def\gyoudori@floatsep{} \def\gyoudori@textfloatsep{} \def\gyoudori@intextsep{} \def\gyoudori@dblfloatsep{} \def\gyoudori@dbltextfloatsep{} \def\gyoudori@overflow{warning} \def\gyoudori@displaymathextra{1} \DeclareKeys[gyoudori]{ displaymath .if = gyoudori@displaymath , displaymath .default:n = true , float .if = gyoudori@float , float .default:n = true , indent .if = gyoudori@indent , indent .default:n = true , floatsep .store = \gyoudori@floatsep , textfloatsep .store = \gyoudori@textfloatsep , intextsep .store = \gyoudori@intextsep , dblfloatsep .store = \gyoudori@dblfloatsep , dbltextfloatsep .store = \gyoudori@dbltextfloatsep , overflow .store = \gyoudori@overflow , displaymathextra .store = \gyoudori@displaymathextra , } \ProcessKeyOptions[gyoudori] % displaymathextraは0以上の整数 \@tempcnta\numexpr\gyoudori@displaymathextra\relax \ifnum\@tempcnta<\z@ \PackageError{gyoudori}{displaymathextra must be 0 or more}{% You gave `\gyoudori@displaymathextra'.}% \@tempcnta\z@ \fi \edef\gyoudori@displaymathextra{\the\@tempcnta} \def\@tempa{warning}\def\@tempb{error} \ifx\gyoudori@overflow\@tempa\else\ifx\gyoudori@overflow\@tempb\else \PackageError{gyoudori}{Unknown value `\gyoudori@overflow' for overflow}{% The value is warning or error.}% \def\gyoudori@overflow{warning}% \fi\fi \def\@gyoudori@setsep#1{% \expandafter\ifx\csname gyoudori@#1\endcsname\@empty\else \expandafter\setlength\csname #1\endcsname{\csname gyoudori@#1\endcsname}% \fi} \@gyoudori@setsep{floatsep} \@gyoudori@setsep{textfloatsep} \@gyoudori@setsep{intextsep} \@gyoudori@setsep{dblfloatsep} \@gyoudori@setsep{dbltextfloatsep} %% 行取りの基準:\normalsizeの「あ」の高さ・深さ(JFMの字の枠)と行送り \newdimen\@gyoudori@ht \newdimen\@gyoudori@dp \newdimen\@gyoudori@bs \def\@gyoudori@metrics{% \begingroup \normalsize \setbox\z@\hbox{あ}% \global\@gyoudori@ht\ht\z@ \global\@gyoudori@dp\dp\z@ \global\@gyoudori@bs\normalbaselineskip \endgroup} % オプションlocal:その場の文字サイズの「あ」の高さ・深さと\baselineskipを基準にする \def\@gyoudori@metrics@local{% \setbox\z@\hbox{あ}% \global\@gyoudori@ht\ht\z@ \global\@gyoudori@dp\dp\z@ \global\@gyoudori@bs\baselineskip} % \@gyoudori@placeが使う基準.gyoudori環境と\gyoudoriareaのlocalで切り替える \let\@gyoudori@getmetrics\@gyoudori@metrics % 版面(段)の上端から本文1行目のベースラインまで.TeXは1行目の高さ(「あ」の高さ)が % \topskipより大きいとき,1行目のベースラインを行の高さの位置に置くので,大きいほうをとる \def\@gyoudori@firstbase{% \ifdim\topskip<\@gyoudori@ht\@gyoudori@ht\else\topskip\fi} % #1行取りの領域の高さ:行送りに#1から1を減じた数を掛け,「あ」の高さと深さを加えた長さ \def\@gyoudori@areaheight#1{% \dimexpr\@gyoudori@bs*(#1-1)+\@gyoudori@ht+\@gyoudori@dp\relax} % 高さ#2が収まる最少の行数(#1行以上)を\@gyoudori@linesに得る. % 文書の\loopや\@whiledimの中で呼ばれても干渉しないよう,専用の繰り返しにする \newcount\@gyoudori@lines \def\@gyoudori@fitlines#1#2{% \@gyoudori@lines#1\relax \@gyoudori@fitloop{#2}} \def\@gyoudori@fitloop#1{% \ifdim\@gyoudori@areaheight\@gyoudori@lines<#1\relax \advance\@gyoudori@lines\@ne \expandafter\@gyoudori@fitloop \else \expandafter\@gobble \fi{#1}} % 行数#1が1以上の整数か確かめる \def\@gyoudori@checklines#1{% \@tempcnta\numexpr#1\relax \ifnum\@tempcnta<\@ne \PackageError{gyoudori}{The number of lines must be 1 or more}{% You gave `#1'.}% \fi} %% 領域の中での位置 \def\@gyoudori@pos@t#1{#1\vss} \def\@gyoudori@pos@c#1{\vss#1\vss} \def\@gyoudori@pos@b#1{\vss#1\vskip\z@}% \vskip\z@で深さを0にし,下端にそろえる \def\@gyoudori@checkpos#1{% \@ifundefined{@gyoudori@pos@#1}{% \PackageError{gyoudori}{Undefined position `#1'}{% The position is t, c or b.}}{}} % gyoudori環境と\gyoudoriareaの省略可能な引数:位置(t/c/b),local,indent,noindentを % カンマで区切って並べる.位置を\@gyoudori@posに得て,localがあれば基準をその場のものに % 切り替え,indent/noindentで内容の字下げを決める(既定はパッケージオプションindent) \newif\if@gyoudori@indent \def\@gyoudori@options#1{% \def\@gyoudori@pos{c}% \let\@gyoudori@getmetrics\@gyoudori@metrics \ifgyoudori@indent\@gyoudori@indenttrue\else\@gyoudori@indentfalse\fi \edef\@tempc{\zap@space#1 \@empty}% \@for\@tempa:=\@tempc\do{% \ifx\@tempa\@empty\else \@gyoudori@option\@tempa \fi}} \def\@gyoudori@option#1{% \def\@tempb{local}% \ifx#1\@tempb \let\@gyoudori@getmetrics\@gyoudori@metrics@local \else \def\@tempb{indent}% \ifx#1\@tempb \@gyoudori@indenttrue \else \def\@tempb{noindent}% \ifx#1\@tempb \@gyoudori@indentfalse \else \@gyoudori@checkpos#1% \let\@gyoudori@pos#1% \fi \fi \fi} %% 行取りの本体:#3を#2行取りして,位置#1(t/c/b)に置く. % 領域を1行目の行として\baselineskipで置き,次の行を領域の最終行から\baselineskipで送る % (https://abenori.blogspot.com/2017/12/gyodori.html の方法による).領域は次の3つで % 表す.途中に改ページ・改段できるところはなく,ページ分割の上では#2行の本文の行と % 同じに扱われる(深さが\maxdepthを超える箱を置かないので,最終行の下にはみ出さない) % ・領域の箱:高さを1行目の字の枠の高さ(「あ」の高さ),深さを0にする(中身は下に % はみ出して描かれる) % ・行送りに#2から1を減じた数を掛けた長さのカーン(最終行のベースラインまで) % ・深さが「あ」の深さの空の箱(最終行) % ページ(段)の先頭では,\topskipにより領域の上端が1行目の字の枠の上端(版面の天)に % つき,領域の中の位置は#1に従う. \newbox\@gyoudori@area \def\@gyoudori@place#1#2#3{% \@gyoudori@getmetrics \setbox\@gyoudori@area\vbox to\@gyoudori@areaheight{#2}{% \csname @gyoudori@pos@#1\endcsname{#3}}% \ht\@gyoudori@area\@gyoudori@ht \dp\@gyoudori@area\z@ \par \moveright\@totalleftmargin\box\@gyoudori@area \nointerlineskip \kern\dimexpr\@gyoudori@bs*(#2-1)\relax \hbox{\vrule\@height\z@\@depth\@gyoudori@dp\@width\z@}% \prevdepth\@gyoudori@dp} %% gyoudori環境と\gyoudoriareaの内容 % 内容を箱に組む.先頭の区切り(\penalty-10000)は1行目のベースラインを求めるためのもの. % 内容の最後で,その文字サイズの「あ」の高さ・深さ(字の枠)を記録する \newdimen\@gyoudori@cht \newdimen\@gyoudori@cdp \newdimen\@gyoudori@mathbase % 内容(数式)の1行目から最後の行までのベースラインの距離 \newdimen\@gyoudori@mathoff % 領域の上端から内容(数式)の箱の上端まで \def\@gyoudori@content@begin{% % 直前の行取りの環境の後の字下げの抑制(\@gyoudori@doendpe)は内容には効かせない \@restorepar\everypar{}\@endpefalse \if@gyoudori@indent\else\parindent\z@\fi \penalty-\@M} \def\@gyoudori@content@end{% \par \setbox\z@\hbox{あ}% \global\@gyoudori@cht\ht\z@ \global\@gyoudori@cdp\dp\z@} % 箱#1の1行目と最後の行のベースラインの距離を\@gyoudori@mathbaseに得る.箱の先頭に % \penalty-10000が必要.その区切りで\vsplitすると,残りの先頭に「\splittopskipから % 1行目の高さを減じた長さ」のグルーが入るので,残りの高さから距離がわかる. % 行がなければ負になる \def\@gyoudori@baselines#1{% \begingroup \setbox\z@\copy#1% \vbadness\@M \vfuzz\maxdimen \splitmaxdepth\maxdimen \splittopskip1000\p@ \setbox\tw@\vsplit\z@ to\z@ \global\@gyoudori@mathbase\dimexpr\ht\z@-1000\p@\relax \endgroup} % 内容の箱#3を#2行取りして,位置#1(t/c/b)に置く.内容の1行目のベースラインの % 「あ」の高さ上から,最後の行のベースラインの「あ」の深さ下までを字の枠の範囲とし, % これを領域の中で位置#1に置く(欧文だけの行でも,和文の行と同じ位置になる). % 内容の字面が領域の外側の行間に半分を超えてはみ出すときは,警告かエラーにする \def\@gyoudori@placecontent#1#2#3{% \@gyoudori@getmetrics \@gyoudori@baselines#3% \ifdim\@gyoudori@mathbase<\z@ % 行がない:箱の大きさで置く \@gyoudori@mathoff\dimexpr\@gyoudori@areaheight{#2}-\ht#3-\dp#3\relax \if t#1\@gyoudori@mathoff\z@\fi \if c#1\@gyoudori@mathoff.5\@gyoudori@mathoff\fi \else % 字の枠の範囲の上端は箱の上端から\@tempdima下,その範囲の高さは\@tempdimb \@tempdima\dimexpr\ht#3-\@gyoudori@mathbase-\@gyoudori@cht\relax \@tempdimb\dimexpr\@gyoudori@mathbase+\@gyoudori@cht+\@gyoudori@cdp\relax \@gyoudori@mathoff\dimexpr\@gyoudori@areaheight{#2}-\@tempdimb\relax \if t#1\@gyoudori@mathoff\z@\fi \if c#1\@gyoudori@mathoff.5\@gyoudori@mathoff\fi \advance\@gyoudori@mathoff-\@tempdima \fi \@tempswafalse \ifdim\@gyoudori@mathoff<-.5\@gyoudori@linegap \@tempswatrue \fi \ifdim\dimexpr\@gyoudori@mathoff+\ht#3+\dp#3\relax >\dimexpr\@gyoudori@areaheight{#2}+\@gyoudori@linegap/2\relax \@tempswatrue \fi \if@tempswa \@gyoudori@overflow{#2}\fi \@gyoudori@place{t}{#2}{\kern\@gyoudori@mathoff\box#3}} \def\@gyoudori@overflow#1{% \def\@tempa{error}% \ifx\gyoudori@overflow\@tempa \PackageError{gyoudori}{Content does not fit in #1 line(s)}{% Increase the number of lines or make the content smaller.}% \else \PackageWarning{gyoudori}{Content does not fit in #1 line(s)}% \fi} %% 行取りした環境の直後 % 空行がなければ後続の段落を字下げせず,\parskipも入れない(リスト内の\parsepで % 行送りがずれないように).空行があれば通常の段落とする. % 環境を抜けた後に,LaTeXの\@doendpeと同じ仕組みで処理する. \def\@gyoudori@doendpe{% \edef\@gyoudori@restoreparskip{\parskip\the\parskip\relax}% \parskip\z@skip \@endpetrue \def\par{% \@restorepar\@gyoudori@restoreparskip \clubpenalty\@clubpenalty\@endpefalse\everypar{}\par}% \everypar{{\setbox\z@\lastbox}% \@gyoudori@restoreparskip\everypar{}\@endpefalse}} %% ユーザー命令 % 見出しとして使うので,直後では改ページ・改段しない.見出しの後ろに本文の行が % 1行も入らないときは,見出し全体が次のページ(段)の先頭に送られる % (JLREQ 4.1.7 b). \newbox\@gyoudori@box % localをつけると,\normalsizeではなくその場の文字サイズと行送りで行取りする % (\smallなどの中で,まわりの行にそろえる). \newenvironment{gyoudori}[2][c]{% \@gyoudori@checklines{#2}% \@gyoudori@options{#1}% \edef\@gyoudori@args{{\@gyoudori@pos}{#2}}% \setbox\@gyoudori@box\vbox\bgroup\@gyoudori@content@begin}{% \@gyoudori@content@end\egroup \expandafter\@gyoudori@placecontent\@gyoudori@args\@gyoudori@box \nobreak} \AddToHook{env/gyoudori/after}{\@gyoudori@doendpe} \newcommand\gyoudoriarea[3][c]{% \@gyoudori@checklines{#2}% \@gyoudori@options{#1}% \setbox\@gyoudori@box\vbox{\@gyoudori@content@begin#3\@gyoudori@content@end}% \expandafter\@gyoudori@placecontent\expandafter{\@gyoudori@pos}{#2}\@gyoudori@box \let\@gyoudori@getmetrics\@gyoudori@metrics \nobreak} %% ディスプレイ数式の自動行取り(displaymath=true) % 数式を環境の外側で開いたボックスに組み,行取りの領域に置く. % 位置は,数式の1行目と最後の行のベースラインの中点を,領域の1行目と最後の行の % ベースラインの中点に合わせる(1行の式を奇数行取りにすると,式のベースラインが % 中央の行のベースラインにのる).行数は,数式の箱が収まる最少の行数に % displaymathextra(既定は1)を足したもの(2行以上)とする.箱は,領域の外側の行間に % 半分まではみ出してよい(隣の行の字の枠との間には行間の半分以上が空く). % 基準はその場の文字サイズの「あ」の高さ・深さと % \baselineskipなので,脚注や\smallの中でもまわりの行にそろう. \newbox\@gyoudori@mathbox \newbox\@gyoudori@prebox \newbox\@gyoudori@tmpbox \def\@gyoudori@math@begin{% \par \setbox\@gyoudori@mathbox\vbox\bgroup \hsize\linewidth \parshape\z@ \abovedisplayskip\z@ \belowdisplayskip\z@ \abovedisplayshortskip\z@ \belowdisplayshortskip\z@ % TeXが式の直前に入れる\predisplaypenaltyを,式とその前の部分を分ける区切りにする % (式の前の段落に,hyperrefのリンクの着地点などが入って行ができることがある) \predisplaypenalty-\@M % amsmathが各行に入れる支柱を「あ」の字の枠にする(見えない深さで行数が増えない % ように.行の間隔は\baselineskipで決まるので変わらない) \setbox\z@\hbox{あ}% \setbox\strutbox\hbox{\vrule\@height\ht\z@\@depth\dp\z@\@width\z@}% \noindent} \def\@gyoudori@math@end{% \par \unskip\unpenalty\unskip\unpenalty % \belowdisplayskipと\postdisplaypenaltyを除く \egroup % 基準はその場の文字サイズと\baselineskip(脚注や\smallの中でもまわりの行にそろう. % \normalsizeの本文では\normalsizeの基準と同じ) \let\@gyoudori@getmetrics\@gyoudori@metrics@local \@gyoudori@getmetrics \@gyoudori@math@split % 1行目と最後の行のベースラインの距離を,式の部分だけで測る \setbox\@gyoudori@tmpbox\vbox{\penalty-\@M\unvcopy\@gyoudori@mathbox}% \@gyoudori@baselines\@gyoudori@tmpbox \@gyoudori@lines\z@ \@gyoudori@mathfit % 式の前の部分(リンクの着地点など)は,高さ0にして式の先頭に重ねて残す \ifvoid\@gyoudori@prebox\else \setbox\@gyoudori@mathbox\vbox{% \vbox to\z@{\unvbox\@gyoudori@prebox\vss}% \unvbox\@gyoudori@mathbox}% \fi \@gyoudori@place{t}{\@gyoudori@lines}% {\kern\@gyoudori@mathoff\box\@gyoudori@mathbox}% \let\@gyoudori@getmetrics\@gyoudori@metrics \@gyoudori@doendpe} % 式の箱を,区切り(\predisplaypenalty)の手前の部分\@gyoudori@preboxと,式の部分 % \@gyoudori@mathboxに分ける.区切りがなければ(\samepageなどで\predisplaypenaltyが % 変えられたとき),全体を式の部分とする \def\@gyoudori@math@split{% \begingroup \vbadness\@M \vfuzz\maxdimen \splitmaxdepth\maxdimen \splittopskip\z@ \global\setbox\@gyoudori@prebox\vsplit\@gyoudori@mathbox to\maxdimen \global\setbox\@gyoudori@mathbox\box\@gyoudori@mathbox \endgroup \ifvoid\@gyoudori@mathbox \global\setbox\@gyoudori@mathbox\box\@gyoudori@prebox \fi} % 行数と位置を決める.式が要する行数は,式の箱(高さ+深さ)が,その行数の領域の外側の % 行間に半分まではみ出して収まる最少の行数(本文の行の字面が字の枠からはみ出すのと % 同じ扱い).行取りの行数は,これにdisplaymathextra(既定は1)を足したもの(2行以上). % 位置は,式の1行目と最後の行のベースラインの中点を領域の中点に合わせる(式を中央に % 置く)のを基本とし,はみ出すときだけ収まる範囲に寄せる % (文書の\loopと干渉しないよう,\loopは使わない) \def\@gyoudori@mathfit{% \advance\@gyoudori@lines\@ne \ifdim\dimexpr\ht\@gyoudori@mathbox+\dp\@gyoudori@mathbox\relax >\dimexpr\@gyoudori@areaheight\@gyoudori@lines+\@gyoudori@linegap\relax \expandafter\@gyoudori@mathfit \else \advance\@gyoudori@lines\gyoudori@displaymathextra\relax \ifnum\@gyoudori@lines<\tw@ \@gyoudori@lines\tw@ \fi \@gyoudori@mathoff\dimexpr \@gyoudori@ht+\@gyoudori@bs*(\@gyoudori@lines-1)/2 -\ht\@gyoudori@mathbox+\@gyoudori@mathbase/2\relax \@tempdima-.5\@gyoudori@linegap \ifdim\@gyoudori@mathoff<\@tempdima \@gyoudori@mathoff\@tempdima \fi \@tempdima\dimexpr\@gyoudori@areaheight\@gyoudori@lines+\@gyoudori@linegap/2 -\ht\@gyoudori@mathbox-\dp\@gyoudori@mathbox\relax \ifdim\@gyoudori@mathoff>\@tempdima \@gyoudori@mathoff\@tempdima \fi \fi} % 環境のグループの外側(before/after)にフックする.align*は内部で\endalignを % 呼ぶが,フックは\begin/\endでだけはたらくので二重にはならない. \def\@gyoudori@math@hook#1{% \AddToHook{env/#1/before}{\@gyoudori@math@begin}% \AddToHook{env/#1/after}{\@gyoudori@math@end}} % \[ \]:amsmathはequation*環境として定義し直すので,そのフックで行取りされる. % amsmathがないときは,カーネルの\[ \]を包む(displaymath環境も\[ \]を使う) \def\@gyoudori@math@brackets{% \@ifpackageloaded{amsmath}{}{% \NewCommandCopy\@gyoudori@orig@lbrack\[% \NewCommandCopy\@gyoudori@orig@rbrack\]% \DeclareRobustCommand\[{\@gyoudori@math@begin\@gyoudori@orig@lbrack}% \DeclareRobustCommand\]{\@gyoudori@orig@rbrack\@gyoudori@math@end}}} \ifgyoudori@displaymath \@for\@tempa:=equation,equation*,eqnarray,eqnarray*,align,align*,% gather,gather*,multline,multline*,flalign,flalign*,alignat,alignat*\do {\expandafter\@gyoudori@math@hook\expandafter{\@tempa}} \AtBeginDocument{\@gyoudori@math@brackets} \fi %% フロートの行取り(float=true) % フロートは,それが収まる最少の行取り領域(1行以上)のボックスにする. % 置き場所が決まったら,同じ高さのまま中身を上なら[t],下なら[b],本文中なら中央に % 組み直し,領域が本文の行の字の枠にそろうようにずらす. % アキは「行送りの整数倍に行間を加えた長さ」に丸めるので,フロートの前後で本文の行送りは % ずれない.フロートだけのページ(段)では,フロートを上寄せにして行の位置にそろえる. % 行間:行送りから「あ」の高さと深さを減じた長さ \def\@gyoudori@linegap{% \dimexpr\@gyoudori@bs-\@gyoudori@ht-\@gyoudori@dp\relax} % アキ#1を,「行送りの整数倍に行間を加えた長さ」のうち#1以上で最小のものにする(伸縮なし) \def\@gyoudori@roundsep#1{% \@tempdima\@gyoudori@linegap \@whiledim\@tempdima<#1\do{\advance\@tempdima\@gyoudori@bs}% #1\@tempdima} \def\@gyoudori@float@seps{% \@gyoudori@metrics \@gyoudori@roundsep\floatsep \@gyoudori@roundsep\textfloatsep \@gyoudori@roundsep\dblfloatsep \@gyoudori@roundsep\dbltextfloatsep % 本文中のフロート([h])は上下に\intextsepが入るので,行間を半分ずつ割り振る \@gyoudori@roundsep\intextsep \advance\intextsep-.5\@gyoudori@linegap % フロートだけのページ(段):最初のフロートの領域の上端を本文1行目の字の枠の上端に % そろえ(上寄せ),フロートの間のアキを丸める.余りは下に置く \@gyoudori@fppage\@fptop\@fpsep\@fpbot \@gyoudori@fppage\@dblfptop\@dblfpsep\@dblfpbot} \def\@gyoudori@fppage#1#2#3{% #1\dimexpr\@gyoudori@firstbase-\@gyoudori@ht\relax \@gyoudori@roundsep#2% #3\z@\@plus1fil\relax} % \end{figure}など:フロートのボックスを行取り領域の高さにする(中身は[t]) \def\@gyoudori@float@box{% \@gyoudori@metrics \@gyoudori@fitlines\@ne{\dimexpr\ht\@currbox+\dp\@currbox\relax}% \global\setbox\@currbox\vbox to\@gyoudori@areaheight\@gyoudori@lines{% \@gyoudori@pos@t{\box\@currbox}}} % フロートのボックス#1を,同じ高さのまま,中身を位置#2(t/c/b)に置き, % #3だけ下にずらして組み直す.ボックスの高さと深さは変えない(LaTeXは段抜きの % フロートを深さ1spで見分ける) \newbox\@gyoudori@floatbody \def\@gyoudori@float@set#1#2#3{% \@tempdima\ht#1% \@tempdimb\dp#1% % 末尾のグルー(多くて2つ)を除いて中身を取り出す.\@gyoudori@float@boxが作った形で % ない箱(\@topnewpageの段抜きの表題のように末尾がwhatsitのものなど)からは取り出せ % ないので,そのときは組み直さずにもとのまま残す \global\setbox\@gyoudori@floatbody\box\voidb@x \setbox\z@\vbox{% \unvcopy#1\unskip\unskip \ifnum\lastnodetype>\z@ \ifnum\lastnodetype<\thr@@ % 箱(hlistかvlist) \global\setbox\@gyoudori@floatbody\lastbox \fi\fi}% \ifvoid\@gyoudori@floatbody\else \global\setbox#1\vbox to\dimexpr\@tempdima+\@tempdimb\relax{% \vskip#3\relax \csname @gyoudori@pos@#2\endcsname{\box\@gyoudori@floatbody}% \vskip-#3\relax}% \global\ht#1\@tempdima \global\dp#1\@tempdimb \fi} % フロートを積む各マクロ(\@comflelt)が使う,中身の位置とずらし量 \def\@gyoudori@floatpos{t} \def\@gyoudori@floatshift{\z@} % 上のフロート:[t].本文1行目の字の枠の上端(1行目のベースラインから「あ」の高さだけ上)に % そろえる \def\@gyoudori@floattop{% \@gyoudori@metrics \def\@gyoudori@floatpos{t}% \edef\@gyoudori@floatshift{\the\dimexpr\@gyoudori@firstbase-\@gyoudori@ht\relax}} % \@tempdimb = 段#1の最後の行の深さ.段の箱の深さは\maxdepthで打ち切られている % ことがあるので,最後の箱を取り出してその深さを使う(行取りの領域の最後は深さが % 「あ」の深さの空の箱) \def\@gyoudori@lastdepth#1{% \setbox\z@\vbox{% \unvcopy#1% \global\@tempdimb\dp#1% \ifnum\lastnodetype>\z@ \ifnum\lastnodetype<\thr@@ % 箱(hlistかvlist) \setbox\z@\lastbox \global\@tempdimb\dp\z@ \fi\fi}} % 本文の直後に置く下のフロート:[b].本文の最終行の実際の深さ#1を「あ」の深さと % みなしてそろえる \def\@gyoudori@floatbot#1{% \@gyoudori@metrics \def\@gyoudori@floatpos{b}% \edef\@gyoudori@floatshift{\the\dimexpr\@gyoudori@dp-#1\relax}} % \@tempdima = 高さ#1の版面(段)に入る最終行のベースラインから,その下端までの余り % (1行目のベースラインは\@gyoudori@firstbase,以降は行送りごと) \def\@gyoudori@lastlinegap#1{% \@tempdima\dimexpr#1-\@gyoudori@firstbase\relax \@tempcnta\@tempdima \@tempcntb\@gyoudori@bs \divide\@tempcnta\@tempcntb \advance\@tempdima-\@tempcnta\@gyoudori@bs} % 下のフロート(\@cflb) \newif\if@gyoudori@pushed % 本文の末尾がグルーかカーン(\clearpageの\vfilなど)なら真 \def\@gyoudori@ifpushed{% \setbox\z@\vbox{\unvcopy\@outputbox\global\@tempcnta\lastnodetype}% \@gyoudori@pushedfalse \ifnum\@tempcnta>10 \ifnum\@tempcnta<13 \@gyoudori@pushedtrue\fi\fi} \def\@gyoudori@cflb{% % 本文の末尾がグルーなら,フロートは本文の直後ではなく版面の下端に押し下げ % られる.脚注の後に下のフロートを積むカーネル(LuaLaTeXなど)では,脚注の前に % \vfilを入れてあるので,やはり版面の下端に置かれる \if@gyoudori@fnabove \@gyoudori@pushedtrue \global\@gyoudori@fnabovefalse \else \@gyoudori@ifpushed \fi \if@gyoudori@pushed \@gyoudori@floatbot\@gyoudori@dp % ずらさない \else \@gyoudori@metrics \@gyoudori@lastdepth\@outputbox \@gyoudori@floatbot\@tempdimb \fi \@gyoudori@orig@cflb \@gyoudori@bottomfit} % \@tempdimb = 下のフロートの後ろ(段の最下部)に置かれる脚注の高さ(pLaTeXの % \@makecolは,フロートの後に\skip\footins,脚注罫,脚注を足す.最後の行の深さは % 段の高さに数えない).脚注を先に積むカーネルでは,ここでは\footinsは空 \newif\if@gyoudori@fnabove \def\@gyoudori@footnoteheight{% \ifvoid\footins \@tempdimb\z@ \else \setbox\z@\vbox{\footnoterule}% \@tempdimb\dimexpr\skip\footins+\ht\z@+\dp\z@+\ht\footins\relax \fi} % 下のフロートの並びの末尾を整える % ・最後のフロートの下端から「あ」の深さだけ上を行のベースラインとみなし,深さ「あ」の % 深さの空の行を置く(flushendが最終ページで段をつなぎ直すときにも,行として % 扱われて行送りがそろう) % ・その後に『版面に入る最終行のベースラインと版面の下端との間の余りから「あ」の深さを減じた長さ』 % を足す(脚注があれば,版面の高さから脚注の高さを引いて求める). % 押し下げられたとき(\clearpageの\vfil)に最終行の字の枠の下端にそろい, % 字の枠の下端が版面からはみ出すクラスでもOverfullにならない % ・押し下げられたときは,\@textbottom(\raggedbottomの.0001fil)の伸びを打ち消す \def\@gyoudori@bottomfit{% \@gyoudori@footnoteheight \@gyoudori@lastlinegap{\dimexpr\@colht-\@tempdimb\relax}% \setbox\z@\vbox{\@textbottom\global\@tempskipa\lastskip}% \setbox\@outputbox\vbox{% \unvbox\@outputbox \if@gyoudori@pushed\vskip-\@tempskipa\fi \vskip-\@gyoudori@dp \nointerlineskip \hbox{\vrule\@height\z@\@depth\@gyoudori@dp\@width\z@}% \vskip\dimexpr\@tempdima-\@gyoudori@dp\relax}} % フロートの並びをつくるときに1つずつ呼ばれる \def\@gyoudori@comflelt#1{% \@gyoudori@float@set#1\@gyoudori@floatpos\@gyoudori@floatshift \@gyoudori@orig@comflelt#1} % 段抜きのフロート \def\@gyoudori@comdblflelt#1{% \expandafter\in@\expandafter#1\expandafter{\@dbltoplist}% \ifin@ \@gyoudori@floattop \else % nidanfloatの段抜きの下:[b].並びの下端は版面の下端に来るので, % 版面に入る最終行の字の枠の下端にそろえる \@gyoudori@metrics \@gyoudori@lastlinegap\textheight \def\@gyoudori@floatpos{b}% \edef\@gyoudori@floatshift{\the\dimexpr\@gyoudori@dp-\@tempdima\relax}% % 並びの先頭に\vfilを置き,段が短いとき(balanceオプションの最終ページ)も % 版面の下端に置かれるようにする(アキに伸びがないので) \ifdim\ht\@tempboxa=\z@ \setbox\@tempboxa\vbox{\vfil}\fi \fi \@gyoudori@float@set#1\@gyoudori@floatpos\@gyoudori@floatshift \@gyoudori@orig@comdblflelt#1} % 本文中のフロート([h]):中央.直前の行の深さ\@pagedpを「あ」の深さとみなしてそろえる % (本文中に置けずに上か下に回ったときは,そこで改めて組み直される) % 段の先頭に来ると前のアキが捨てられて位置がずれるので,直前では改段させない % (\if@nobreakが真だと,カーネルは\interlinepenaltyの代わりに\nobreakを入れる. % 本文中に置かれなかったときはもとに戻す) \def\@gyoudori@addtocurcol{% \@gyoudori@metrics \@gyoudori@float@set\@currbox{c}% {\dimexpr\@gyoudori@linegap/2+\@gyoudori@dp-\@pagedp\relax}% \if@nobreak \def\@gyoudori@restore@nobreak{\@nobreaktrue}% \else \def\@gyoudori@restore@nobreak{\@nobreakfalse}% \fi \@nobreaktrue \let\@gyoudori@midlist\@midlist \@gyoudori@orig@addtocurcol % 本文中に置かれたとき(\@midlistに加わったとき)は,カーネルが\if@nobreakを使って % 偽にしている.上や下に置かれたとき,置けなかったときは,もとに戻す(\if@insertは % 上や下に置かれたときも真になるので,判定に使えない) \ifx\@midlist\@gyoudori@midlist\@gyoudori@restore@nobreak\fi} % nidanfloatの2段組の段ごとの下のフロート(\L@cflb,\R@cflbの置き換え. % nidanfloat v2.9による).もとの定義はフロートの後ろにも\vssがあり,位置が伸びの % 配分で決まるので,フロートの並びを段に入る最終行の字の枠の下端にそろえ,伸びは % 本文とフロートの間に置く. % #1:段のボックス,#2:フロートのリスト,#3:段の高さ, % #4:\@makecolで組み直される右段では,\@textbottomの伸びを打ち消す \def\@gyoudori@nidan@cflb#1#2#3#4{% \@gyoudori@floatbot\@gyoudori@dp % 段の下端にそろえるので,ずらさない \let\@elt\@comflelt \setbox\@tempboxa\vbox{}% #2% \@gyoudori@lastlinegap#3% \setbox\z@\vbox{\@textbottom\global\@tempskipa\lastskip}% \setbox#1\vbox to#3{\boxmaxdepth\maxdepth \unvbox#1\vfil \vskip\textfloatsep\botfigrule\unvbox\@tempboxa\vskip-\floatsep \vskip\dimexpr\@tempdima-\@gyoudori@dp\relax #4}% \let\@elt\relax \xdef\@freelist{\@freelist#2}% \global\let#2\@empty \@colht#3} % flushendの最終ページの左右の段:同じ高さのまま,段の中のグルーを伸縮させずに % 組み直す.flushendは段の高さの端数を段の中のグルー(\parskipなど)に配るので, % nospread/noshrinkを指定しても行送りがずれる.段の高さは行送りと無関係に決まる % ので,fil次のグルー(\clearpageの\vfilなど)も伸ばさない(末尾をfill次にする) \def\@gyoudori@flushend@natural{% \@gyoudori@natural\@leftcolumn \@gyoudori@natural\@outputbox} \def\@gyoudori@natural#1{% \setbox#1\vbox to\ht#1{\unvbox#1\vskip\z@\@plus1fill\@minus1fill}} % フロートの箱#1の中身のずらし量(\@gyoudori@float@setの#3.箱の中の先頭の % グルー)を\@gyoudori@shiftに得る \newdimen\@gyoudori@shift \def\@gyoudori@shiftof#1{% \setbox\z@\vbox{% \unvcopy#1\unskip\unskip \setbox\z@\lastbox \ifnum\gluestretchorder\lastskip>\z@ \unskip\fi \global\@gyoudori@shift\lastskip}} % 左段の最後の要素について,ベースライン(フロートなら,中身の領域の下端から % 「あ」の深さだけ上)から箱の下端までを\@gyoudori@leftdepthに得る \newdimen\@gyoudori@leftdepth \def\@gyoudori@leftlast{% \setbox\z@\vbox{% \unvcopy\flushend@@varbox@a \unskip\unkern\unpenalty\unskip\unkern\unpenalty\unskip\unkern\unpenalty \global\setbox\@gyoudori@floatbody\lastbox}% \ifvbox\@gyoudori@floatbody \@gyoudori@shiftof\@gyoudori@floatbody \global\@gyoudori@leftdepth\dimexpr\@gyoudori@dp-\@gyoudori@shift\relax \else \global\@gyoudori@leftdepth\dp\@gyoudori@floatbody \fi} % 縦のリストの末尾からグルー・カーン・ペナルティと箱を取り除いていき,最後に取り除いた % 箱(リストの先頭の箱)を\@gyoudori@floatbodyに得る.ほかの種類の要素で止まる \def\@gyoudori@firstbox{% \ifnum\lastnodetype>10 \ifnum\lastnodetype<14 \unskip\unkern\unpenalty \expandafter\expandafter\expandafter\@gyoudori@firstbox \fi\fi \ifnum\lastnodetype>\z@ \ifnum\lastnodetype<\thr@@ \global\setbox\@gyoudori@floatbody\lastbox \expandafter\expandafter\expandafter\@gyoudori@firstbox \fi\fi} % flushendが左右の段をつなぐところ(\atColsBreakの位置):つなぎ目の間隔を % 行送りの整数倍に切り上げる.flushendはつなぎ目に「右段の先頭で捨てられた % グルー」を入れるが,段の切れ目がフロートの処理と重なると,それが行間の % \baselineskipではなく\topskipになり,つなぎ目が詰まる. % 左段の最後の要素のベースラインから,右段の最初の要素のベースライン(フロート % なら中身の領域の上端から「あ」の高さだけ下.中身は箱の上端からずらし量だけ下に % ある)までを,行送りの整数倍にする \def\@gyoudori@colsbreak{% \ifdim\ht\@outputbox>\z@ \@gyoudori@metrics \begingroup % 右段の最初の要素を取り出す \setbox\z@\vbox{\unvcopy\@outputbox}% \splittopskip\z@ \splitmaxdepth\maxdimen \vbadness\@M \vfuzz\maxdimen \setbox\tw@\vsplit\z@ to\z@ % 切り出した部分は,行取りの領域なら箱・カーン・空の箱の3つになるので, % 末尾から取り除いていき,先頭の箱を得る \global\setbox\@gyoudori@floatbody\box\voidb@x \setbox\tw@\vbox{\unvbox\tw@\@gyoudori@firstbox}% \endgroup % \oldbreak@skip:flushendがつなぎ目に入れたグルー \@tempdima\dimexpr\@gyoudori@leftdepth+\oldbreak@skip\relax \ifvbox\@gyoudori@floatbody \@gyoudori@shiftof\@gyoudori@floatbody \advance\@tempdima\dimexpr\@gyoudori@ht+\@gyoudori@shift\relax \else \advance\@tempdima\ht\@gyoudori@floatbody \fi \@tempdimb\@gyoudori@bs \@whiledim\@tempdimb<\@tempdima\do{\advance\@tempdimb\@gyoudori@bs}% \vskip\dimexpr\@tempdimb-\@tempdima\relax \fi} % 脚注を下のフロートより先に積むカーネル(LaTeX 2025-06-01以降の\@makecol. % 既定のfootnotes-floats-legacyなど):下のフロートがあれば,脚注の前に\vfilを % 入れて,脚注と下のフロートを版面の下端に置く(本文が\vfilで終わっていれば % そのまま) \def\@gyoudori@appendfootnotes{% \global\@gyoudori@fnabovefalse \ifvoid\footins\else\ifx\@botlist\@empty\else \global\@gyoudori@fnabovetrue \@gyoudori@ifpushed \if@gyoudori@pushed\else \setbox\@outputbox\vbox{\unvbox\@outputbox\vfil}% \fi \fi\fi \@gyoudori@orig@@outputbox@appendfootnotes} % evenend:最終ページでは,段内フロートの複製を\@makecolの前にとって自分で段を % 組むので,その前に上のフロートを[t],下のフロートを[b]に組み直しておく % (下のフロートは段の下端につけられるので,ずらさない) \def\@gyoudori@evenend@prep{% \begingroup \@gyoudori@floattop \def\@elt##1{\@gyoudori@float@set##1\@gyoudori@floatpos\@gyoudori@floatshift}% \@toplist \def\@elt##1{\@gyoudori@float@set##1{b}\z@}% \@botlist \endgroup} % evenend:持ち越された段内フロート\evenendfloatboxを上寄せに組み直す \def\@gyoudori@evenend@deferred{% \begingroup \@gyoudori@floattop \@gyoudori@float@set\evenendfloatbox\@gyoudori@floatpos\@gyoudori@floatshift \endgroup} % 出力ルーチンのマクロ#1の前に#2を足す(もとの定義は\@gyoudori@orig@#1) \def\@gyoudori@prepend#1#2{% \expandafter\let\csname @gyoudori@orig@#1\expandafter\endcsname \csname #1\endcsname \expandafter\def\csname #1\endcsname{#2\csname @gyoudori@orig@#1\endcsname}} % 出力ルーチンを書き換えるパッケージ(nidanfloat)の後で差し替える \def\@gyoudori@float@install{% \@gyoudori@float@seps \g@addto@macro\@endfloatbox{\@gyoudori@float@box}% \@gyoudori@prepend{@cflt}{\@gyoudori@floattop}% \let\@gyoudori@orig@cflb\@cflb \let\@cflb\@gyoudori@cflb \let\@gyoudori@orig@comflelt\@comflelt \let\@comflelt\@gyoudori@comflelt \let\@gyoudori@orig@comdblflelt\@comdblflelt \let\@comdblflelt\@gyoudori@comdblflelt \let\@gyoudori@orig@addtocurcol\@addtocurcol \let\@addtocurcol\@gyoudori@addtocurcol % フロートだけのページ(段):本文中のフロートとして試したときの組み方が残っているので, % 上寄せに組み直してから積む \let\@gyoudori@orig@wtryfc\@wtryfc \def\@wtryfc##1{\@gyoudori@float@set##1{t}\z@\@gyoudori@orig@wtryfc##1} % フロートだけのページ(段)に収まるかの判定で,LaTeXは\@fptopを数えないので, % 判定のときだけ段の高さから差し引く.\@xtryfcは,ページが組めると残りの候補の判定を % 止めるために\@eltを局所的に\@gobbleにするので,グループを出た後でし直す % 版面より高いフロートは,LaTeXが\@largefloatcheckで版面の高さに縮める.上の判定と % 合わせて\@fptopの分も縮める(でないと,いつまでも収まらないと判定されて出力が % 空回りする) \let\@gyoudori@orig@largefloatcheck\@largefloatcheck \def\@largefloatcheck{% \@gyoudori@orig@largefloatcheck \ifdim\ht\@currbox>\dimexpr\textheight-\@fptop\relax \@latex@warning{Float too large for page by \the\dimexpr\ht\@currbox-\textheight+\@fptop\relax\space (gyoudori aligns it below \string\@fptop)}% \ht\@currbox\dimexpr\textheight-\@fptop\relax \fi}% \let\@gyoudori@orig@xtryfc\@xtryfc \def\@xtryfc##1{\begingroup \advance\@colht-\@fptop\relax \@gyoudori@orig@xtryfc##1\endgroup \if@fcolmade\let\@elt\@gobble\fi} % 脚注を下のフロートより先に積むカーネル(pLaTeXは独自の\@makecolを使う) \@ifundefined{pltx@adjust@wd@outputbox}{% \@ifundefined{@outputbox@appendfootnotes}{}{% \let\@gyoudori@orig@@outputbox@appendfootnotes\@outputbox@appendfootnotes \let\@outputbox@appendfootnotes\@gyoudori@appendfootnotes}}{}% % nidanfloatの2段組:段ごとのフロート \@ifundefined{L@cflt}{}{% \@gyoudori@prepend{L@cflt}{\@gyoudori@floattop}% \@gyoudori@prepend{R@cflt}{\@gyoudori@floattop}% \def\L@cflb{\@gyoudori@nidan@cflb\@leftcolumn\L@botlist\@fixht{}}% \def\R@cflb{\@gyoudori@nidan@cflb\@outputbox\R@botlist\@rightfixht {\vskip-\@tempskipa}}}% % evenend \@ifundefined{evenend@capture}{}{% \@gyoudori@prepend{evenend@capture}{\@gyoudori@evenend@prep}% % 段数の切り換えや最終ページで,持ち越された段内フロート(\evenendfloatbox)は % 段の上に置かれるので,上のフロートと同じく上寄せに組み直す \AddToHook{evenend/deferredfloat}{\@gyoudori@evenend@deferred}}% % flushend:最終ページの段の組み上げの後に足す \@ifundefined{set@outputbox@with@footnote@and@float}{}{% \g@addto@macro\set@outputbox@with@footnote@and@float {\@gyoudori@flushend@natural}% \@gyoudori@prepend{combine@columns@for@balance}{% \@gyoudori@leftlast \atColsBreak\expandafter{\expandafter\@gyoudori@colsbreak\the\atColsBreak}}}} \ifgyoudori@float \AtBeginDocument{\@gyoudori@float@install} \fi \endinput