summaryrefslogtreecommitdiff
path: root/graphics/pxpic/pxpic.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/pxpic/pxpic.dtx')
-rw-r--r--graphics/pxpic/pxpic.dtx1022
1 files changed, 1022 insertions, 0 deletions
diff --git a/graphics/pxpic/pxpic.dtx b/graphics/pxpic/pxpic.dtx
new file mode 100644
index 0000000000..5ece9f6490
--- /dev/null
+++ b/graphics/pxpic/pxpic.dtx
@@ -0,0 +1,1022 @@
+% \iffalse meta-comment
+%
+% File: pxpic.dtx Copyright (C) 2021 Jonathan P. Spratte
+%
+% This work may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this license or
+% (at your option) any later version. The latest version of this license is in
+% the file:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% ------------------------------------------------------------------------------
+%
+%<*driver>^^A>>=
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+\input l3docstrip.tex
+\askforoverwritefalse
+\preamble
+
+--------------------------------------------------------------
+pxpic -- draw pixel pictures
+E-mail: jspratte@yahoo.de
+Released under the LaTeX Project Public License v1.3c or later
+See http://www.latex-project.org/lppl.txt
+--------------------------------------------------------------
+
+Copyright (C) 2021 Jonathan P. Spratte
+
+This work may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this license or
+(at your option) any later version. The latest version of this license is in
+the file:
+
+ http://www.latex-project.org/lppl.txt
+
+This work is "maintained" (as per LPPL maintenance status) by
+ Jonathan P. Spratte.
+
+This work consists of the file pxpic.dtx
+and the derived files pxpic.pdf
+ pxpic.sty
+
+\endpreamble
+% stop docstrip adding \endinput
+\postamble
+\endpostamble
+\generate{\file{pxpic.sty}{\from{pxpic.dtx}{pkg}}}
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+%
+\ProvidesFile{pxpic.dtx}[2021-01-10 v1.0 draw pixel pictures]
+\PassOptionsToPackage{full}{textcomp}
+\documentclass{l3doc}
+\RequirePackage[oldstylenums,nott]{kpfonts}
+\usepackage{pxpic}
+\input{glyphtounicode}
+\pdfgentounicode=1
+\RequirePackage{listings}
+\RequirePackage{booktabs}
+\RequirePackage{array}
+\RequirePackage{collcell}
+\RequirePackage{xcolor}
+\RequirePackage{caption}
+\RequirePackage{microtype}
+\RequirePackage{accsupp}
+\RequirePackage{enumitem}
+\lstset
+ {
+ ,flexiblecolumns=false
+ ,basewidth=.53em
+ ,gobble=2
+ ,basicstyle=\fontfamily{jkp}\itshape
+ ,morekeywords=^^A
+ {^^A
+ \pxpic,\pxpicsetup
+ }
+ ,morecomment=[l]\%
+ ,commentstyle=\color[gray]{0.4}
+ ,literate={\{}{{\CodeSymbol\{}}{1}
+ {\}}{{\CodeSymbol\}}}{1}
+ ^^A,literate=*{<key>}{\key}{4}{<set>}{\set}{4}
+ }
+\newcommand*\CodeSymbol[1]{\textbf{#1}}
+\RequirePackage{randtext}
+\let\metaORIG\meta
+\protected\def\meta #1{\texttt{\metaORIG{#1}}}
+\newcommand*\CS{\cs[no-index]}
+\renewcommand*\thefootnote{\fnsymbol{footnote}}
+\definecolor{pxpicred}{HTML}{9F393D}
+\colorlet{pxpicgrey}{black!75}
+\makeatletter
+\newcommand*\pxpicname
+ {^^A
+ \texorpdfstring
+ {^^A
+ \mbox
+ {^^A
+ \BeginAccSupp{ActualText=pxpic}^^A
+ \href{https://github.com/Skillmon/ltx_pxpic}{\pxpiclogo}^^A
+ \EndAccSupp{}^^A
+ }^^A
+ }
+ {pxpic}^^A
+ }
+\definecolor{expkvred}{HTML}{9F393D}
+\colorlet{expkvgrey}{black!75}
+\newcommand*\expkv
+ {^^A
+ \texorpdfstring
+ {^^A
+ \mbox
+ {^^A
+ \BeginAccSupp{ActualText=expkv}^^A
+ \href{https://github.com/Skillmon/tex_expkv}
+ {^^A
+ \rmfamily
+ \bfseries
+ {\color{expkvgrey}e\kern-.05em x\kern-.05em}^^A
+ \lower.493ex
+ \hbox{{\color{expkvgrey}P}\kern-.1em{\color{expkvred}k}}^^A
+ \kern-.18em{\color{expkvred}v}^^A
+ }^^A
+ \EndAccSupp{}^^A
+ }^^A
+ }
+ {expkv}^^A
+ }
+\hypersetup{linkcolor=red!80!black,urlcolor=purple!80!black}
+\DoNotIndex{\baselineskip,\begingroup,\bgroup}
+\DoNotIndex{\csname}
+\DoNotIndex{\def,\detokenize,\dimexpr}
+\DoNotIndex{\egroup,\ekvdef,\ekvdefNoVal,\ekvifdefinedNoVal,\ekvletkv,\ekvparse}
+\DoNotIndex{\ekvsetdef,\endcsname,\endgroup,\expandafter}
+\DoNotIndex{\hbox,\hskip}
+\DoNotIndex{\leavevmode,\let,\long,\lower}
+\DoNotIndex{\newcommand,\newdimen}
+\DoNotIndex{\PackageError,\protected,\ProvidesPackage}
+\DoNotIndex{\relax,\RequirePackage}
+\DoNotIndex{\@depth,\@height,\@ifdefinable,\@ifnextchar,\@ifundefined,\@width}
+\DoNotIndex{\ekv@ifempty,\ekv@name,\z@}
+\DoNotIndex{\color}
+\DoNotIndex{\vbox,\vrule}
+\@ifdefinable\gobbledocstriptag{\def\gobbledocstriptag#1>{}}
+\makeatother
+\newenvironment{options}[1][]
+ {%
+ \begin{description}
+ [
+ style=nextline
+ ,font=\normalfont\ttfamily
+ ,labelindent=-.5\marginparwidth
+ ,labelwidth=\dimexpr.5\marginparwidth-5pt\relax
+ ,labelsep*=5pt
+ ,leftmargin=!
+ ,#1
+ ]%
+ \renewenvironment{options}[1][]
+ {%
+ \begin{description}
+ [
+ style=nextline
+ ,font=\normalfont\ttfamily
+ ,#1
+ ]%
+ }
+ {\end{description}}%
+ }
+ {\end{description}}
+\begin{document}
+ \title
+ {^^A
+ \texorpdfstring
+ {^^A
+ \Huge
+ \mbox
+ {^^A
+ \BeginAccSupp{ActualText=pxpic}^^A
+ \href{https://github.com/Skillmon/ltx_pxpic}{\pxpiclogo}^^A
+ \EndAccSupp{}^^A
+ }^^A
+ \\[\medskipamount]
+ \Large draw pixel pictures^^A
+ }{pxpic - draw pixel pictures}^^A
+ }
+ \date{2021-01-10 v1.0}
+ \author{Jonathan P. Spratte\thanks{\protect\randomize{jspratte@yahoo.de}}}
+ \DocInput{pxpic.dtx}
+\end{document}
+%</driver>^^A=<<
+% \fi
+%
+% \maketitle
+% \renewcommand*\thefootnote{\arabic{footnote}}
+%
+% \begin{abstract}
+% \noindent\parfillskip=0pt
+% With \pxpicname\ you draw pictures pixel by pixel. It was inspired by a
+% \href{https://tex.stackexchange.com/a/63759/117050}
+% {lovely post by Paulo Cereda},
+% among other things (most notably a beautiful duck) showcasing the use of
+% characters from the Mario video games by Nintendo in \LaTeX.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \begin{documentation}^^A>>=
+%
+% \section{Documentation}
+%
+% \subsection{Drawing pictures}
+%
+% \pxpicname\ supports different input modes, all of them have the same basic
+% parsing behaviour. A \meta{pixel list} contains the pixel colours. The image
+% is built line wise from top left to bottom right. Each row of pixels should be
+% a single \TeX\ argument (so either just one token, or a group delimited by
+% |{}|), and within each line each pixel in turn should be a single \TeX\
+% argument (so either just one token, or a group delimited by |{}|). Spaces and
+% hence single newlines in the sources between \meta{pixel list} elements are
+% ignored. The different modes are explained in \autoref{sec:modes}. The only
+% disallowed token in the \meta{pixel list} is the control sequence
+% \CS{pxpic@end} (plus the usual restrictions of \TeX\ so no unbalanced braces,
+% no macros defined as \CS{outer}).
+%
+% There is a small caveat however: \pxpicname\ draws each pixel individually,
+% and there is really no space between them, however some \textsc{pdf} viewers
+% fail to display such adjacent lines correctly and leave small gaps (basically
+% the same issue which packages like \pkg{colortbl} suffer from as well). In
+% print this shouldn't be an issue, but some rasterisation algorithms employed
+% by viewers and conversion tools have this deficit.
+%
+% \begin{function}{\pxpic}
+% \begin{syntax}
+% \cs{pxpic}\oarg{options}\marg{pixel list}
+% \end{syntax}
+% \meta{options} might be any options as listed in \autoref{sec:options}, and
+% \meta{pixel list} is a list of pixels as described above. \cs{pxpic} parses
+% the \meta{pixel list} and draws the corresponding picture. The result is
+% contained in an \CS{hbox} and can be used wherever \TeX\ expects an
+% \CS{hbox}. As a result, when you're in vertical mode a \cs{pxpic} will form
+% a text line, to prevent this you can use \CS{leavevmode} before it. The
+% \cs{pxpic} will be bottom aligned, you can change this using \CS{raisebox}
+% (or, if you want, \TeX's \CS{raise} and \CS{lower} primitives).
+% \end{function}
+%
+% \subsubsection{Examples}
+%
+% Since the above explanation of the \meta{pixel list} syntax might've been a
+% bit cryptic, and a good documentation should contain examples (this doesn't
+% claim this documentation is \emph{good}), well, here are some examples (you
+% might need to take a look at \autoref{sec:options} and \autoref{sec:modes} to
+% fully understand the examples). Examples in this section will use the
+% following \CS{pxpicsetup}:
+%
+% \begingroup
+% \footnotesize
+% \begin{lstlisting}
+% \pxpicsetup
+% {
+% mode = px
+% ,colours = {k=black, r=[HTML]{9F393D}, g=green!75!black, b=[rgb]{0,0,1}}
+% ,skip = .
+% ,size = 10pt
+% }
+% \end{lstlisting}
+% \endgroup
+%
+% \begingroup
+% \pxpicsetup
+% {
+% mode = px
+% ,colours = {k=black, r=[HTML]{9F393D}, g=green!75!black, b=[rgb]{0,0,1}}
+% ,skip = .
+% ,size = 10pt
+% }
+%
+% We can draw a small cross rather easily:\par\nobreak
+% \noindent
+% \begin{minipage}[c]{.5\linewidth}\footnotesize
+% \begin{lstlisting}
+% \pxpic
+% {
+% {.k}
+% {kkk}
+% {.k}
+% }
+% \end{lstlisting}
+% \end{minipage}
+% \begin{minipage}[c]{.45\linewidth}
+% \leavevmode
+% \pxpic
+% {
+% {.k}
+% {kkk}
+% {.k}
+% }
+% \end{minipage}
+%
+% A small multicoloured grid:\par\nobreak
+% \noindent
+% \begin{minipage}[c]{.5\linewidth}\footnotesize
+% \begin{lstlisting}
+% \pxpic
+% {
+% {brgk}
+% {kbrg}
+% {gkbr}
+% {rgkb}
+% }
+% \end{lstlisting}
+% \end{minipage}
+% \begin{minipage}[c]{.45\linewidth}
+% \leavevmode
+% \pxpic
+% {
+% {brgk}
+% {kbrg}
+% {gkbr}
+% {rgkb}
+% }
+% \end{minipage}
+%
+% A heart (shamelessly copied example from \pkg{pixelart}):\par\nobreak
+% \noindent
+% \begin{minipage}[c]{.5\linewidth}\footnotesize
+% \begin{lstlisting}
+% \pxpic
+% {
+% {..rr.rr}
+% {.rrrrrrr}
+% {rrrrrrrrr}
+% {rrrrrrrrr}
+% {rrrrrrrrr}
+% {.rrrrrrr}
+% {..rrrrr}
+% {...rrr}
+% {....r}
+% }
+% \end{lstlisting}
+% \end{minipage}
+% \begin{minipage}[c]{.45\linewidth}
+% \leavevmode
+% \pxpic
+% {
+% {..rr.rr}
+% {.rrrrrrr}
+% {rrrrrrrrr}
+% {rrrrrrrrr}
+% {rrrrrrrrr}
+% {.rrrrrrr}
+% {..rrrrr}
+% {...rrr}
+% {....r}
+% }
+% \end{minipage}
+%
+% Using |mode=rgb| to draw a short coloured line:\par\nobreak
+% \noindent
+% \begin{minipage}[c]{.5\linewidth}\footnotesize
+% \begin{lstlisting}
+% \pxpic[mode=rgb]{{{1,0,1}{1,1,0}{0,1,1}}}
+% \end{lstlisting}
+% \end{minipage}
+% \begin{minipage}[c]{.45\linewidth}
+% \leavevmode
+% \pxpic[mode=rgb]{{{1,0,1}{1,1,0}{0,1,1}}}
+% \end{minipage}
+%
+% A multicoloured grid using skips and |mode=cmy|:\par\nobreak
+% \noindent
+% \begin{minipage}[c]{.5\linewidth}\footnotesize
+% \begin{lstlisting}
+% \pxpic[mode=cmy]
+% {
+% {{1,0,1} {1,1,0} {0,1,1} {} }
+% {{} {1,0,1} {1,1,0} {0,1,1}}
+% {{0,1,1} {} {1,0,1} {1,1,0}}
+% {{1,1,0} {0,1,1} {} {1,0,1}}
+% }
+% \end{lstlisting}
+% \end{minipage}
+% \begin{minipage}[c]{.45\linewidth}
+% \leavevmode
+% \pxpic[mode=cmy]
+% {
+% {{1,0,1} {1,1,0} {0,1,1} {} }
+% {{} {1,0,1} {1,1,0} {0,1,1}}
+% {{0,1,1} {} {1,0,1} {1,1,0}}
+% {{1,1,0} {0,1,1} {} {1,0,1}}
+% }
+% \end{minipage}
+%
+% Showing the difference between a skipped and a white pixel:\par\nobreak
+% \noindent
+% \begin{minipage}[c]{.5\linewidth}\footnotesize
+% \begin{lstlisting}
+% \pxpicsetup{colours = {w=white}}
+% \colorbox{gray}{\pxpic{{bbb}{b.b}{bbb}}}
+% \colorbox{gray}{\pxpic{{bbb}{bwb}{bbb}}}
+% \end{lstlisting}
+% \end{minipage}
+% \begin{minipage}[c]{.45\linewidth}
+% \pxpicsetup{colours = {w=white}}
+% \colorbox{gray}{\pxpic{{bbb}{b.b}{bbb}}}
+% \colorbox{gray}{\pxpic{{bbb}{bwb}{bbb}}}
+% \end{minipage}
+%
+% \enlargethispage{1.1\baselineskip}
+% A biggish example: Tux.\footnote{Source:
+% \url{https://www.reddit.com/r/linux/comments/hwpm9j/tux_pixel_art_v10/}} I
+% put two rows of pixels per code line to reduce the size a bit and the code is
+% displayed tinily.\par\nobreak
+% \noindent
+% \begin{minipage}[c]{.5\linewidth}\tiny
+% \begin{lstlisting}
+% \pxpic
+% [
+% size = 2.5pt
+% ,colours = {:=orange,
+% '=black!10,
+% g=black!75,
+% O=orange!80!black}
+% ]
+% {
+% {...........gggg} {.........gggkkggg}
+% {........ggkkkkkkkg} {........gkkkkkkkkg}
+% {........kkkkkkkkkk} {.......gkk.kkkk.kkk}
+% {.......gk.k.kk.k.kk} {.......gk.k.kk.k.kk}
+% {.......gkkkkkkkkkkk} {.......gkkk::::kkkk}
+% {.......gk::::::::kk} {.......gk.:kkkk:kkk}
+% {......gkk..::::'kkkk} {......gkk....'''kkkk}
+% {......gkk....''''kkk} {.....gkk.....''''kkkk}
+% {.....gk.......''''kkk} {....gkk........'''kkkk}
+% {....gkk........'''kkkk} {....gk..........''kkkk}
+% {...gkkg.........'''kkkk} {...gkkkk........'''kkkk}
+% {..OOOOkkk.......'''kOOOO} {..O::::kkk......'''O:::O}
+% {.O::::::kk.....'''::::::O} {.O::::::kkk...''kk::::::O}
+% {O:::::::kkk...'kkk:::::::O} {O:::::::kkk...'kkk:::::::O}
+% {.O:::::::kkkkkkkk:::::::O} {..OO:::::kkkkkkkk:::::OO}
+% {....OO::O.kkkkkk.O::OO} {......OOO........OOO}
+% }
+% \end{lstlisting}
+% \end{minipage}
+% \begin{minipage}[c]{.45\linewidth}
+% \leavevmode
+% \pxpic
+% [
+% size = 2.5pt
+% ,colours = {:=orange,
+% '=black!10,
+% g=black!75,
+% O=orange!80!black}
+% ]
+% {
+% {...........gggg} {.........gggkkggg}
+% {........ggkkkkkkkg} {........gkkkkkkkkg}
+% {........kkkkkkkkkk} {.......gkk.kkkk.kkk}
+% {.......gk.k.kk.k.kk} {.......gk.k.kk.k.kk}
+% {.......gkkkkkkkkkkk} {.......gkkk::::kkkk}
+% {.......gk::::::::kk} {.......gk.:kkkk:kkk}
+% {......gkk..::::'kkkk} {......gkk....'''kkkk}
+% {......gkk....''''kkk} {.....gkk.....''''kkkk}
+% {.....gk.......''''kkk} {....gkk........'''kkkk}
+% {....gkk........'''kkkk} {....gk..........''kkkk}
+% {...gkkg.........'''kkkk} {...gkkkk........'''kkkk}
+% {..OOOOkkk.......'''kOOOO} {..O::::kkk......'''O:::O}
+% {.O::::::kk.....'''::::::O} {.O::::::kkk...''kk::::::O}
+% {O:::::::kkk...'kkk:::::::O} {O:::::::kkk...'kkk:::::::O}
+% {.O:::::::kkkkkkkk:::::::O} {..OO:::::kkkkkkkk:::::OO}
+% {....OO::O.kkkkkk.O::OO} {......OOO........OOO}
+% }
+% \end{minipage}
+%
+% Just for Paulo, a duck. Also, showing that the colour definitions in |mode=px|
+% can be arbitrary tokens or multiple letters:\par\nobreak
+% \noindent
+% \begin{minipage}[c]{.5\linewidth}\tiny
+% \begin{lstlisting}
+% \pxpic[colours = {oo=orange,
+% \ylw=yellow,
+% \blk=black},
+% skip = \skp]
+% {
+% {\skp\skp\skp\ylw\ylw\ylw\ylw}
+% {\skp\skp\ylw\ylw\ylw\ylw\ylw\ylw}
+% {\skp\skp{oo}\ylw\blk\ylw\ylw\ylw}
+% {{oo}{oo}{oo}\ylw\ylw\ylw\ylw\ylw}
+% {\skp{oo}{oo}{oo}\ylw\ylw\ylw\skp\skp\skp\skp\skp\ylw}
+% {\skp\skp\skp\ylw\ylw\ylw\ylw\ylw\ylw\ylw\skp\ylw\ylw}
+% {\skp\skp\ylw\ylw\ylw\ylw\ylw\ylw\ylw\ylw\ylw\ylw\ylw}
+% {\skp\ylw\ylw\ylw\ylw\ylw\ylw\ylw\ylw\skp\ylw\ylw}
+% {\skp\ylw\ylw\skp\ylw\ylw\ylw\ylw\skp\ylw\ylw\ylw}
+% {\skp\ylw\ylw\ylw\skp\skp\skp\skp\ylw\ylw\ylw}
+% {\skp\skp\ylw\ylw\ylw\ylw\ylw\ylw\ylw\ylw}
+% {\skp\skp\skp\skp\ylw\ylw\ylw\ylw\ylw}
+% }
+% \end{lstlisting}
+% \end{minipage}
+% \begin{minipage}[c]{.45\linewidth}
+% \leavevmode
+% \pxpic[colours = {oo=orange,
+% \ylw=yellow,
+% \blk=black},
+% skip = \skp]
+% {
+% {\skp\skp\skp\ylw\ylw\ylw\ylw}
+% {\skp\skp\ylw\ylw\ylw\ylw\ylw\ylw}
+% {\skp\skp{oo}\ylw\blk\ylw\ylw\ylw}
+% {{oo}{oo}{oo}\ylw\ylw\ylw\ylw\ylw}
+% {\skp{oo}{oo}{oo}\ylw\ylw\ylw\skp\skp\skp\skp\skp\ylw}
+% {\skp\skp\skp\ylw\ylw\ylw\ylw\ylw\ylw\ylw\skp\ylw\ylw}
+% {\skp\skp\ylw\ylw\ylw\ylw\ylw\ylw\ylw\ylw\ylw\ylw\ylw}
+% {\skp\ylw\ylw\ylw\ylw\ylw\ylw\ylw\ylw\skp\ylw\ylw}
+% {\skp\ylw\ylw\skp\ylw\ylw\ylw\ylw\skp\ylw\ylw\ylw}
+% {\skp\ylw\ylw\ylw\skp\skp\skp\skp\ylw\ylw\ylw}
+% {\skp\skp\ylw\ylw\ylw\ylw\ylw\ylw\ylw\ylw}
+% {\skp\skp\skp\skp\ylw\ylw\ylw\ylw\ylw}
+% }
+% \end{minipage}
+%
+% Another example might be the definition of \CS{pxpiclogo} in
+% \autoref{sec:implementation:pxpiclogo}.
+%
+% Who still needs \env{picture}-mode or complicated packages like
+% \pkg{pstricks} or Ti\emph{k}Z with such pretty pictures?
+%
+% \endgroup
+%
+% \subsection{Setting options}\label{sec:options}
+%
+% To control its behaviour \pxpicname\ uses a key=value interface powered by
+% \expkv. Options can be set either in the optional argument of
+% \CS{pxpic} or with
+%
+% \begin{function}{\pxpicsetup}
+% \begin{syntax}
+% \cs{pxpicsetup}\marg{options}
+% \end{syntax}
+% Sets the \meta{options} locally to the current \TeX\ group.
+% \end{function}
+%
+% \medskip\noindent
+% Package options are not supported.
+%
+% \bigskip
+% The available options are
+%
+% \begin{options}
+% \item[colors] Define pixel colours for |mode=px|, see \autoref{sec:colours}
+% for a description of the value's syntax. No pixel definitions are made by
+% the package.
+% \item[colours] \emph{see \texttt{colors}.}
+% \item[ht] Set the height of the pixels.
+% \item[mode] Set the used mode, see \autoref{sec:modes} for available modes.
+% Initial value is |px|.
+% \item[size] Set both |ht| and |wd|. Initial value is \the\pxpicHT.
+% \item[skip] Define the value to be a skip (an empty space of width |wd|) in
+% |mode=px|. No skip definitions are made by the package.
+% \item[wd] Set the width of the pixels.
+% \end{options}
+%
+% \subsubsection{Colour syntax}\label{sec:colours}
+%
+% In the value of the |colours| option you'll have to use the following syntax.
+% Use a comma separated key=value list in which each key corresponds to a new
+% pixel name for |mode=px|, and each value to the used colour. If the colour
+% starts with an opening bracket use the complete value as is behind \CS{color},
+% else use the whole value as the first mandatory argument to \CS{color} with a
+% set of braces added. For example to define |r| as the named colour |red|, and
+% |x| as the colour |#abab0f| (in the \textsc{html} colour model) use:
+% \begin{lstlisting}
+% colours = {r=red, x=[HTML]{abab0f}}
+% \end{lstlisting}
+%
+% \subsubsection{Available modes}\label{sec:modes}
+%
+% \begin{options}
+% \item[px]
+% As already mentioned, \pxpicname\ supports different modes of input. The
+% easiest to use |mode| is |px|, in which each element of the \meta{pixel
+% list} has been previously defined as either a coloured pixel (using the
+% |colour| option) or as a skipped pixel (using the |skip| option, resulting
+% in a fully transparent pixel). Each element will be \CS{detokenize}d, so
+% (within \TeX's limitations) the name of a pixel can be arbitrary. This is
+% the initial mode \pxpicname\ uses. But other options are available as
+% well.
+% \item[named]
+% Another |mode| is |named|, in which each element of the \meta{pixel list}
+% should be a named colour (or colour expression) known to \pkg{xcolor}.
+% Each element will be used like so: |{\color{|\meta{element}|}\px}|. An
+% exception is an element which is empty (|{}|), which will be a skipped
+% pixel.
+% \item[rgb, cmy, cmyk, hsb, Hsb, tHsb, gray, RGB, HTML, HSB, Gray, wave]
+% The modes |rgb|, |cmy|, |cmyk|, |hsb|, |Hsb|, |tHsb|, |gray|, |RGB|,
+% |HTML|, |HSB|, |Gray|, and |wave| correspond to the different colour
+% models supported by \pkg{xcolor}. With these modes each element of the
+% \meta{pixel list} will be the values in these colour models, so they'll be
+% used like so: |{\color[|\meta{mode}|]{|\meta{element}|}\px}|. An
+% exception is an element which is empty (|{}|), which will be a skipped
+% pixel.
+% \end{options}
+%
+% You can define additional modes selectable with the |mode| option using the
+% macros |\pxpicnewmode| or |\pxpicsetmode|.
+%
+% \subsection{Other customisation macros}
+%
+% \begin{function}{\pxpicnewmode,\pxpicsetmode}
+% \begin{syntax}
+% \cs{pxpicnewmode}\marg{name}\marg{definition}
+% \end{syntax}
+% You can define your own modes with \cs{pxpicnewmode}. Inside
+% \meta{definition} |#1| is the currently parsed item in the \CS{pxpic}
+% \meta{pixel list}. You can output a pixel using \CS{px}, and skip a pixel
+% using \CS{pxskip}. The pixel will use the currently active colour (so if you
+% want to draw a red pixel you could use |{\color{red}\px}|).
+% \cs{pxpicnewmode} will throw an error if you try to define a mode which
+% already exists, \cs{pxpicsetmode} has no checks on the name.
+% \end{function}
+%
+% \begin{function}{\pxpicforget}
+% \begin{syntax}
+% \cs{pxpicforget}\marg{px}
+% \end{syntax}
+% Undefines the \meta{px} definition for use in |mode=px| (or skip symbol)
+% added with the |colours| (or |skip|) option.
+% \end{function}
+%
+% \subsection{Other macros}
+%
+% \begin{function}{\px,\pxskip}
+% Inside of a \CS{pxpic} the macro \cs{px} draws a pixel (of the currently
+% active colour), and \cs{pxskip} leaves out a pixel (so this one pixel is
+% fully transparent). Use this in the \meta{definition} of a mode in
+% \CS{pxpicnewmode}.
+% \end{function}
+%
+% \begin{variable}{\pxpicHT,\pxpicWD}
+% These two are |dimen| registers storing the height and width of the pixels.
+% \end{variable}
+%
+% \begin{function}{\pxpiclogo}
+% \begin{syntax}
+% \cs{pxpiclogo}\oarg{size}
+% \end{syntax}
+% This draws the logo of \pxpicname. The \meta{size} controls the pixel size.
+% \end{function}
+%
+% \subsection{Miscellaneous}
+%
+% If you find bugs or have suggestions I'll be glad to hear about it, you can
+% either open a ticket on Github (\url{https://github.com/Skillmon/ltx_pxpic})
+% or email me (see the first page).
+%
+% A similar package is \pkg{pixelart}, which, as of writing this, is described
+% as a ``working draft'' by its author. \pxpicname\ wasn't intended as a direct
+% competitor (I already started coding \pxpicname\ when I learned about
+% \pkg{pixelart}'s existence), but I took inspiration from the ``Bugs, Ideas,
+% Undefined behaviours'' section of \pkg{pixelart}'s documentation for the
+% syntax of |mode=px|.
+%
+%
+% \end{documentation}^^A=<<
+%
+% \begin{implementation}^^A>>=
+%
+% \gobbledocstriptag
+%<*pkg>
+%
+% \clearpage
+%
+% \section{Implementation}^^A>>=
+%
+% Report who we are
+% \begin{macrocode}
+\ProvidesPackage{pxpic}[2021-01-10 v1.0 draw pixel pictures]
+% \end{macrocode}
+% and load dependencies
+% \begin{macrocode}
+\RequirePackage{xcolor}
+\RequirePackage{expkv}
+% \end{macrocode}
+% \begin{variable}{\pxpicHT,\pxpicWD}
+% These two variables store the height and width of a pixel.
+% \begin{macrocode}
+\@ifdefinable\pxpicHT{\newdimen\pxpicHT}
+\@ifdefinable\pxpicWD{\newdimen\pxpicWD}
+\pxpicHT=1pt
+\pxpicWD=\pxpicHT
+% \end{macrocode}
+% \end{variable}
+%
+%
+% \subsection{Options}
+%
+% We define the options using \expkv\ directly (no fancy options are involved
+% and these are just a few anyway).
+%
+% The first few options are straight forward. We use \expkv's name space to
+% actually store the |skip| and |px| definitions, hence we use
+% \CS{ekvdefNoVal} in the code of |skip|.
+%
+% \begin{macrocode}
+\protected\ekvdef{pxpic}{size}
+ {\pxpicHT=\dimexpr#1\relax\pxpicWD=\dimexpr#1\relax}
+\protected\ekvdef{pxpic}{ht}{\pxpicHT=\dimexpr#1\relax}
+\protected\ekvdef{pxpic}{wd}{\pxpicWD=\dimexpr#1\relax}
+\protected\ekvdef{pxpic}{skip}{\ekvdefNoVal{pxpic@px}{#1}{\pxskip}}
+% \end{macrocode}
+% The |colours| option is parsed using \CS{ekvparse} and \CS{pxpic@setcolor}.
+% \begin{macrocode}
+\protected\ekvdef{pxpic}{colors}{\ekvparse\pxpic@noval\pxpic@setcolor{#1}}
+\ekvletkv{pxpic}{colours}{pxpic}{colors}
+% \end{macrocode}
+% And the |mode| just checks whether the |mode| macro is defined and lets the
+% auxiliary macro \CS{pxpic@parse@px} to the defined |mode|.
+% \begin{macrocode}
+\protected\ekvdef{pxpic}{mode}
+ {%
+ \@ifundefined{pxpic@parse@px@#1}%
+ {\pxpic@unknown@mode{#1}}%
+ {%
+ \expandafter\let\expandafter\pxpic@parse@px
+ \csname pxpic@parse@px@#1\endcsname
+ }%
+ }
+% \end{macrocode}
+%
+%
+% \subsection{User macros}\label{sec:implementation:pxpiclogo}
+%
+% \begin{macro}{\pxpic}
+% \begin{macro}[internal]{\pxpic@}
+% \CS{pxpic} expands directly to an opened \CS{hbox}, the auxiliary
+% \CS{pxpic@} checks for the optional argument and inserts the rest of the
+% code. We need to set \CS{baselineskip} to \CS{pxpicHT} so that the pixels
+% are stacked vertically without gaps. \CS{pxpic@parse} will parse the
+% \meta{pixel list} until \CS{pxpic@end} is hit. The final \CS{egroup} closes
+% the \CS{hbox}. The row-wise output is done via a \CS{vbox} in which each
+% pixel row will be wrapped inside an \CS{hbox}.
+% \begin{macrocode}
+\newcommand*\pxpic{\hbox\bgroup\pxpic@}
+\newcommand\pxpic@[2][]
+ {%
+ \vbox
+ {%
+ \pxpicsetup{#1}%
+ \let\px\pxpic@px
+ \let\pxskip\pxpic@skip
+ \baselineskip\pxpicHT
+ \pxpic@parse#2\pxpic@end
+ }%
+ \egroup
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\pxpicsetup}
+% Just directly defined to call \expkv's parser for the \pxpicname\ set.
+% \begin{macrocode}
+\ekvsetdef\pxpicsetup{pxpic}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pxpiclogo}
+% The logo is just a biggish pixel picture. The \CS{lower} will move it down a
+% bit so that it appears correctly aligned on the baseline. Since the logo
+% should be part of a normal sentence in most usages we put \CS{leavevmode}
+% before it. Also we make sure that the |mode| and |px| definitions are
+% correct.
+% \begin{macrocode}
+\newcommand*\pxpiclogo[1][.13ex]
+ {%
+ \begingroup
+ \pxpicHT\dimexpr#1\relax
+ \pxpicWD\pxpicHT
+ \leavevmode
+ \lower3.2\pxpicHT\pxpic
+ [mode=px,colours={o=[HTML]{9F393D},g=black!75},skip=.]
+ {
+ {............................................g}
+ {...........................................gggg}
+ {.oooo.......................gggg...........ggg}
+ {.ooooo...oo......oo...oo....ggggg...gg......g..........g}
+ {.ooooooooooo...ooooo..oooo..ggggggggggg...ggggg...ggggggg}
+ {..ooooo..oooo.ooooooooooo....ggggg..gggg.ggggggg.ggggggggg}
+ {...oooo..oooo....ooooo........gggg..gggg...gggg..gggg.ggg}
+ {...oooo..oooo.....oooo........gggg..gggg...gggg..gggg}
+ {.oooooo..oooo.....ooooo.....gggggg..gggg...gggg..gggg}
+ {oooooooooooo...ooooooooo...gggggggggggg....gggg..ggggggggg}
+ {o.oooooooo....ooooo.oooooo.g.gggggggg......ggggg..ggggggg}
+ {...ooo.o......o.oo...oo.......ggg.g.........gg......ggg}
+ {...ooo........................ggg}
+ {...ooo........................ggg}
+ {....o..........................g}
+ }%
+ \endgroup
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pxpicforget}
+% Straight forward, just let the |px| macro to an undefined macro.
+% \begin{macrocode}
+\newcommand\pxpicforget[1]
+ {\expandafter\let\csname\ekv@name{pxpic@px}{#1}N\endcsname\pxpic@undef}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pxpicnewmode,\pxpicsetmode}
+% These are pretty simple as well, the |new| variant will use \CS{newcommand}
+% which will do the testing for us, the |set| variant uses \CS{def}.
+% \begin{macrocode}
+\protected\def\pxpicnewmode#1#2%
+ {\expandafter\newcommand\csname pxpic@parse@px@#1\endcsname[1]{#2}}
+\protected\def\pxpicsetmode#1#2%
+ {\long\expandafter\def\csname pxpic@parse@px@#1\endcsname##1{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Parser}
+%
+% \begin{macro}[internal]{\pxpic@ifend,\pxpic@ifempty,\pxpic@ifbracket}
+% These are three helper macros. The first just gobbles everything until the
+% next \CS{pxpic@end}, and we borrow a fast test for an empty argument from
+% \expkv. The last can be used to check for an opening bracket if used like
+% |\pxpic@ifbracket|\hskip0pt|\pxpic@end|\hskip0pt|#1.\pxpic@end|\hskip0pt
+% |[]\pxpic@end|.
+% \begin{macrocode}
+\long\def\pxpic@ifend#1\pxpic@end{}
+\let\pxpic@ifempty\ekv@ifempty
+\long\def\pxpic@ifbracket#1\pxpic@end[#2]\pxpic@end{\pxpic@ifempty{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\pxpic@parse,\pxpic@done}
+% The parsing loop is pretty simple, first check whether we're done, else open
+% a new \CS{hbox} (which will form a row in the \CS{vbox} placed by
+% \CS{pxpic@}) in which the inner parsing loop is run. Then call the next
+% iteration. If we're done just gobble the remainder of the current iteration.
+% \begin{macrocode}
+\newcommand\pxpic@parse[1]
+ {%
+ \pxpic@ifend#1\pxpic@done\pxpic@end
+ \hbox{\pxpic@parseline#1\pxpic@end}%
+ \pxpic@parse
+ }
+\long\def\pxpic@done\pxpic@end\hbox#1\pxpic@parse{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\pxpic@parseline,\pxpic@linedone}
+% The line parsing loop also checks whether we're done, if not we place a
+% pixel using the current definition of \CS{pxpic@parse@px} (which will be set
+% by the current |mode|) and afterwards call the next iteration. If we're done
+% we gobble the remainder of the current iteration and control goes back to
+% \CS{pxpic@parse}.
+% \begin{macrocode}
+\newcommand\pxpic@parseline[1]
+ {%
+ \pxpic@ifend#1\pxpic@linedone\pxpic@end
+ \pxpic@parse@px{#1}%
+ \pxpic@parseline
+ }
+\long\def\pxpic@linedone\pxpic@end\pxpic@parse@px#1\pxpic@parseline{}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Modes}
+%
+% The modes define how a single element of the \meta{pixel list} is parsed.
+%
+% \begin{macro}[internal]{\pxpic@parse@px@px,\pxpic@parse@px}
+% In the |px| mode we check whether the pixel is defined (using the name space
+% of \expkv), if so call it, else throw an error and skip. Since this is also
+% the initial |mode| we \CS{let} the auxiliary macro \CS{pxpic@parse@px} to
+% this mode here.
+% \begin{macrocode}
+\newcommand\pxpic@parse@px@px[1]
+ {%
+ \ekvifdefinedNoVal{pxpic@px}{#1}
+ {\csname\ekv@name{pxpic@px}{#1}N\endcsname}%
+ {%
+ \pxpic@unknown@px{#1}%
+ \pxskip
+ }%
+ }
+\let\pxpic@parse@px\pxpic@parse@px@px
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\pxpic@parse@px@named}
+% |named| just checks whether the skip is empty. If so skip, else call
+% \CS{color} with the element and output a pixel.
+% \begin{macrocode}
+\newcommand\pxpic@parse@px@named[1]
+ {%
+ \pxpic@ifempty{#1}
+ {\pxskip}
+ {{\color{#1}\px}}%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]
+% {
+% \pxpic@parse@px@rgb,
+% \pxpic@parse@px@cmy,
+% \pxpic@parse@px@cmyk,
+% \pxpic@parse@px@hsb,
+% \pxpic@parse@px@Hsb,
+% \pxpic@parse@px@tHsb,
+% \pxpic@parse@px@gray,
+% \pxpic@parse@px@RGB,
+% \pxpic@parse@px@HTML,
+% \pxpic@parse@px@HSB,
+% \pxpic@parse@px@Gray,
+% \pxpic@parse@px@wave
+% }
+% The colour model modes are all the same in principle. They test for an empty
+% element to introduce a skip, else they call \CS{color} with the respective
+% colour model and output a pixel. We use the auxiliary \CS{pxpic@tmp} to do
+% all those definitions and undefine it afterwards.
+% \begin{macrocode}
+\def\pxpic@tmp#1%
+ {%
+ \pxpicnewmode{#1}%
+ {%
+ \pxpic@ifempty{##1}
+ {\pxskip}
+ {{\color[#1]{##1}\px}}%
+ }%
+ }
+\pxpic@tmp{rgb}
+\pxpic@tmp{cmy}
+\pxpic@tmp{cmyk}
+\pxpic@tmp{hsb}
+\pxpic@tmp{Hsb}
+\pxpic@tmp{tHsb}
+\pxpic@tmp{gray}
+\pxpic@tmp{RGB}
+\pxpic@tmp{HTML}
+\pxpic@tmp{HSB}
+\pxpic@tmp{Gray}
+\pxpic@tmp{wave}
+\let\pxpic@tmp\pxpic@undef
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Pixel and Skip}
+%
+% \begin{macro}[internal]{\pxpic@px,\pxpic@skip}
+% The actual definition of pixels and skips is stored in macros to which the
+% frontend macros \CS{px} and \CS{pxskip} will be let inside of \CS{pxpic}.
+% \begin{macrocode}
+\newcommand\pxpic@px{\vrule\@height\pxpicHT\@width\pxpicWD\@depth\z@}
+\newcommand\pxpic@skip{\hskip\pxpicWD}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Parser for colours}
+%
+% \begin{macro}[internal]{\pxpic@setcolor,\pxpic@setcolor@a,\pxpic@setcolor@b}
+% First we test whether the colour starts with an opening bracket or not.
+% Depending on that we either just put the colour after \CS{color}, or put
+% braces around it (as it then is a colour expression for \pkg{xcolor} and
+% just a single argument). \CS{pxpic@setcolor} defines a |px| in the name
+% space of \expkv\ (this has a slight overhead during definition, but \expkv\
+% is fast in checking whether one of its keys is defined or not, and reduces
+% the amount of code in this package).
+% \begin{macrocode}
+\newcommand\pxpic@setcolor[2]
+ {%
+ \pxpic@ifbracket\pxpic@end#2.\pxpic@end[]\pxpic@end
+ \pxpic@setcolor@a\pxpic@setcolor@b
+ {#1}{#2}%
+ }
+\newcommand\pxpic@setcolor@a[2]
+ {\ekvdefNoVal{pxpic@px}{#1}{{\color{#2}\px}}}
+\newcommand\pxpic@setcolor@b[2]
+ {\ekvdefNoVal{pxpic@px}{#1}{{\color#2\px}}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Messages}
+%
+% \begin{macro}[internal]{\pxpic@noval,\pxpic@unknown@px,\pxpic@unknown@mode}
+% These are just some macros throwing errors, nothing special here.
+% \begin{macrocode}
+\newcommand\pxpic@noval[1]
+ {\PackageError{pxpic}{Missing colour definition for name `\detokenize{#1}'}{}}
+\newcommand\pxpic@unknown@px[1]
+ {\PackageError{pxpic}{Unknown pixel `\detokenize{#1}'. Skipping}{}}
+\newcommand\pxpic@unknown@mode[1]
+ {\PackageError{pxpic}{Unknown mode `#1'}{}}
+% \end{macrocode}
+% \end{macro}
+%
+%^^A=<<
+%
+% \gobbledocstriptag
+%</pkg>
+%
+% \end{implementation}^^A=<<
+%
+% \clearpage
+% \PrintIndex
+%
+\endinput
+%
+^^A vim: ft=tex fdm=marker fmr=>>=,=<<