LaTeX 如何在設置行距後讓字體垂直居中?

(文字說明可能不是很清楚,直接上圖)

不管是用fontsize還是設置aselineskip還是設置比例係數什麼的,

由於行距定義為基線之間的距離,只要行距大於字型大小,多出來的空白全部位於文字上方

這樣的上下不對稱空白造成一系列的排版不對稱問題

比如設置圖表浮動體距離文本為intextsep=6pt,圖距離上下文本間隙應該一致對稱的,但是,實際效果就是這樣:

圖片上方距離文字就是6pt,但是圖片下方距離文字為6pt+aselineskip-f@size!!!!

類似的問題在表格內部字體、段落間距設置的時候也都會出現。

我知道可以用vspace一個個的調,但是這樣很不爽啊。。。。

那麼問題來了,有沒有方法讓設置行距的時候文字上下居中?

不明白我在問什麼?直接上圖,能不能做到這樣的效果?讓文字就在當前行的中間(垂直居中)

----------------------------------------2016年5月24日分割線--------------------------------------------------------

感謝@劉海洋 大神和@李青 大神的回復,在此總結一下我的問題和最後採用的解決方案:

1、首先,我的問題的來源為:

最初就是浮動體和上下文的間距問題,還有一個就是設置標題段前段後間距的時候標題與上下文之間的距離問題。當字型大小和行距相等的時候,浮動體與上下文間距是沒有問題的,標題與上下文間距會有一些偏差!!

documentclass[a4paper,openany,UTF8,10pt,
scheme=plain,
]{ctexart}

usepackage{graphicx}

makeatletter

enewcommand
ormalsize{%
@setfontsize
ormalsize{10pti}{10pt} % 改變字型大小和行距
abovedisplayskip=12pt plus 2pt minus 2pt
abovedisplayshortskip=0pt plus 2pt minus 2pt
elowdisplayskip=abovedisplayskip
elowdisplayshortskip=abovedisplayshortskip
}
makeatother

ctexset{%
section={
format={heitifontsize{20pt}{20pt}selectfont},% 標題字型大小
beforeskip=0pt, % 段前0pt
afterskip =0pt, % 段後0pt
},
}

setlengthintextsep{0pt} % 浮動體距離上下文0pt
setlengthparindent{0pt}

egin{document}

燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙

ule{0.5linewidth}{1pt}

%
ointerlineskip
section{屯屯屯屯屯屯}

燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙

ule{0.5linewidth}{1pt}

egin{figure}[htbp]
centering
includegraphics[w=.4linewidth]{example-image.pdf}
caption{example-image}
end{figure}

%
ointerlineskip

ule{0.5linewidth}{1pt}
燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙

end{document}

這裡說明一下,雖然@李清 大神說了在單獨使用rule的時候,浮動體下方的rule與浮動體之間是有距離的,那是由於rule是基線對其,所以rule上方有一個fontsize的空白高度,在加入文字後,可以看到是沒有問題的。

但是,當文字字型大小和行距不等的時候,由於行距多出來的空白全部填充到文字上方,使得浮動體上下間隙就不相等了:

如下圖:(這是文本的字型大小和行距不相等的時候)

@setfontsize
ormalsize{10pti}{10pt} % 這行改為

@setfontsize
ormalsize{10pti}{15pt}

(這是標題的字型大小和行距不相等的時候)

format={heitifontsize{20pt}{20pt}selectfont},% 標題字型大小 %改為

format={heitifontsize{20pt}{30pt}selectfont},% 標題字型大小

就是由於這個行距大於字型大小的部分都填充在文字上方,破壞了這種原本的對稱間隙關係

所以提出問題:能否有方法使得多出來的行距能夠平均的填充在文字的上下方。

(哎呀,不能超過3000字?請看我自己的回復吧)


@劉海洋 在評論中已經談到了很多,還有一個叫
ointerlineskip 的東西。就讓我們具體來看看問題中提到的浮動體前後距離不一致:

documentclass{article}

usepackage{graphicx}

