计算文本和字母的精确宽度

计算文本和字母的精确宽度

从技术上来说,这个问题可以分为两个小问题。

我正在使用lettrine和一些诗歌文本,但确定文本缩进量的计算并不总是正常工作。

我曾尝试将的设置\titlespacing为,但结果并未如预期。\sectionrunin

下面是代码示例,我尽可能地简化了代码以显示失败之处并提供一个可行的示例:

\documentclass[paper=a5,pagesize=pdftex]{scrbook}
\usepackage[top=2cm,bottom=1.5cm, left=1.5cm, right=1.5cm]{geometry}
\usepackage[pagestyles]{titlesec}
\usepackage{lettrine}
\usepackage{xltxtra}
\usepackage{etoolbox}
\usepackage{setspace}

\renewcommand{\thesection}{\arabic{section}}
\renewcommand{\thesubsection}{\arabic{subsection}}

\setmainfont{Cardo}

\newcounter{bingo}
\newlength\howwide

\newcommand\defhowwide{
    \setcounter{bingo}{\value{section}}
    %To sync the width with the next section to display
    \addtocounter{bingo}{1}
    \settowidth{\howwide}{\Huge{\thebingo}}
    }

% sections and subsections formatting
\titleformat{\section}{}{\lettrine{\thesection}}{0pt}{}[\vskip-1\baselineskip]
\titleformat{\subsection}[runin]{\small\bfseries}{\thesubsection}{1em}{}
\titlespacing{\section}{\howwide}{-1pt}{0pt}
\titlespacing{\subsection}{0pt}{0pt}{1em}

\setlength{\parindent}{0pt}

\newlength\NumLen
\newlength\LinLen
% indents one line of text. Indentation= width of section number + 1em
\newcommand\IndOne{%
  \setlength\NumLen{\howwide}
  \addtolength\NumLen{0.5em}
  \setlength\LinLen{\dimexpr\textwidth-\NumLen}%\the\NumLen\the\LinLen
  \parshape 2 \NumLen \LinLen 0pt \textwidth}
% indents two lines of text. Indentation= width of section number + 1em
\newcommand\IndTwo{%
  \setlength\NumLen{\howwide}
  \addtolength\NumLen{0.5em}
  \setlength\LinLen{\dimexpr\textwidth-\NumLen}%\the\NumLen\the\LinLen
  \parshape 3 \NumLen \LinLen \NumLen \LinLen 0pt \textwidth}

\usepackage{layouts}

\usepackage[none]{hyphenat}
\sloppy

\begin{document}
\newlength{\myIndent}

\setcounter{section}{4}
\defhowwide
\section{}
\settowidth{\myIndent}
{\IndOne Kom nou, julle rykes, ween en huil oor die ellendes wat oor julle kom.}
\ifdimless{\myIndent}
{\textwidth-\howwide}
{\IndOne Kom nou, julle rykes, ween en huil oor die ellendes wat oor julle kom. \stepcounter{subsection}
\subsection{} \IndOne Julle rykdom is bedorwe, en julle klere is deur die motte verniel.}
{\IndTwo Kom nou, julle rykes, ween en huil oor die ellendes wat oor julle kom. \stepcounter{subsection} \subsection{} Julle rykdom is bedorwe, en julle klere is deur die motte verniel.}
\printinunitsof{pt}
\prntlen{\myIndent} myIndent\\
\prntlen{\textwidth} textwidth\\
\prntlen{\linewidth} linewidth\\
\prntlen{\howwide} howwide\\
\prntlen{\LinLen} LinLen\\
\prntlen{\NumLen} NumLen
\subsection{} Julle goud en silwer is verroes, en hulle roes sal tot 'n getuienis teen julle wees en sal soos 'n vuur julle vlees verteer. Julle het skatte vergader in die laaste dae.

