和\pgfmathtruncatemacro

和\pgfmathtruncatemacro

在此示例中,BIOS 字体从“@”到“G”的位表示有两种形式。第一种是用逗号分隔的 1 和 0 序列。第二种是塞进标记中的 1 和 0 的字符串。说实话,我想要一个从第二种形式生成 tikzpicture 的宏。这是我能做到的,我需要帮助来完成它。

以此为源运行“pdflatex BIOS.tex”对第一个表单执行正确,但无法输出第二个表单。代码实际上是错误的,但目标是拥有索引 (\xi,\yi) 和 \chr,以便在每个 \row 中为每个 \chr 放置一个实心圆。

请帮我完成这个。我不知道该尝试什么,而且没有搜索结果。

\documentclass[12pt]{article}

\usepackage{tikz}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% TODO make this work by enumerating each character with \xi
\makeatletter
\def\dowithchar#1#2{%
    \begingroup%
    \def\myspace{}% defined with local scope
    \@tfor\chr:=#1\do{%
        \myspace\ifx\chr{X} \fill (0.18*\xi,-0.18*#2) circle (0.08) \fi;%
        \let\myspace\space%
    }%
    \endgroup%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\makeatother

\listfiles
\begin{document}

\newcommand\ASCIIbits{
    {0,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,%
     0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0},%
    {1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,%
     0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,1,1},%
    {1,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,1,1,0,0,0,0,0},%
    {1,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0},%
    {1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,1,1,0,0,1,1,1},%
    {1,1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,%
     0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,1,1},%
    {0,1,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,%
     0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,1},%
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,%
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}%
}
\newcommand\ASCIIfont{
    OXXXXXOOOOOXXOOOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXXXXOOOOXXXXO,%
    XXOOOXXOOOXXXXOOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOXOOOXXOOXX,%
    XXOXXXXOOXXOOXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOOOO,%
    XXOXXXXOOXXOOXXOOOOXXXXXOOOXXOOOOOOOOXXOOXXOOOXXXXOOOOOXXXXOOOOXXOOOOO,%
    XXOXXXOOOXXXXXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOXXX,%
    XXOOOOOOOXXOOXXOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOOOOOXXOOXX,%
    OXXXXXOOOXXOOXXOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXOOOOOOOXXXOX,%
    OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO%
}

\begin{tikzpicture}
    \foreach\row [count=\yi] in \ASCIIbits{
        \foreach\chr [count=\xi] in \row {
            \ifodd\chr \fill (0.18*\xi,-0.18*\yi) circle (0.08) \fi;
        }
    }
\end{tikzpicture}

\begin{tikzpicture}
    \foreach\row [count=\yi] in \ASCIIfont{
        \dowithchar\row\yi
    }
\end{tikzpicture}

\end{document}

答案1

Z 有parser专门用于此目的的模块。它允许您解析字符串并对其进行处理。

\documentclass[12pt]{article}

\usepackage{tikz}
\usepgfmodule{parser}
\newcounter{pft}
\pgfparserdef{ASCIIswitch}{initial}{the letter X}% 
{\stepcounter{pft}%
\fill (0.18*\number\value{pft},0) circle [radius=0.08];}%
\pgfparserdef{ASCIIswitch}{initial}{the letter O}% 
{\stepcounter{pft}}%
\pgfparserdef{ASCIIswitch}{initial}{the character ;}% 
{\pgfparserswitch{final}}%

\listfiles
\begin{document}

\newcommand\ASCIIbits{
    {0,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,%
     0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0},%
    {1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,%
     0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,1,1},%
    {1,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,1,1,0,0,0,0,0},%
    {1,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0},%
    {1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,1,1,0,0,1,1,1},%
    {1,1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,%
     0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,1,1},%
    {0,1,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,%
     0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,1},%
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,%
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}%
}
\newcommand\ASCIIfont{
    OXXXXXOOOOOXXOOOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXXXXOOOOXXXXO,%
    XXOOOXXOOOXXXXOOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOXOOOXXOOXX,%
    XXOXXXXOOXXOOXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOOOO,%
    XXOXXXXOOXXOOXXOOOOXXXXXOOOXXOOOOOOOOXXOOXXOOOXXXXOOOOOXXXXOOOOXXOOOOO,%
    XXOXXXOOOXXXXXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOXXX,%
    XXOOOOOOOXXOOXXOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOOOOOXXOOXX,%
    OXXXXXOOOXXOOXXOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXOOOOOOOXXXOX,%
    OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO%
}

Comma-separated list:

