侧边距和精确左/右对齐

侧边距和精确左/右对齐

正如有人建议的那样,我将重新措辞我之前的问题,这个问题并没有被关在棺材里。

正如@MartinScharrer 正确指出的那样,我问的是如何在换行后在边缘处光学对齐文本,更具体地说,当您事先不知道内容时。

模板中就是这种情况,其中的文本由用户提供。

由于 TeX 使用方框进行编写,因此侧边距始终存在,但在标题页或海报中使用大尺寸字体时,侧边距会变得更加明显。

使用 xelatex,我解决了单行句子的问题,但无法解决多行段落的问题。(同样,事先不知道文本。)

完美对齐,单句,事先未知的文字。

完美对齐,单句,事先未知的文本。

多行标题中的可变右侧间隙。 多行标题中的可变右间隙

我想要的方式(手工完成,已知文本)

按照我想要的方式(手工完成,已知文本)

    \documentclass{article}

    \RequirePackage{xcolor}
    \RequirePackage{xstring}

    %% scrapping sidebearing both L & R

    \newcommand\shaveLR[1]{% 
        \if\relax\detokenize{#1}\relax\else% check  empty
        \StrLeft{#1}{1}[\tempi]%    the first char
        \StrRight{#1}{1}[\tempii]%  the last char
        \kern-\XeTeXglyphbounds1 \the\XeTeXcharglyph\expandafter`\tempi% first char L un-kernig
        #1%  input string
        \kern-\XeTeXglyphbounds3 \the\XeTeXcharglyph\expandafter`\tempii% last char R un-kernig
        \fi}

        \newcommand{\hairlineiv}[1][green]{% 
        \leavevmode%
        \kern-0.1pt %
        \smash{\color{#1}\vrule height 4\baselineskip depth 5pt width 0.1pt}%
        \kern-0.1pt}

        \newcommand{\hairlinei}[1][red]{% 
        \leavevmode\kern-0.1pt %
        \smash{\color{#1}\vrule height 35pt depth 15pt width 0.1pt}%
        \kern-0.1pt}

    \newcommand{\byauthor}{}
    \newcommand{\longtitles}{}

    \begin{document}  
    \pagestyle{empty}   

    \renewcommand{\byauthor}{Your Name} % put your name here
    \renewcommand{\longtitles}{Long titles must be exactly align with the vertical green bar.}% the main title

    %%%% examples
    \newcommand{\thislongtitleR}{%
    \shaveLR{Long titles must be}\\%
    \shaveLR{exactly align with}\\%
    \shaveLR{the vertical green}\\%
    \shaveLR{bar.}}


    \Large \flushright
    Note the gap between\\ the red line and the 'e'.

    \vspace{\baselineskip}
    {\sffamily\fontsize{60}{60}\selectfont
     by \byauthor\hairlinei}
    \vspace{\baselineskip}

    No gap here after\\ zeroing the kern.

    \vspace{1\baselineskip}
    {\sffamily\fontsize{60}{60}\selectfont
        by \shaveLR{\byauthor}\hairlinei}
    \vspace{2\baselineskip}


    \newpage
    \Large \flushright The way it is:
    \vspace{1\baselineskip}
    \begin{minipage}{1.3\textwidth}
    \raggedleft\sffamily\fontsize{50}{60}\selectfont\bfseries \longtitles\hairlineiv\par
    \end{minipage}

    \vspace{2\baselineskip}
    \Large \flushright The way it should be:
    \vspace{1\baselineskip}

    \begin{minipage}{1.3\textwidth}
        \raggedleft\sffamily\fontsize{50}{60}\selectfont\bfseries \thislongtitleR\hairlineiv
    \end{minipage}

    \end{document}

答案1

LuaTeX 解决方案:

在 LuaTeX 中,您可以使用post_linebreak_filter截取折线并添加一些偏移量。可以从 luaotfload 保存的 rawdata 中提取侧边距。添加偏移量后,必须重新打包水平盒以确定新的粘合设置。

要将其应用于文档中的每个垂直框,请在序言中添加

\usepackage{luacode}
\begin{luacode*}
  local function drop_sidebearing(head, groupcode)
    for n in node.traverse_id(node.id'hlist', head) do
      local char = node.has_glyph(n.head)
      if char then
        local f = font.getfont(char.font)
        if f.shared then
          local off = f.shared.rawdata.descriptions[char.char].boundingbox[1]*f.size/1000
          char.xadvance = char.xadvance - off
          char.xoffset = char.xoffset - off
        end
      end
      for ch in node.traverse_id(node.id'glyph', n.head) do
        char = ch
      end
      if char then
        local f = font.getfont(char.font)
        if f.shared then
          local desc = f.shared.rawdata.descriptions[char.char]
          char.xadvance = char.xadvance - (desc.width-desc.boundingbox[3])*f.size/1000
        end
      end
      local new_list = node.hpack(n.head, n.width, 'exactly')
      new_list.head = nil
      n.glue_order = new_list.glue_order 
      n.glue_set = new_list.glue_set
      n.glue_sign = new_list.glue_sign 
      node.free(new_list)
    end
    return true
  end
  luatexbase.add_to_callback('post_linebreak_filter', drop_sidebearing, 'Drop sidebearings after linebreaking')
\end{luacode*}

编辑:将相同的代码集成到原始示例中,并添加参数。仅当不在段落末尾时,\dropsidebearings代码才会产生效果。\dropsidebearings0

\documentclass{article}

\RequirePackage{xcolor}
\RequirePackage{xstring}

\usepackage{luacode}
\newcount\dropsidebearings
\begin{luacode*}
  local function drop_sidebearing(head, groupcode)
    if tex.count['dropsidebearings'] == 0 then
      return true
    end
    for n in node.traverse_id(node.id'hlist', head) do
      local char = node.has_glyph(n.head)
      if char then
        local f = font.getfont(char.font)
        if f.shared then
          local off = f.shared.rawdata.descriptions[char.char].boundingbox[1]*f.size/1000
          char.xadvance = char.xadvance - off
          char.xoffset = char.xoffset - off
        end
      end
      for ch in node.traverse_id(node.id'glyph', n.head) do
        char = ch
      end
      if char then
        local f = font.getfont(char.font)
        if f.shared then
          local desc = f.shared.rawdata.descriptions[char.char]
          char.xadvance = char.xadvance - (desc.width-desc.boundingbox[3])*f.size/1000
        end
      end
      local new_list = node.hpack(n.head, n.width, 'exactly')
      new_list.head = nil
      n.glue_order = new_list.glue_order 
      n.glue_set = new_list.glue_set
      n.glue_sign = new_list.glue_sign 
      node.free(new_list)
    end
    return true
  end
  luatexbase.add_to_callback('post_linebreak_filter', drop_sidebearing, 'Drop sidebearings after linebreaking')
\end{luacode*}

\newcommand{\hairlineiv}[1][green]{% 
  \leavevmode%
  \kern-0.1pt %
  \smash{\color{#1}\vrule height 4\baselineskip depth 5pt width 0.1pt}%
  \kern-0.1pt
}

\newcommand{\hairlinei}[1][red]{% 
  \leavevmode\kern-0.1pt %
  \smash{\color{#1}\vrule height 35pt depth 15pt width 0.1pt}%
  \kern-0.1pt
}

\begin{document}  
\pagestyle{empty}   

\newcommand{\byauthor}{Your Name} % put your name here
\newcommand{\longtitles}{Long titles must be exactly align with the vertical green bar.}% the main title

\Large \flushright
Note the gap between\\ the red line and the 'e'.
\protrudechars=1

\vspace{\baselineskip}
{\sffamily\fontsize{60}{60}\selectfont
 by \byauthor\hairlinei}
\vspace{\baselineskip}

No gap here after\\ zeroing the kern.

\vspace{1\baselineskip}
{\sffamily\fontsize{60}{60}\selectfont
    \dropsidebearings=1
    by \byauthor\hairlinei\par}
\vspace{2\baselineskip}


\newpage
\Large \flushright The way it is:
\vspace{1\baselineskip}
\begin{minipage}{1.3\textwidth}
  \raggedleft\sffamily\fontsize{50}{60}\selectfont\bfseries \longtitles\hairlineiv\par
\end{minipage}

\vspace{2\baselineskip}
\Large \flushright The way it should be:
\vspace{1\baselineskip}

\begin{minipage}{1.3\textwidth}
  \dropsidebearings=1
  \raggedleft\sffamily\fontsize{50}{60}\selectfont\bfseries \longtitles\hairlineiv
\end{minipage}

\end{document}

相关内容