\setcounter{section}{9}
\defhowwide
\section{}
\settowidth{\myIndent}
{\IndOne Kom nou, julle rykes, ween en huil oor die ellendes wat oor julle kom.}
\ifdimless{\myIndent}
{\textwidth-\howwide}
{\IndOne Kom nou, julle rykes, ween en huil oor die ellendes wat oor julle kom. \stepcounter{subsection}
\subsection{} \IndOne Julle rykdom is bedorwe, en julle klere is deur die motte verniel.}
{\IndTwo Kom nou, julle rykes, ween en huil oor die ellendes wat oor julle kom. \stepcounter{subsection} \subsection{} Julle rykdom is bedorwe, en julle klere is deur die motte verniel.}
\printinunitsof{pt}
\prntlen{\myIndent} myIndent\\
\prntlen{\textwidth} textwidth\\
\prntlen{\linewidth} linewidth\\
\prntlen{\howwide} howwide\\
\prntlen{\LinLen} LinLen\\
\prntlen{\NumLen} NumLen
\subsection{} Julle goud en silwer is verroes, en hulle roes sal tot 'n getuienis teen julle wees en sal soos 'n vuur julle vlees verteer. Julle het skatte vergader in die laaste dae.
\end{document}

总体而言,代码运行良好,但在某些情况下仍然会出现文本重叠的情况,如本屏幕截图所示。

显示问题

我想如果我能找到确切的宽度,lettrine我就能\ifdimless{\myIndent}{\textwidth-\howwide}...更准确地进行计算。


正如下面评论中提到的。使用 XeLaTeX 和 Cardo 字体进行编译可获得相同的结果。

答案1

我知道已经很晚了,但是我看到这个问题与您的另一个问题相关。

我认为这lettrine不是解决你的问题的正确方法。这里有另一种解决方法。

\documentclass[paper=a5,pagesize=pdftex]{scrbook}
\usepackage[top=2cm,bottom=1.5cm, left=1.5cm, right=1.5cm]{geometry}
\usepackage[pagestyles]{titlesec}
\usepackage{fontspec}
\usepackage{etoolbox}

\setmainfont{Cardo}

\newcommand{\Sectionnumber}{%
  \sbox\Sectionbox{\smash{\raisebox{-\baselineskip}{%
    \fontsize{2.2\baselineskip}{0}\selectfont\theSection}}\enspace}}

\newcounter{Section}
\newcounter{Subsection}[Section]
\newlength{\Sectionwidth}
\newif\ifFirstSubsection
\newsavebox{\Sectionbox}

\makeatletter
\newcommand{\Section}{\par\vskip\z@ \@plus 2\p@
  \FirstSubsectiontrue\clubpenalty\@M
  \refstepcounter{Section}\stepcounter{Subsection}%
  \Sectionnumber\setlength{\Sectionwidth}{\wd\Sectionbox}%
  \hangindent\Sectionwidth\hangafter-2
  \leavevmode\llap{\box\Sectionbox}\ignorespaces}
\newcommand{\Subsection}{%
  \par\clubpenalty\@clubpenalty
  \ifFirstSubsection
    \ifnum\prevgraf=\@ne\nobreak\hspace*{\Sectionwidth}\fi
    \FirstSubsectionfalse
  \fi
  \refstepcounter{Subsection}\textbf{\theSubsection}\enspace\ignorespaces}
\makeatother

\parindent=0pt
\parskip=0pt


\begin{document}

\setcounter{Section}{8}

\Section Kom nou, julle rykes, ween en huil oor die ellendes wat oor julle kom.

\Subsection Julle rykdom is bedorwe, en julle klere is deur die motte verniel.

\Subsection Julle goud en silwer is verroes, en hulle roes sal tot 'n getuienis 
teen julle wees en sal soos 'n vuur julle vlees verteer. Julle het skatte vergader
in die laaste dae.

\Section Kom nou, julle rykes, ween en huil oor die ellendes wat oor julle kom.

\Subsection Julle rykdom is bedorwe, en julle klere is deur die motte verniel.

\Subsection Julle goud en silwer is verroes, en hulle roes sal tot 'n getuienis 
teen julle wees en sal soos 'n vuur julle vlees verteer. Julle het skatte vergader
in die laaste dae.

\end{document}

诀窍是\Section使用内部计数器计算段落的行数\prevgraf的行数。如果我们处于一个章节之后的第一个小节中该部分段落只有一行长,然后插入缩进以获得正确的间距。

在此处输入图片描述

答案2

这是一个简单的宏,类似于lettrine包的功能。LaTeX 源其 PDF 输出。这主要针对 RTL(在本例中为波斯语)。请注意,宏编程是用波斯语完成的,因为 xepersian 提供了波斯语宏编程工具,因此如果您需要等效的英语命令,请查看xepersian文档。