\begin{tikzpicture}
    \foreach\row [count=\yi] in \ASCIIbits{
        \foreach\chr [count=\xi] in \row {
            \ifodd\chr \fill (0.18*\xi,-0.18*\yi) circle [radius=0.08] \fi;
        }
    }
\end{tikzpicture}

\bigskip

ASCII strings parsed by parser module:

\begin{tikzpicture}
    \foreach\row [count=\yi] in \ASCIIfont{
       \begin{scope}[yshift=-0.18*\yi*1cm]
        \setcounter{pft}{0}
        \edef\temp{\noexpand\pgfparserparse{ASCIIswitch}\row;}
        \temp
       \end{scope}
    }
\end{tikzpicture}

\end{document}

在此处输入图片描述

附录:至于您在评论中提出的问题,是否可以将字符串拆分为以逗号分隔的原子列表:当然,您几乎自己就有代码。

\documentclass[12pt]{article}

\usepackage{tikz}

\makeatletter
\def\splitstring#1#2->#3;{%
      \edef#3{#1}\@tfor\chr:=#2\do{%
        \edef#3{#3,\chr}%
      }%
}
\makeatother
\begin{document}
\newcommand\ASCIIfont{
    OXXXXXOOOOOXXOOOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXXXXOOOOXXXXO,%
    XXOOOXXOOOXXXXOOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOXOOOXXOOXX,%
    XXOXXXXOOXXOOXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOOOO,%
    XXOXXXXOOXXOOXXOOOOXXXXXOOOXXOOOOOOOOXXOOXXOOOXXXXOOOOOXXXXOOOOXXOOOOO,%
    XXOXXXOOOXXXXXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOXXX,%
    XXOOOOOOOXXOOXXOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOOOOOXXOOXX,%
    OXXXXXOOOXXOOXXOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXOOOOOOOXXXOX,%
    OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO%
}

\begin{tikzpicture}
    \foreach\row [count=\yi] in \ASCIIfont{
        \expandafter\splitstring \row->\myrow;
        \foreach\chr [count=\xi] in \myrow {\def\myX{X}
            \ifx\chr\myX \fill (0.18*\xi,-0.18*\yi) circle[radius=0.08] \fi;
        }
    }
\end{tikzpicture}
\end{document}

答案2

您可以使用expl3:不需要花哨的索引,它是通过“索引图”开箱即用的。

\documentclass[12pt]{article}

\usepackage{tikz}
\usepackage{xparse}

