samcarter
I'm working on a [peyote stitch](https://en.wikipedia.org/wiki/Peyote_stitch) pattern, in which I can input the colours of the beads either row-wise or column-wise (I don't mind, which one it is).
I hacked together the following document to show the desired result, but I'm wondering if there are any simpler ways, thus I thought to post it here for a code review.
```
\documentclass{article}
\usepackage{xcolor}
\usepackage{graphicx}
\newcounter{col}
\setlength{\fboxsep}{0cm}
\newcommand{\bead}[2]{%
\fcolorbox{black}{#1}{\makebox[0.5cm]{\raisebox{0.02cm}{\rotatebox[origin=c]{270}{#2}}}\rule{0cm}{0.25cm}}%
}
\renewcommand{\a}{\bead{lightgray}{1}}
\renewcommand{\b}{\bead{gray}{2}}
\renewcommand{\c}{\bead{darkgray}{3}}
\renewcommand{\\}{%
\newline%
\addtocounter{col}{1}%
\ifodd\value{col}
\hspace*{0.125cm}%
\fi
}
\begin{document}
\footnotesize\sffamily\noindent%
\a\a\b\b\b\b\c\c\c\c\a\a\\
\a\b\b\b\b\a\c\c\c\c\a\a\\
\a\b\b\b\b\a\a\c\c\c\c\a\\
\b\b\b\b\a\a\a\c\c\c\c\a\\
\c\c\c\c\a\a\a\a\b\b\b\b\\
\c\c\c\c\a\a\a\b\b\b\b\a\\
\a\c\c\c\c\a\a\b\b\b\b\a\\
\a\c\c\c\c\a\b\b\b\b\a\a\\
\a\a\b\b\b\b\c\c\c\c\a\a\\
\a\b\b\b\b\a\c\c\c\c\a\a\\
\a\b\b\b\b\a\a\c\c\c\c\a\\
\b\b\b\b\a\a\a\c\c\c\c\a\\
\c\c\c\c\a\a\a\a\b\b\b\b\\
\c\c\c\c\a\a\a\b\b\b\b\a\\
\a\c\c\c\c\a\a\b\b\b\b\a\\
\end{document}
```
![document.png](/image?hash=060ca586eeaac2956937c1df6d4ece5ef24d65f5eb2e1487308848ed12c1be1c)
Boundary conditions:
- it would be nice, if I could just input `aabbcc...` or `112233` without having to type all the `\`.
- this is a standalone document with no other content then the stitch pattern. There won't be any harm done from messing with catcodes etc.
- something like 10 different colours is enough, the solution does not need to scale to an arbitrary number of colours
Top Answer
Skillmon
Sorry, this is not really a code review, more a complete different approach. The following uses `pxpic` for the parsing step and outputs boxes instead of pixels (with the right size).
It supports horizontally and vertically ragged patterns, input is always row wise (because that's how `pxpic` works). The horizontally ragged patterns use some knowledge about the internals of `pxpic` (I think I described them in the documentation, but am not sure).
```
\documentclass[]{article}
\usepackage{xcolor}
\usepackage{expkv-def}
\usepackage{pxpic}
\makeatletter
\newcommand*\peyote@vcentre
{\raisebox{.5\dimexpr\pxpicHT-2\fboxrule+\depth-\height\relax}}
% inject keys
\ekvdefinekeys{peyote}
{%
protected choice start =
{
still =
\let\peyote@raise\peyote@down
\let\peyote@kern\peyote@left
,move =
\let\peyote@raise\peyote@up
\let\peyote@kern\peyote@right
}
,protected choice ragged =
{
horizontal = \def\peyote@move{\peyote@kern}%
,vertical = \def\peyote@move{\peyote@raise}%
}
,bool showcentre = \ifpeyote@showcentre
}
\ekvdefunknown{pxpic}{\ekvset{peyote}{#2={#1}}}
\ekvdefunknownNoVal{pxpic}{\ekvset{peyote}{#1}}
% movements, in reality we only move up or right, the rest is not moved
\protected\def\peyote@down#1%
{%
\let\peyote@raise\peyote@up
\hbox{#1}%
}
\protected\def\peyote@up#1%
{%
\aftergroup\let\aftergroup\peyote@up\aftergroup\peyote@smashedup
\let\peyote@raise\peyote@down
\raise.5\dimexpr\pxpicHT-\pxpic@kern\relax\hbox{#1}%
}
\protected\def\peyote@smashedup#1%
{%
\let\peyote@raise\peyote@down
\smash{\raise.5\dimexpr\pxpicHT-\pxpic@kern\relax\hbox{#1}}%
}
\protected\def\peyote@left#1%
{%
% affect the next line (the \aftergroup escapes the \hbox of this line)
\aftergroup\let\aftergroup\peyote@kern\aftergroup\peyote@right
\let\peyote@move\peyote@still
\hbox{#1}%
}
\protected\def\peyote@right#1%
{%
% affect the next line (the \aftergroup escapes the \hbox of this line)
\aftergroup\let\aftergroup\peyote@kern\aftergroup\peyote@left
\let\peyote@move\peyote@still
\kern.5\dimexpr\pxpicWD-\pxpic@kern\relax\hbox{#1}%
}
\protected\def\peyote@still#1{\hbox{#1}}
% initial directions
\let\peyote@raise\peyote@down
\let\peyote@kern\peyote@left
% boxing things up, I'm pretty sure this is overly complicated...
\protected\def\peyote@box#1%
{%
\fboxsep=\z@
\fcolorbox{black}{peyote #1}
{%
\makebox[\dimexpr\pxpicWD-2\fboxrule][c]{\smash{\peyote@vcentre{#1}}}%
\rule\z@{\dimexpr\pxpicHT-2\fboxrule\relax}%
\peyote@showcentre
}%
}
\protected\def\peyote@showcentre
{%
\ifpeyote@showcentre
\smash
{%
\llap
{%
\makebox[\dimexpr\pxpicWD-2\fboxrule][c]
{\textcolor{red}{\peyote@vcentre{\rule{.4pt}{3.5ex}}}}%
}%
\llap
{%
\makebox[\dimexpr\pxpicWD-2\fboxrule][c]
{\peyote@vcentre{\textcolor{red}{\rule{3.5ex}{.4pt}}}}%
}%
}%
\fi
}
\pxpicnewmode{peyote}{\peyote@move{\peyote@box{#1}}}
% user interface
% colour definition supports both \colorlet and \definecolor, if the colour
% model is given as an optional argument
\newcommand\peyotecolor[1]
{%
\ekvoptargTF
{\definecolor{peyote #1}}%
{\colorlet{peyote #1}}%
}
% we don't touch internals of \pxpic, but expandably grabbing the optional
% argument doesn't kill the direct expansion to a \hbox of \pxpic
\newcommand*\peyote{\ekvoptarg\peyote@{}}
\newcommand\peyote@[1]{\pxpic[{mode=peyote,wd=2.5ex,ht=2.5ex,gap-hack=-.2ex,#1}]}
\makeatother
% specify the colours
\peyotecolor{1}[gray]{0.9}% <- definecolor syntax
\peyotecolor{2}{gray}% <- colorlet syntax
\peyotecolor{3}[gray]{0.3}
\begin{document}
\peyote[start=still,ragged=vertical,showcentre]
{
{11112111111121111}
{11332221113322211}
{33332222333322222}
{33332222333322222}
{33331222333312222}
{33111112331111122}
{21111111211111113}
{22211133222111333}
{22223333222233333}
{22223333222233333}
{12223333122233331}
{11123311111233111}
}
\peyote[start=move,ragged=horizontal,showcentre]
{
{113333222211}
{113333122221}
{133331122221}
{133331112222}
{222211113333}
{122221113333}
{122221133331}
{112222133331}
{113333222211}
{113333122221}
{133331122221}
{133331112222}
{222211113333}
{122221113333}
{122221133331}
{112222133331}
{112222333311}
}
\end{document}
```
Results (without `showcentre`):
![peyote.png](/image?hash=5407f74cf0a90f6283c3bedd45f03cb07ab4170bf7e7dfb2689b36bcfd25d63d)