还要注意,lettrine包完全受bidi包支持,但picins不受bidi包支持,您在排版 RTL 文本时可能会遇到一些问题(为什么不支持?因为 picins 是用 LaTeX2.09 编写的,不是一个免费包,更重要的是不包含在 TeXLive 中)。

答案3

认为这与其说是对你问题的回答,不如说是建议。帖子末尾添加了你遇到的问题的一些参考。看起来你正在尝试排版詹姆斯书中的一些章节和诗句 -南非荷兰语 Bybel:Jakobus. 可以理解lettrine看起来是个不错的选择。但是,正如您已经注意到的,它不喜欢短段落(如果您将诗句排版为分段项目或段落,这种情况很常见)。这是一个相当简单的替代方案,使用picins包裹

picins提供

\parpic(<width>,<height>)(<x-offset>,<y-offset>)[<options>][<position>]{<stuff>}

<stuff>以类似的方式排版wrapfig确实如此。我只是有时觉得它更容易使用。<option>允许一些基本的边框/阴影命令,并<position>指定放置段落图片的位置(左l或右rpicins。偏移参数提供了额外的移动。因此,您无需摆弄lettrinetitlesec定义,上面提供了一个干净的界面和非常易读的代码。嗯,这主要归功于一些宏的编写......

由于我没有 Cardo 字体并且已经剥离了你的 MWE,因此以下内容不需要xelatex

\documentclass{article}
\usepackage[paper=a5paper,margin=15mm]{geometry}% http://ctan.org/pkg/geometry
\usepackage{picins}% http://ctan.org/pkg/picins
\usepackage{needspace}% http://ctan.org/pkg/needspace

\newcounter{bchapter} \renewcommand{\thebchapter}{\Huge\arabic{bchapter}}% Chapter
\newcounter{bverse}[bchapter] \renewcommand{\thebverse}{\textbf{\arabic{bverse}}}% Verse
\newcommand{\bchapter}{%
  \refstepcounter{bchapter}% Increment counter and allow referencing (\stepcounter would also work)
  \setcounter{bverse}{1}% First verse doesn't need to typeset '1'
  \setbox0=\hbox{\Huge\thebchapter}% Store \Huge chapter number in box0
  \needspace{\ht0}% Need at least the height of box0
  \pichskip{5pt}\noindent\parpic(\wd0,\ht0)(0pt,20pt)[][r]{\usebox0}% Insert \Huge chapter number
}%
\newcommand{\bverse}{%
  \par\refstepcounter{bverse}% Increment counter and allow referencing (\stepcounter would also work)
  \thebverse~\ignorespaces%
}

% Remove paragraph indentation & skip
\setlength{\parindent}{0pt} \setlength{\parskip}{0pt}

\begin{document}

\bchapter Kom nou, julle rykes, ween en huil oor die ellendes wat oor julle kom. 
\bverse Julle rykdom is bedorwe, en julle klere is deur die motte verniel. 
\bverse Julle goud en silwer is verroes, en hulle roes sal tot 'n getuienis teen julle wees en sal soos ‘n vuur julle vlees verteer. Julle het skatte vergader in die laaste dae. 
\bverse Kyk, die loon van die arbeiders wat julle lande afgeoes het, wat deur julle agtergehou is, roep uit; en die geroep van die maaiers het gekom tot in die ore van die Here van die leërskare. 
\bverse Julle het op die aarde 'n weelderige en losbandige lewe gelei; julle het jul harte vet gevoer soos op ‘n slagdag. 
\bverse Veroordeel, vermoor het julle die regverdige; hy versit hom nie teen julle nie. 
\bverse Wees dan geduldig, broeders, tot op die wederkoms van die Here. Kyk, die landbouer wag op die kostelike vrug van die aarde en het geduld daarmee totdat dit die vroe\"e en die laat re\"en ontvang het. 
\bverse Julle moet ook geduldig wees; versterk julle harte, want die wederkoms van die Here is naby. 
\bverse Moenie teen mekaar sug nie, broeders, sodat julle nie veroordeel word nie. Kyk, die Regter staan voor die deur. 
\bverse Neem as voorbeeld van lyding, my broeders, en van geduld die profete wat in die Naam van die Here gespreek het. 
\bverse Kyk, ons reken hulle geluksalig wat verdra. Julle het gehoor van die lydsaamheid van Job, en julle het die einddoel van die Here met hom gesien, dat die Here vol medelye en ontferming is. 
\bverse Maar bo alles, my broeders, moenie sweer nie: nie by die hemel nie, ook nie by die aarde nie en ook geen ander eed nie; maar laat julle ja ja wees en julle nee nee, sodat julle nie onder ‘n oordeel val nie. 
\bverse Is daar iemand onder julle wat ly? Laat hom bid. Is iemand opgeruimd? Laat hom psalmsing. 
\bverse Is daar iemand siek onder julle? Laat hom die ouderlinge van die gemeente inroep, en laat hulle oor hom bid nadat hulle hom in die Naam van die Here met olie gesalf het. 
\bverse En die gebed van die geloof sal die kranke red, en die Here sal hom oprig. Selfs as hy sonde gedoen het, sal dit hom vergewe word. 
\bverse Bely mekaar julle misdade en bid vir mekaar, sodat julle gesond kan word. Die vurige gebed van ‘n regverdige het groot krag. 
\bverse Elía was ‘n mens net soos ons, en hy het ernstig gebid dat dit nie moes re\"en nie, en dit het op die aarde drie jaar en ses maande lank nie gere\"en nie; 
\bverse en hy het weer gebid, en die hemel het re\"en gegee en die aarde het sy vrug laat uitspruit. 
\bverse Broeders, as een onder julle van die waarheid afgedwaal het en iemand hom bekeer, 
\bverse laat hy weet dat die een wat ‘n sondaar van sy dwaalweg bekeer, 'n siel uit die dood sal red en 'n menigte sondes sal bedek.

\setcounter{bchapter}{9}%

\bchapter Kom nou, julle rykes, ween en huil oor die ellendes wat oor julle kom. 
\bverse Julle rykdom is bedorwe, en julle klere is deur die motte verniel. 
\bverse Julle goud en silwer is verroes, en hulle roes sal tot 'n getuienis teen julle wees en sal soos 'n vuur julle vlees verteer. Julle het skatte vergader in die laaste dae. 
\bverse Kyk, die loon van die arbeiders wat julle lande afgeoes het, wat deur julle agtergehou is, roep uit; en die geroep van die maaiers het gekom tot in die ore van die Here van die le\"erskare. 
\bverse Julle het op die aarde 'n weelderige en losbandige lewe gelei; julle het jul harte vet gevoer soos op 'n slagdag. 
\bverse Veroordeel, vermoor het julle die regverdige; hy versit hom nie teen julle nie. 
\bverse Wees dan geduldig, broeders, tot op die wederkoms van die Here. Kyk, die landbouer wag op die kostelike vrug van die aarde en het geduld daarmee totdat dit die vroe\"e en die laat re\"en ontvang het. 
\bverse Julle moet ook geduldig wees; versterk julle harte, want die wederkoms van die Here is naby. 
\bverse Moenie teen mekaar sug nie, broeders, sodat julle nie veroordeel word nie. Kyk, die Regter staan voor die deur. 
\bverse Neem as voorbeeld van lyding, my broeders, en van geduld die profete wat in die Naam van die Here gespreek het. 
\bverse Kyk, ons reken hulle geluksalig wat verdra. Julle het gehoor van die lydsaamheid van Job, en julle het die einddoel van die Here met hom gesien, dat die Here vol medelye en ontferming is. 
\bverse Maar bo alles, my broeders, moenie sweer nie: nie by die hemel nie, ook nie by die aarde nie en ook geen ander eed nie; maar laat julle ja ja wees en julle nee nee, sodat julle nie onder 'n oordeel val nie. 
\bverse Is daar iemand onder julle wat ly? Laat hom bid. Is iemand opgeruimd? Laat hom psalmsing. 
\bverse Is daar iemand siek onder julle? Laat hom die ouderlinge van die gemeente inroep, en laat hulle oor hom bid nadat hulle hom in die Naam van die Here met olie gesalf het. 
\bverse En die gebed van die geloof sal die kranke red, en die Here sal hom oprig. Selfs as hy sonde gedoen het, sal dit hom vergewe word. 
\bverse Bely mekaar julle misdade en bid vir mekaar, sodat julle gesond kan word. Die vurige gebed van 'n regverdige het groot krag. 
\bverse El\'\i a was 'n mens net soos ons, en hy het ernstig gebid dat dit nie moes re\"en nie, en dit het op die aarde drie jaar en ses maande lank nie gere\"en nie; 
\bverse en hy het weer gebid, en die hemel het re\"en gegee en die aarde het sy vrug laat uitspruit. 
\bverse Broeders, as een onder julle van die waarheid afgedwaal het en iemand hom bekeer, 
\bverse laat hy weet dat die een wat 'n sondaar van sy dwaalweg bekeer, 'n siel uit die dood sal red en 'n menigte sondes sal bedek.

\end{document}

在此处输入图片描述

你会注意到,我还使用了needspace包裹。这是因为您不希望出现章节号(计数器bchapter)在页面上只剩下 1 行而实际上需要 2 行的情况。如果页面上剩余的空间不足,\needspace{<len>}则发出。\break<len>


具体到您的 MWE,您主要关心的是长度的设置。引用calc包裹 文档

\setcounter命令\addtocounter具有全局效果,而\setlength\addtolength命令遵循正常的作用域规则。

因此,当你使用\setlength\NumLen{\howwide} 之内宏(例如\IndOne),更改仅在该宏内有效,一旦宏终止,更改将恢复为原始设置。如果您希望效果是全局的,则需要将其存储在框或另一个宏中,以便可以在设置的范围之外使用它。

这对南非荷兰语来说太好听了,谢谢!

答案4

进一步回答 egreg 的问题......

我对他的代码的实现。标题标记现在失败了。对于此示例,标题标记应显示 1:1-2:5,但它只显示了我为目录指定的名称。

看起来应该有点像这样: 在此处输入图片描述

但现在看起来像这样: 在此处输入图片描述

\documentclass[pagesize=pdftex, fontsize=12]{scrbook}
\usepackage[paperwidth=15.6cm, paperheight=23.4cm, top=2cm,bottom=1cm, left=1cm, right=1cm]{geometry}
\usepackage[pagestyles]{titlesec}
\usepackage{lettrine}
\usepackage{xltxtra}
\usepackage{tocloft}
\usepackage{etoolbox}
\usepackage[toc]{multitoc}
\usepackage{setspace}
\usepackage{needspace}
\usepackage{calc}
\usepackage{fix2col} %fixes numbering of the sections in the header for two columns

\setlength{\hoffset}{0cm}

\usepackage[none]{hyphenat}
\sloppy
\usepackage{hyperref}
\hypersetup{
    bookmarksnumbered=true,
    bookmarksopen=true,
    bookmarksopenlevel=0,
    bookmarksdepth=1,
    unicode=true,
    colorlinks=true,
    citecolor={black},
    linkcolor={black},
    urlcolor={black},
    pdffitwindow=true,
    pdftitle={Santa Biblia},
    pdfauthor={}
}

\defaultfontfeatures{Mapping=tex-text}
\setmainfont{Times New Roman}

\usepackage{polyglossia} 
%   \setmainlanguage[numerals=hebrew]{hebrew}
    \setmainlanguage{spanish} 

\renewcommand{\thesection}{\arabic{section}}
\renewcommand{\thesubsection}{\arabic{subsection}}

\setcounter{tocdepth}{0}
\setcounter{secnumdepth}{2}

% definition of the page style with required headers
\newpagestyle{Biblestyle}{
  \setheadrule{.02pt}
  \sethead[\thepage][\chaptertitle][\firsttitlemarks\thesection:\ifthesubsection{\firsttitlemarks\thesubsection}{1}---\bottitlemarks\thesection:\bottitlemarks\thesubsection]{\firsttitlemarks\thesection:\ifthesubsection{\firsttitlemarks\thesubsection}{1}---\bottitlemarks\thesection:\bottitlemarks\thesubsection}{\chaptertitle}{\thepage}
}

% sets the marks to be used (section and subsection)
\setmarks{section}{subsection}

\linespread{0.85}

\addtokomafont{disposition}{\rmfamily\mdseries}

%\renewcommand{\contentsname}{TABLA DE LOS LIBROS DEL}
\newcommand{\newtocname}{\LARGE{TABLA DE LOS LIBROS DEL}}
\renewcommand*\cfttoctitlefont{\huge\hfill}
\renewcommand*\cftaftertoctitle{\hfill}
\renewcommand{\cftchapdotsep}{\cftdot}
\renewcommand{\cftpartfont}{\bfseries}
\renewcommand{\cftchapfont}{\mdseries}
\cftpagenumbersoff{part}
\renewcommand{\cftchappagefont}{\hfill\mdseries}
\setlength{\cftbeforetoctitleskip}{-4.7em}
\setlength{\cftaftertoctitleskip}{1pt}
\setlength{\cftbeforechapskip}{.1em}
\setlength{\cftbeforepartskip}{.1em}
\setlength{\columnsep}{3em}
\setlength\columnseprule{.4pt}

%\dottedcontents{chapter}[2.5em]{}{2.3em}{1pc}

\newcommand{\Sectionnumber}{%
  \sbox\Sectionbox{\smash{\raisebox{-\baselineskip}{%
    \fontsize{2.2\baselineskip}{0}\selectfont\theSection}}\enspace}}

\newcounter{Section}
\newcounter{Subsection}[Section]
\newlength{\Sectionwidth}
\newif\ifFirstSubsection
\newsavebox{\Sectionbox}

\makeatletter
\newcommand{\Section}{%
  \par\vskip\z@ \@plus 2\p@
  \FirstSubsectiontrue\clubpenalty\@M
  \refstepcounter{Section}\stepcounter{Subsection}%
  \Sectionnumber\setlength{\Sectionwidth}{\wd\Sectionbox}%
  \hangindent\Sectionwidth\hangafter-2
  \leavevmode\llap{\box\Sectionbox}\ignorespaces}
\newcommand{\Subsection}{%
  \par\clubpenalty\@clubpenalty
  \ifFirstSubsection
    \ifnum\prevgraf=\@ne\nobreak\hspace*{\Sectionwidth}\fi
    \FirstSubsectionfalse
  \fi
  \refstepcounter{Subsection}\textbf{\theSubsection}\enspace\ignorespaces}
\makeatother

\parindent=0pt
\parskip=0pt

\begin{document}
\frontmatter
\renewcommand{\contentsname}{\newtocname}
\pdfbookmark[0]{\contentsname}{tofcontents}
\tableofcontents

\mainmatter
\setlength\columnseprule{0pt}
\pagestyle{Biblestyle}
\newlength{\myIndent}
\Needspace*{15\baselineskip}

\twocolumn[\vspace{-0.5cm}\center{\textbf{\Huge{Génesis}}}\vspace{0.5cm}]
\phantomsection
\addcontentsline{toc}{chapter}{Génesis}%\noindent

\addtocounter{chapter}{1}
\renewcommand{\chaptertitle}{Génesis}
\setcounter{section}{0}
\Needspace*{3\baselineskip}

\Section EN el principio crió Dios los cielos y la tierra.
\Subsection Y la tierra estaba desordenada y vacía, y las tinieblas estaban sobre la haz del abismo, y el Espíritu de Dios se movía sobre la haz de las aguas.
\Subsection Y dijo Dios: Sea la luz: y fué la luz.
\Subsection Y vió Dios que la luz era buena: y apartó Dios la luz de las tinieblas.
\Needspace*{3\baselineskip}

\Section Y FUERON acabados los cielos y la tierra, y todo su ornamento.
\Subsection Y acabó Dios en el día séptimo su obra que hizo, y reposó el día séptimo de toda su obra que había hecho.
\Subsection Y bendijo Dios al día séptimo, y santificólo, porque en él reposó de toda su obra que había Dios criado y hecho.
\Subsection Estos son los orígenes de los cielos y de la tierra cuando fueron criados, el día que Jehová Dios hizo la tierra y los cielos,
\Subsection Y toda planta del campo antes que fuese en la tierra, y toda hierba del campo antes que naciese: porque aun no había Jehová Dios hecho llover sobre la tierra, ni había hombre para que labrase la tierra;
\end{document}

相关内容