\newcommand{\makedot}[2]{%
  \fill (0.18*#1,-0.18*#2) circle (0.08);
}

\ExplSyntaxOn
\NewDocumentCommand{\ASCIIfont}{O{}m}
 {
  \begin{tikzpicture}[#1]
  \jlettvin_asciifont:n { #2 }
  \end{tikzpicture}
 }

\seq_new:N \l__jlettvin_asciifont_rows_seq
\seq_new:N \l__jlettvin_asciifont_row_seq

\cs_new_protected:Nn \jlettvin_asciifont:n
 {
  \seq_set_from_clist:Nn \l__jlettvin_asciifont_rows_seq { #1 }
  \seq_indexed_map_function:NN \l__jlettvin_asciifont_rows_seq \__jlettvin_asciifont_row:nn
 }

\cs_new_protected:Nn \__jlettvin_asciifont_row:nn
 {% #1 = row index, #2 = row
  \seq_set_split:Nnn \l__jlettvin_asciifont_row_seq { } { #2 }
  \seq_indexed_map_inline:Nn \l__jlettvin_asciifont_row_seq
   {% ##1 = column index, ##2 = item
    \str_if_eq:nnT { ##2 } { X }
     {
      \makedot{##1}{#1}
     }
   }
 }
\ExplSyntaxOff

\begin{document}

\ASCIIfont{
    OXXXXXOOOOOXXOOOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXXXXOOOOXXXXO,
    XXOOOXXOOOXXXXOOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOXOOOXXOOXX,
    XXOXXXXOOXXOOXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOOOO,
    XXOXXXXOOXXOOXXOOOOXXXXXOOOXXOOOOOOOOXXOOXXOOOXXXXOOOOOXXXXOOOOXXOOOOO,
    XXOXXXOOOXXXXXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOXXX,
    XXOOOOOOOXXOOXXOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOOOOOXXOOXX,
    OXXXXXOOOXXOOXXOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXOOOOOOOXXXOX,
    OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
}

\end{document}

输入以逗号分隔,并根据其编号(y 坐标)对每一行进行处理;该行再次被拆分为项目(以无分隔),并根据项目编号(x 坐标)进行相同的处理。

该命令\ASCIIfont有一个可选参数,用于指定选项tikzpicture

尾随的零行不会产生垂直空间,但这在其他实现中也是一个问题。

在此处输入图片描述

答案3

这里有两种方法可以修复你的代码(与薛定谔的猫给出的方法完全不同)。

可能,您最重要的“错误”是您需要\row在将结果输入到之前扩展宏\dowithchar,如第二张图片所示。另外,我看不出您的\myspace宏的用途,所以我删除了它。

第二个问题是你需要的\if是 而不是\ifx(当然,\ifx可以使用,但不能这样使用)。你的\ifx测试中发生的事情是,它将\chr宏与类别代码 1(组的开头)的左括号进行比较{:比较始终为 false;这就是第二张图片不可见的原因。\ifx比较接下来的两个标记,它永远不会扩大它们。另一方面,\if扩展后面的内容直到它有两个不可扩展的标记;然后,它比较它们的字符代码(这有点简单化:对于不可扩展的控制序列标记和活动字符有特殊的规则 - 参见 TeXbook p.209 或专门的问题)。

\pgfmathtruncatemacro

这里,里面\dowithchar\xi一个宏,就像第一张图片一样。

\documentclass{article}
\usepackage{tikz}

\makeatletter
\def\dowithchar#1#2{%
  \begingroup
    \def\xi{1}
      \@tfor\chr:=#1\do{%
        \if X\chr \fill (0.18*\xi,-0.18*#2) circle (0.08); \fi
        \pgfmathtruncatemacro{\xi}{\xi+1}
      }%
  \endgroup
}
\makeatother

\begin{document}

\newcommand\ASCIIbits{
    {0,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,%
     0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0},%
    {1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,%
     0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,1,1},%
    {1,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,1,1,0,0,0,0,0},%
    {1,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0},%
    {1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,1,1,0,0,1,1,1},%
    {1,1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,%
     0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,1,1},%
    {0,1,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,%
     0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,1},%
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,%
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}%
}
\newcommand\ASCIIfont{
    OXXXXXOOOOOXXOOOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXXXXOOOOXXXXO,%
    XXOOOXXOOOXXXXOOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOXOOOXXOOXX,%
    XXOXXXXOOXXOOXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOOOO,%
    XXOXXXXOOXXOOXXOOOOXXXXXOOOXXOOOOOOOOXXOOXXOOOXXXXOOOOOXXXXOOOOXXOOOOO,%
    XXOXXXOOOXXXXXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOXXX,%
    XXOOOOOOOXXOOXXOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOOOOOXXOOXX,%
    OXXXXXOOOXXOOXXOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXOOOOOOOXXXOX,%
    OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO%
}

\begin{tikzpicture}
    \foreach\row [count=\yi] in \ASCIIbits{
        \foreach\chr [count=\xi] in \row {
            \ifodd\chr \fill (0.18*\xi,-0.18*\yi) circle (0.08) \fi;
        }
    }
\end{tikzpicture}

\bigskip
\begin{tikzpicture}
    \foreach\row [count=\yi] in \ASCIIfont{
        \expandafter\dowithchar\expandafter{\row}\yi
    }
\end{tikzpicture}

\end{document}

使用 TeX\count寄存器

在这里,我们通过一个标记使用 TeX\count寄存器来计算(第二张图片)\countdef中的列数。标记是。我们可以重复使用相同的名称,但我更喜欢使用不同的名称以避免混淆,因为在第一张图片中,是一个宏(一个\ASCIIfont\countdef\myXi\xi\xi\countdef标记是不可扩展的;特别是,它是不是宏)。

\documentclass{article}
\usepackage{tikz}

\newcount\myXi

\makeatletter
\def\dowithchar#1#2{%
  \myXi=1                     % <--- don't remove the space
  \@tfor\chr:=#1\do{%
    \if X\chr \fill (0.18*\myXi,-0.18*#2) circle (0.08); \fi
    \advance \myXi by 1       % <--- don't remove the space
  }%
}
\makeatother

\begin{document}

\newcommand\ASCIIbits{
    {0,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,%
     0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0},%
    {1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,%
     0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,1,1},%
    {1,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,1,1,0,0,0,0,0},%
    {1,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0},%
    {1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,1,1,0,0,1,1,1},%
    {1,1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,%
     0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,1,1},%
    {0,1,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,%
     0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,1},%
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,%
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}%
}
\newcommand\ASCIIfont{
    OXXXXXOOOOOXXOOOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXXXXOOOOXXXXO,%
    XXOOOXXOOOXXXXOOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOXOOOXXOOXX,%
    XXOXXXXOOXXOOXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOOOO,%
    XXOXXXXOOXXOOXXOOOOXXXXXOOOXXOOOOOOOOXXOOXXOOOXXXXOOOOOXXXXOOOOXXOOOOO,%
    XXOXXXOOOXXXXXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOXXX,%
    XXOOOOOOOXXOOXXOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOOOOOXXOOXX,%
    OXXXXXOOOXXOOXXOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXOOOOOOOXXXOX,%
    OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO%
}

\begin{tikzpicture}
    \foreach\row [count=\yi] in \ASCIIbits{
        \foreach\chr [count=\xi] in \row {
            \ifodd\chr \fill (0.18*\xi,-0.18*\yi) circle (0.08) \fi;
        }
    }
\end{tikzpicture}

\bigskip
\begin{tikzpicture}
    \foreach\row [count=\yi] in \ASCIIfont{
        \expandafter\dowithchar\expandafter{\row}\yi
    }
\end{tikzpicture}

\end{document}

输出

两种情况下的输出相同:

在此处输入图片描述

答案4

为了好玩,您可以实现自己的\romannumeral0基于 -expansion 的尾部递归循环宏,以便用\row逗号散布构成扩展的标记。(如果这样做,需要一点扩展控制才能使所有标记按正确的顺序排列,但这可能是一项不错且轻松的练习。)然后,您可以使用基于逗号列表的 -loop\foreach..[count=...]...而不是基于非分隔参数的\@tfor-loop。

\documentclass[12pt]{article}

\usepackage{tikz}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatletter
\newcommand\insertcommas[3]{%
  % #1 tokens to put in front of brace-nested comma-list
  % #2 comma-list accumulated so far
  % #3 either the appended \insertcommas or an element from non-comma-list
  \romannumeral0%
  \ifx\insertcommas#3\expandafter\@secondoftwo\else\expandafter\@firstoftwo\fi
  {\expandafter\@gobbletwo\insertcommas{#1}{#2#3,}}{ #1{#2}}%
}%
\newcommand\exchange[2]{#2#1}%
\newcommand\dowithchar[2]{%
    % #1 = the token \row needs to be expanded before \insertcommas can be applied.
    \expandafter\exchange\expandafter{#1}{\insertcommas{\foreach\chr [count=\xi] in }{}}\insertcommas{%
       % You have nullfont inside tikzpicture-environment, so \space has no effect inside
       % tikzpicture-environment, so it is not clear to me why you want it, but here
       % you get it:
       \ifnum\xi>1 \space\fi
       %%%%%%%%
       \expandafter\ifx\expandafter X\chr\fill(0.18*\xi,-0.18*#2) circle (0.08) \fi;%
    }%
}%
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\listfiles
\begin{document}

\newcommand\ASCIIbits{
    {0,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,%
     0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0},%
    {1,1,0,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,%
     0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,1,1},%
    {1,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,1,1,0,0,0,0,0},%
    {1,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0},%
    {1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,%
     0,0,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,1,1,0,0,1,1,1},%
    {1,1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,%
     0,0,1,1,0,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,1,1},%
    {0,1,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,%
     0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,1},%
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,%
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}%
}
\newcommand\ASCIIfont{%
    OXXXXXOOOOOXXOOOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXXXXOOOOXXXXO,%
    XXOOOXXOOOXXXXOOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOXOOOXXOOXX,%
    XXOXXXXOOXXOOXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOOOO,%
    XXOXXXXOOXXOOXXOOOOXXXXXOOOXXOOOOOOOOXXOOXXOOOXXXXOOOOOXXXXOOOOXXOOOOO,%
    XXOXXXOOOXXXXXXOOOOXXOOXXOOXXOOOOOOOOXXOOXXOOOXXOXOOOOOXXOXOOOOXXOOXXX,%
    XXOOOOOOOXXOOXXOOOOXXOOXXOOOXXOOXXOOOXXOXXOOOOXXOOOXOOOXXOOOOOOOXXOOXX,%
    OXXXXXOOOXXOOXXOOOXXXXXXOOOOOXXXXOOOXXXXXOOOOXXXXXXXOOXXXXOOOOOOOXXXOX,%
    OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO%
}

\begin{tikzpicture}
    \foreach\row [count=\yi] in \ASCIIbits{
        \foreach\chr [count=\xi] in \row {
            \ifodd\chr \fill (0.18*\xi,-0.18*\yi) circle (0.08) \fi;
        }
    }
\end{tikzpicture}

\begin{tikzpicture}
    \foreach\row [count=\yi] in \ASCIIfont{
        \dowithchar\row\yi
    }
\end{tikzpicture}

\end{document}

相关内容