setlengthintextsep{0pt}

egin{document}

oindent
ule{linewidth}{1pt}

egin{figure}[htbp]
centering
includegraphics[w=.5linewidth]{example-image.pdf}
caption{example-image}
end{figure}

oindent
ule{linewidth}{1pt}

end{document}

可以看到,浮動體底部與正文確實有一定的距離,不是我們設置的 0pt。這個距離是 TeX 插入行間 glue 產生的,按通常做法,在浮動體下方的文字之前設置
ointerlineskip 加以抑制就可以:

documentclass{article}

usepackage{graphicx}

setlengthintextsep{0pt}

egin{document}

oindent
ule{linewidth}{1pt}

egin{figure}[htbp]
centering
includegraphics[w=.5linewidth]{example-image.pdf}
caption{example-image}
end{figure}

ointerlineskip

oindent
ule{linewidth}{1pt}

end{document}

但是,既然是浮動體,就很有可能會被浮動到別的地方去,主要的困難是具體要在哪裡加
ointerlineskip。好在 LaTeX3 項目小組的領導 Frank Mittelbach 給出了詳細的解釋和解決辦法 [1]:

documentclass{article}

usepackage{graphicx}

setlengthintextsep{0pt}

usepackage{etoolbox}
makeatletter
%% http://tex.stackexchange.com/a/40363
patchcmd{@addtocurcol}%
{vskip intextsep}%
{edefsave@first@penalty{ helastpenalty}unpenalty
ifnum lastpenalty = @M % hopefully the OR penalty
unpenalty
else
penalty save@first@penalty
elax % put it back
fi
ifnumoutputpenalty &<-@Mii addvspaceintextsep vskipparskip else addvspaceintextsep fi}% { ypeout{*** SUCCESS ***}}{ ypeout{*** FAIL ***}} patchcmd{@addtocurcol}% {vskipintextsep ifnumoutputpenalty &<-@Mii vskip -parskipfi}% {ifnumoutputpenalty &<-@Mii aftergroupvskipaftergroupintextsep aftergroup ointerlineskip else vskipintextsep fi}% { ypeout{*** SUCCESS ***}}{ ypeout{*** FAIL ***}} patchcmd{@getpen}{@M}{@Mi} { ypeout{*** SUCCESS ***}}{ ypeout{*** FAIL ***}} makeatother egin{document} oindent ule{linewidth}{1pt} egin{figure}[htbp] centering includegraphics[w=.5linewidth]{example-image.pdf} caption{example-image} end{figure} oindent ule{linewidth}{1pt} end{document}

[1]: spacing - intextsep gives doubled space


下面說一下 @劉海洋 大神和 @李清 大神的建議和結果

1、首先, @劉海洋 大神說的利用lineskip和linelimit來代替aselineskip調整行距,很好的啟發,但是效果卻不是很理想,並帶來了一些其他問題:

具體為:

1、lineskip好像對浮動體沒有什麼用

2、當字體行距發生改變時,lineskip重新賦值後對上下文的間隙會產生影響。

上圖:

documentclass[a4paper,openany,UTF8,10pt,
scheme=plain,
]{ctexart}

usepackage{graphicx}

makeatletter

enewcommand
ormalsize{%
@setfontsize
ormalsize{10pti}{10pt} % 改變字型大小和行距
abovedisplayskip=12pt plus 2pt minus 2pt
abovedisplayshortskip=0pt plus 2pt minus 2pt
elowdisplayskip=abovedisplayskip
elowdisplayshortskip=abovedisplayshortskip
lineskiplimit=1000pt
% 使得aselineskip失效 lineskip=10pt % 字距=10pt+10pt=20pt
}
makeatother

ctexset{%
section={
format={heitifontsize{20pt}{20pt}selectfont lineskip=0pt},% 標題字型大小
beforeskip=0pt, % 段前0pt
afterskip =0pt, % 段後0pt
},
}

setlengthintextsep{0pt} % 浮動體距離上下文0pt
setlengthparindent{0pt}

egin{document}

燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙

ule{0.5linewidth}{1pt}

%
ointerlineskip
section{屯屯屯屯屯屯}

燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙

ule{0.5linewidth}{1pt}

egin{figure}[htbp]
centering
includegraphics[w=.4linewidth]{example-image.pdf}
caption{example-image}
end{figure}

%
ointerlineskip

ule{0.5linewidth}{1pt}
燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙
fontsize{15pt}{15pt}selectfont lineskip=0pt 燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙

ule{0.5linewidth}{1pt}

end{document}

所以 @劉海洋 大神提供的解決思路目前貌似不能很好的解決我的問題(也可能是我理解得不夠好,沒能找到好的其他變數來調整)。

2、下面是 @李清 大神的方法。

先說結果: @李清 大數的方法基本上的比較完美的解決了我的問題。

說是完美,是因為只需要在序言部分添加命令宏觀調控就好了,而且這個命令比較普適,大家可以直接拿來用,完全不用修改的,特別適合小白使用,非常方便。

說是比較完美,是因為那個命令只針對浮動體,對於標題,還需要在標題前後添加
ointerlineskip來解決,不過還好,標題不會像浮動體一樣到處跳,可以直接用一個宏來實現,也比較方便。

直接上圖,代碼稍後附上:

documentclass[a4paper,openany,UTF8,10pt,
scheme=plain,
]{ctexart}

usepackage{graphicx}

usepackage{etoolbox}
makeatletter
%% http://tex.stackexchange.com/a/40363
patchcmd{@addtocurcol}%
{vskip intextsep}%
{edefsave@first@penalty{ helastpenalty}unpenalty
ifnum lastpenalty = @M % hopefully the OR penalty
unpenalty
else
penalty save@first@penalty
elax % put it back
fi
ifnumoutputpenalty &<-@Mii addvspaceintextsep vskipparskip else addvspaceintextsep fi}% { ypeout{*** SUCCESS ***}}{ ypeout{*** FAIL ***}} patchcmd{@addtocurcol}% {vskipintextsep ifnumoutputpenalty &<-@Mii vskip -parskipfi}% {ifnumoutputpenalty &<-@Mii aftergroupvskipaftergroupintextsep aftergroup ointerlineskip else vskipintextsep fi}% { ypeout{*** SUCCESS ***}}{ ypeout{*** FAIL ***}} patchcmd{@getpen}{@M}{@Mi} { ypeout{*** SUCCESS ***}}{ ypeout{*** FAIL ***}} makeatother makeatletter enewcommand ormalsize{% @setfontsize ormalsize{10pt}{20pt} % 改變字型大小行距 abovedisplayskip=12pt plus 2pt minus 2pt abovedisplayshortskip=0pt plus 2pt minus 2pt elowdisplayskip=abovedisplayskip elowdisplayshortskip=abovedisplayshortskip } makeatother ctexset{% section={ format={heitifontsize{20pt}{20pt}selectfont}, % 標題字型大小 beforeskip=5pt, % 段前 afterskip =5pt, % 段後 }, } setlengthintextsep{5pt} % 浮動體距離上下文5pt setlengthparindent{0pt} egin{document} 燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙 ule{0.5linewidth}{1pt} ointerlineskip % 標題前後需要添加這個命令 section{屯屯屯屯屯屯} ointerlineskip % 標題前後需要添加這個命令 燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙 ule{0.5linewidth}{1pt} egin{figure}[htbp] centering includegraphics[w=.4linewidth]{example-image.pdf} caption{example-image} end{figure} % ointerlineskip ule{0.5linewidth}{1pt} 燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙 end{document}


推薦閱讀:

LaTeX 公式中的逗號可以改成全形么?
LaTeX把一個字元放在另一個上面, 但是字元寬度按照下面的字元來的效果怎麼做出來?
LaTeX小寫花體字母?
如何提高LaTeX的編譯速度?
TeX 是個什麼樣的排版軟體?使用它的最好方法是什麼?

TAG:字體 | LaTeX | LaTeX排版與設計 |