格式化 pgp - 每四个插入一个空格

格式化 pgp - 每四个插入一个空格

我偶尔会使用 Latex(这意味着我从来没有用它写过大篇幅的专业文章,但写过一些个人使用的文章),并且想创建一些名片,基本而简单,不做作但也不会太丑。

在这里,我想格式化我的 pgp 密钥指纹。通常 pgp 密钥每四位数字有一个空格,以使其更易读。

因此它转换如下:

47D6459B2DCEE5C1439C53330403A28B2D8DE8FB

变成这样:

47D6 459B 2DCE E5C1 439C 5333 0403 A28B 2D8D E8FB

那么如何在每组之间插入空格?

其次,如果我可以在中间创建一个新行,也就是在第 5 个空格处,那就太好了。我该怎么做?

47D6 459B 2DCE E5C1 439C
5333 0403 A28B 2D8D E8FB

我将用这个创建一个宏。谢谢帮助!

答案1

一个不检查字符串长度的简单解决方案:

\documentclass{article}

\makeatletter
\newcommand{\printpgp}[1]{\print@pgp#1\@nil}

\def\print@pgp#1#2#3#4#5\@nil{%
  #1#2#3#4%
  \ifx\\#5\\%
    \expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi
  {~\print@pgp#5\@nil}%
}
\makeatother

\begin{document}
$|$\printpgp{47D6459B2DCEE5C1439C53330403A28B2D8DE8FB}$|$
\end{document}

我在侧面添加了两个条,只是为了显示没有添加多余的空间。

在此处输入图片描述

如果要以等宽字体打印指纹,只需将第一个定义更改为

\newcommand{\printpgp}[1]{\texttt{\print@pgp#1\@nil}}

在此处输入图片描述

更多功能。如果长度错误,则打印“INVALID PGP”。字符串中的空格将被忽略。您可以指定一个键值接口:break默认情况下为 true,但break=false键会打印在一行上。font您可以指定字体选择(默认\ttfamily)。

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\printpgp}{O{}m}
 {
  \par\noindent
  \group_begin:
  \keys_set:nn { xxiidecembre/printpgp } { #1 }
  \xxiidecembre_printpgp:n { #2 }
  \par
  \group_end:
 }

\keys_define:nn { xxiidecembre/printpgp }
 {
  font .tl_set:N = \l_xxiidecembre_pgpfont_tl,
  font .initial:n = \ttfamily,
  break .bool_set:N = \l_xxiidecembre_pgpbreak_bool,
  break .initial:n = true,
 }

\tl_new:N \l__xiidecembre_pgp_tl
\int_new:N \l__xxiidecembre_step_int
\int_new:N \l__xxiidecembre_group_int
\cs_new_protected:Npn \xxiidecembre_printpgp:n #1
 {
  \tl_use:N \l_xxiidecembre_pgpfont_tl
  \tl_set:Nn \l__xiidecembre_pgp_tl { #1 }
  \tl_replace_all:Nnn \l__xiidecembre_pgp_tl { ~ } { }
  \int_compare:nTF { \tl_count:N \l__xiidecembre_pgp_tl = 40 }
   {
    \__xxiidecembre_printpgp:V \l__xiidecembre_pgp_tl
   }
   {
    INVALID~PGP
   }
 }

\cs_new_protected:Npn \__xxiidecembre_printpgp:n #1
 {
  \tl_map_inline:nn { #1 }
   {
    ##1
    \int_incr:N \l__xxiidecembre_step_int
    \int_compare:nT { \l__xxiidecembre_step_int = 4 }
     {
      \int_incr:N \l__xxiidecembre_group_int
      \int_compare:nTF { \l__xxiidecembre_group_int = 5 }
       {
        \bool_if:NTF \l_xxiidecembre_pgpbreak_bool { \\ } { ~ }
       }
       {
        \c_space_tl
       }
      \int_zero:N \l__xxiidecembre_step_int
     }
   }
 }
\cs_generate_variant:Nn \__xxiidecembre_printpgp:n { V }
\ExplSyntaxOff

\begin{document}

\printpgp{47D6459B2DCEE5C1439C53330403A28B2D8DE8FB}

\medskip

\printpgp[break=false]{47D6459B2DCEE5C1439C53330403A28B2D8DE8FB}

\medskip

\printpgp[font=\ttfamily\LARGE]{47D6 459B 2DCE E5C1 439C 5333 0403 A28B 2D8D E8FB}

\medskip

\printpgp{0000 1111 2222}

\end{document}

在此处输入图片描述

首先删除空格,然后逐个字符地映射输入,每一步都增加一个计数器;如果计数器为 4,则组计数器将步进;发出一个空格,但\\如果组计数器为 5 且break=true有效,则使用空格。

答案2

这里的两个答案都使用了不太理想的参数操作方法,因为#5循环中的每个步骤都会重写参数(其余数字)。更好的解决方案是:

\newcount\tmpnum
\def\pgp#1{\tmpnum=0 \pgpA #1 {}...}
\def\pgpA#1#2#3#4{\ifx^#1^\unskip\else
   \ifnum\tmpnum=5\par\fi
   \advance\tmpnum by1
   #1#2#3#4
   \expandafter\pgpA\fi}

\pgp{47D6459B2DCEE5C1439C53330403A28B2D8DE8FB}

答案3

\documentclass{scrartcl}

\newcount\pgpcount
\long\def\firstofone#1{#1}
\long\def\gobbleone#1{}
\def\dopgp#1#2#3#4#5\relax
  {#1#2#3#4\if\relax\detokenize{#5}\relax
    \expandafter\gobbleone
   \else
    \expandafter\firstofone
   \fi
   {\advance\pgpcount by 1
    \ifnum\pgpcount=5
      \par\pgpcount=0
    \else\ \fi
    \dopgp#5\relax\unskip}}

\def\pgp#1{\dopgp#1\relax}

\begin{document}

\pgp{47D6459B2DCEE5C1439C53330403A28B2D8DE8FB}

\end{document}

egreg 打败了我,但我想这是我第一次玩“TeX 宏”,所以我就把它留在这里了。

答案4

我很惊讶还没有基于 luatex 的解决方案。这是 ConTeXt 中的一个解决方案,适用于平衡和非平衡输入。我定义了一个单独的突出显示来更改输出的样式(等宽字体等)。

\startluacode
  local C, Ct     = lpeg.C, lpeg.Ct
  local lpegmatch = lpeg.match
  local hexdigit  = lpeg.patterns.hexdigit 
  local concat    = table.concat

  userdata = userdata or {}

  userdata.splitPGP = function(str)
    local block    = C(hexdigit * hexdigit * hexdigit * hexdigit)
    local nonblock = C(hexdigit^0)
    local pattern  = Ct(block^0 * nonblock)
    local tbl      = lpegmatch(pattern, str)

    context.PGPstyle(concat(tbl, " "))

  end
\stopluacode

\definehighlight[PGPstyle][style=mono]

\define[1]\splitPGP{\ctxlua{userdata.splitPGP([==[#1]==])}}

\starttext
\startlines
\splitPGP{47D6459B2DCEE5C1439C53330403A28B2D8DE8FB}
\splitPGP{47D6459B2DCEE5C1439C53330403A28B2D8DE8}
\stoplines
\stoptext

在此处输入图片描述

相关内容