% Florian Sihler, 2022 % Licensed under GNU General Public License version 3 % https://opensource.org/licenses/gpl-3.0.html \errorcontextlines9999 \documentclass[parskip=half,english,numbers=noenddot,footnotes=nomultiple,oneside]{scrartcl} \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage{babel} \usepackage{marginnote} \makeatletter \def\input@path{{../tex/}} \usepackage[glows]{tikzpingus} % \definecolor{doc-main}{RGB}{204,0,25} \colorlet{doc-main}{pingu@blue!65!pingu@black} \colorlet{@opcolor}{doc-main!70!pingu@black} \usepackage[linkcolor=@opcolor,urlcolor=@opcolor,colorlinks,breaklinks,pdfusetitle]{hyperref} \usetikzlibrary{shapes.misc,arrows.meta} \urlstyle{same} \expandafter\def\expandafter\UrlBreaks\expandafter{\UrlBreaks\do-} \usepackage[hyper]{listings} \usepackage[skins,breakable,hooks,xparse,listingsutf8,external]{tcolorbox} \usepackage{lmodern} \usepackage{CrimsonPro} \usepackage{imakeidx} \usepackage{tikz} \usepackage{fontawesome} \usepackage{csquotes} \usepackage{enumitem} \usepackage{microtype} \usepackage{tikzducks} \usepackage{datatool} \usepackage{multicol} \usepackage{footnotebackref} \usepackage{adjustbox} \usepackage{xstring} \usepackage{colorinfo} \makeindex[title={Key Overview},name=\jobname,columns=2,columnsep=.75cm,noautomatic=true,intoc] \def\indexinternalsoverviewname{Internals Overview} \makeindex[title={\indexinternalsoverviewname},name=\jobname-internals,columns=2,columnsep=.75cm,noautomatic=true,intoc] \def\current@indexfile{\jobname} \deffootnote{1.5em}{1em}{\textsuperscript{\hyperref[\BackrefFootnoteTag]{\thefootnotemark}}\thinspace} \def\thefootnote{$\langle$\arabic{footnote}$\rangle$} % https://tex.stackexchange.com/questions/78423/how-to-use-the-footnotebackref-package-with-footnotemark-and-footnotetext \LetLtxMacro\BHFN@Old@footnotemark\@footnotemark \def\@footnotemark{% \refstepcounter{BackrefHyperFootnoteCounter}% \xdef\BackrefFootnoteTag{bhfn:\theBackrefHyperFootnoteCounter}% \label{\BackrefFootnoteTag}% \BHFN@Old@footnotemark } \newlist{inlist}{enumerate*}{1} \setlist[inlist]{itemjoin={{, }},itemjoin*={{, and }},label=$\roman*$),mode=boxed} \def\MapDTLList#1{\ifcsname ListnameOf#1\endcsname\csname ListnameOf#1\endcsname\else#1\fi} \def\ListnameOflefteye{eyes} \def\ListnameOfbodytype{body type} \let\say\enquote \def\DTLlistformatoxford{,}\def\DTLandname{and} % TODO: do guard against same keys for different selectors \long\def\ParseDTLListElement#1"#2"\@nil{\textsuperscript{\smash{\raisebox{2pt}{\ifcsname pingu@@lib@#2@\CurrentList @\endcsname\index[\current@indexfile]{Libraries!\textit{\csname pingu@@lib@#2@\CurrentList @\endcsname}!#2?\hyperref[expl-list:\CurrentList]{\protect\lpingu{#2} {\tiny\sffamily(\MapDTLList{\CurrentList})}}}~$\underset{\text{\tiny\smash{\raisebox{3pt}{\textsf{\hyperref[Libraries]{\@declaredcolor{gray}Library}}}}}}{\text{\textit{\tiny\strut\csname pingu@@lib@#2@\CurrentList @\endcsname}}}$\fi}}}} \def\DTLlistformatitem#1{\textit{#1\expandafter\ParseDTLListElement :#1\@nil}} \newcommand*\typesetselection[1][]{\begingroup\ifx!#1!\else\def\DTLlistformatitem##1{#1}\fi\dotypesetselection} \def\dotypesetselection#1{\label{expl-list:#1}\def\CurrentList{#1}\expandafter\DTLformatlist\expandafter{\csname @pingu@#1@\endcsname}\endgroup} % this can be used to remove some prefixes of the keys if necessary \let\@gobblekey\@gobble \addtokomafont{sectioning}{\@declaredcolor{black}} \addtokomafont{title}{\@declaredcolor{@opcolor}} \addtokomafont{author}{\normalsize} \addtokomafont{date}{\normalsize} \colorlet{@softgray}{gray!60!white} \colorlet{@softgray@b}{gray!75!white} \colorlet{@darkerblue}{pingu@blue!40!black} \def\optstyle{\@declaredcolor{@opcolor}\slshape} \def\cmdstyle{\@declaredcolor{@darkerblue}} \def\nostyle{\@declaredcolor{black}} \let\lstfnsize\small \lstdefinestyle{lstpingu}{% tabsize=2, breaklines, basicstyle=\lstfnsize\ttfamily, commentstyle={\@declaredcolor{gray}\slshape}, columns=fullflexible, emphstyle=\slshape, emphstyle=[2]\optstyle, emphstyle=[3]\@declaredcolor{@softgray@b}, emphstyle=[4]\@declaredcolor{@darkerblue}, lineskip=2.5pt, keepspaces=true, moredelim=[s][\itshape]{<}{>}, } \lstset{style=lstpingu} \def\ipingu#1{\lstinline'#1'} \def\lpingu#1{\lstinline[style=lstpingu,language=pingulang]'#1'} \def\ltex#1{\lstinline[style=lstpingu,language=pinguinternallang]'#1'} \def\doccmd#1{{\@declaredcolor{doc-main}\bfseries\textbackslash #1}} \def\graycmd#1{{\@declaredcolor{gray}\bfseries\textbackslash #1}} \def\ghostcmd#1{{\@declaredcolor{@softgray}\textbackslash #1}} \lstdefinelanguage{pinguinternallang}{ language={[LaTeX]TeX}, moreemph={tikzpicture}, alsoletter={@}, add to literate= {\\pingu@block}{{\doccmd{pingu@block}}}{12} {\\pingu@draw}{{\doccmd{pingu@draw}}}{11} {\\@pingu@none}{{\graycmd{@pingu@none}}}{11} {\\path}{{\graycmd{path}}}5 {\\coordinate}{{\graycmd{coordinate}}}5 {\\definecolor}{{\doccmd{definecolor}}}{12} {\\pgfqkeys}{{\graycmd{pgfqkeys}}}9 {\\@ifnextchar}{{\graycmd{@ifnextchar}}}9 {\\csname}{{\graycmd{csname}}}6 {\\endcsname}{{\graycmd{endcsname}}}9 {/pingu/}{{\@declaredcolor{@softgray}/pingu/}}7 } \def\t@lst@addToLiterate#1{\protected@edef\lst@literate{\unexpanded\expandafter{\lst@literate}\unexpanded{#1}}} \lst@Key{add to literate}{}{\t@lst@addToLiterate{#1}} \let\lst@ifxliterate\iftrue % make literate a star literate \lstdefinelanguage{pingulang}{ language={[LaTeX]TeX}, moreemph={tikzpicture}, alsoletter={.-!:0123456789},%disable number deletetexcs={begin,end}, % -> lift 3 moreemph=[3]{!hide,.style,xshift,yshift}, add to literate={/pingu/}{{\@declaredcolor{gray}/pingu/}}7 {\{tikzpicture\}}{{\@declaredcolor{@softgray}\{tikzpicture\}}}{13} {\{\\number\\pdfrandomseed\}}{{\@declaredcolor{@softgray}\{\textbackslash number\textbackslash pdfrandomseed\}}}{23} % otherwise these would interfere with random {!random}{{\@declaredcolor{darkgray}\itshape!random}}7 {\\node}{{\doccmd{node}}}5 {\\duck}{{\doccmd{duck}}}5 {\\begin}{{\ghostcmd{begin}}}6 {\\end}{{\ghostcmd{end}}}4 {\\tikz}{{\ghostcmd{tikz}}}5 {\\pgfmathsetseed}{{\ghostcmd{pgfmathsetseed}}}{15} } \def\@CreateCodeHyperLink#1#2#3#4#5{\lstset{add to literate={#2}{{\hyperref[#3]{#5#4}}}{#1}}} % #1 Keys | #2 length (optimized) \def\CreateCodeHyperLink#1#2{% \StrLen{\@elem}[\@cclen] \@for\@elem:=#1\do{\ifx\@elem\@empty\else % space to space cmd % TODO: do this on store and just keep store? \StrSubstitute{\@elem}{ }{\noexpand\ }[\@sub]\relax \let\hyperstyle\optstyle \IfBeginWith{\@sub}{_}{% update hypersyle \let\hyperstyle\cmdstyle \StrSubstitute{\@sub}{_}{\\}[\@sub]% \StrSubstitute{\@sub}{\\}{\textbackslash}[\@subb]% deal with backslash }{% \IfBeginWith{\@sub}{+}{% update blockstyle \let\hyperstyle\nostyle \StrDel{\@sub}{+}[\@sub]% }{}% \let\@subb\@sub }% \edef\@tmp{\noexpand\@CreateCodeHyperLink{#2}{\@sub}{pk:/pingu/\@elem}{\@subb}{\expandonce{\hyperstyle}}}\@tmp\fi}% } % store all. we use their precalculated length to ensure prefixes we go from small to large on set \def\cmdsstore#1#2{\csxdef{allcmds@#1}{#2}} \def\allcmdsmin{3}% think \def\allcmdsmax{3}% \AtEndDocument{% \pgfkeys{/pingu/.cd,defaults}% this way we have active defaults \foreach \i in {\allcmdsmin,...,\allcmdsmax} {% \immediate\write\@auxout{\noexpand\cmdsstore{\i}{\csuse{allcmds@\i}}}% }% \immediate\write\@auxout{% \noexpand\gdef\noexpand\allcmdsmin{\allcmdsmin}% \noexpand\gdef\noexpand\allcmdsmax{\allcmdsmax}% \noexpand\gdef\noexpand\pengu@all@showcases{\pengu@all@showcases}% }% } \def\RawShowcase#1#2{\scalebox{.68}{%\begin{tcbexternal}{showcase-#2#1}% \tikzpicture[baseline={(pingu-bottom-center)}] \pingu[:mix=30!white,name=pingu,#1#2] \pgfonlayer{foreground} \node[below=3mm] at(pingu-bottom-center) {\strut}; % buffer \pgfinterruptboundingbox \node[below=3mm,fill=white,fill opacity=.52,text opacity=1,rounded corners=3pt] at(pingu-bottom-center) {\textsf{\strut\smash{#1}}}; \endpgfinterruptboundingbox \endpgfonlayer \endtikzpicture %\end{tcbexternal}% }} \setbox0=\hbox{\RawShowcase{}{}} \newdimen\pingu@showcase@height \pingu@showcase@height=\dimexpr\ht0+\dp0\relax \def\ShowcasePengu#1=#2;{{\hypersetup{linkcolor=.}% \hyperref[pk:/pingu/#1]{% \parbox[b][\pingu@showcase@height]{.14\linewidth}{\centering\ifx!#2!\def\Arg{}\else\def\Arg{=#2}\fi\edef\MakeShowcase{\noexpand\RawShowcase{#1}{\Arg}}~\clap{\MakeShowcase}~}% }}} \def\pengu@all@showcases{} % we mix them somewhat funny \def\@showcase@pre{pre} \let\@showcase@cur\@showcase@pre \def\@toggle@showcase{\ifx\@showcase@cur\@showcase@pre\global\let\@showcase@cur\@empty\else \global\let\@showcase@cur\@showcase@pre\fi} \newcommand\ShowcaseThis[2][]{\ifx\@showcase@cur\@showcase@pre \global\let\@showcase@cur\@empty\expandafter\gpreto\else \global\let\@showcase@cur\@showcase@pre\expandafter\gappto\fi\pengu@all@showcases{{#2=#1},}} \RedeclareSectionCommand[runin=false,afterskip=-2mm]{section} \RedeclareSectionCommand[runin=false,afterskip=-2mm]{subsection} \RedeclareSectionCommand[runin=false,beforeskip=2mm,afterskip=-2mm]{subsubsection} \tcbset{% colframe=gray,enhanced,breakable, arc=2mm, fonttitle=\bfseries, sidebyside, boxrule=.35mm,listing options={style=lstpingu,language=pingulang}, center lower,segmentation at break=false, righthand width=4.75cm, bottom=0pt, top=0pt,boxsep=2.25pt, before lower app={}, colback=white } \lstMakeShortInline[style=lstpingu,language=pingulang,basicstyle=\small\ttfamily\@declaredcolor{black!90!white},moredelim={[s][\itshape]{<}{>}}]{|} \def\explaincolor{@opcolor!9!white} \def\cursub{} \def\keyexplainindent{2.5em}% \let\@explainsuff\@empty \let\@labelhack\@empty \def\@append@key{\protected@csxappto{allcmds@\@cclen}{\@key,}% % update the range \ifnum\@cclen>\allcmdsmax\relax \xdef\allcmdsmax{\@cclen}\fi \ifnum\@cclen<\allcmdsmin\relax \xdef\allcmdsmin{\@cclen}\fi} % allow the oxes to have minor overlaps \newcommand\DefineKey[2][/pingu/]{% \StrSubstitute{#2}{ }{-}[\keyexternalname]% % only use _ to keep the length intact when replace with the backslash \StrSubstitute{\keyexternalname}{\\}{_}[\keyexternalname]% {\def\\{_}\protected@xdef\@key{#2}}% {\def\\{}\protected@xdef\@idxkey{#2}\@gobblekey{\@idxkey}}% backslash should not interfere with keys \tcbset{@/.style={externalize listing=key-\keyexternalname}}% set for externalize \phantomsection\label{pk:#1\@labelhack\@key}\index[\current@indexfile]{\cursub\@idxkey?\hyperref[pk:#1\@key]{\protect\lpingu{#2}}}% % get its length: \StrLen{#2}[\@cclen]% \@append@key } % prevent something from get a highlight \newcommand\BlockString[2][/pingu/]{% {\def\\{_}\protected@xdef\@key{+#2}}% % no index \phantomsection\label{pk:#1\@labelhack\@key}% % get its length: \StrLen{#2}[\@cclen]% % now, remove prefix it with a char which marks block: \edef\@cclen{\the\numexpr\@cclen-1\relax} \@append@key } \newenvironment{keyexplain}[4][/pingu/]{\minipage{\linewidth} \parskip\smallskipamount \DefineKey[#1]{#2}% \expandafter\gdef\csname pinguopt\@key\endcsname{#3}% \expandafter\gdef\csname pingudefa\@key\endcsname{#4}% \begingroup\pgfkeys{/pingu/.cd,defaults}\protected@edef\@tmp{#4}% \protected@edef\@tmpb{#3}% \hspace*{-\keyexplainindent}\tcbox[left=3pt,right=3pt,top=3pt,bottom=3pt,colframe=white,colback=\explaincolor,on line]{% \parbox{\dimexpr\linewidth-2\fboxsep+\keyexplainindent}{\small \ifx\@tmpb\@empty\lpingu{#1#2}\@explainsuff\else\lpingu{#1#2 =\ }\texttt{<\textit{\@tmpb}>}\fi\hfill \ifx\@tmp\@empty\else{\@declaredcolor{gray}(}#4{\@declaredcolor{gray})}\fi } }\ifcsname pingu@@lib@\@key @\endcsname\index[\current@indexfile]{Libraries!\textit{\csname pingu@@lib@#2@\endcsname}!\@idxkey?\hyperref[pk:#1\@key]{\protect\lpingu{#2}}}\rlap{~\quad\raisebox{2.75pt}{$\underset{\text{\tiny\smash{\raisebox{3pt}{\textsf{\hyperref[Libraries]{\@declaredcolor{gray}Library}}}}}}{\text{\textit{\footnotesize\parbox{4em}{\null\hfill\strut\csname pingu@@lib@#2@\endcsname\hfill\null}}}}$}}\fi\kern-\linewidth\par\endgroup } {\endminipage\smallskip\par} \def\singleshortcut#1#2"#3"#4{\def\cursub{#2?\hyperref[pk:#1#2]{\protect\lpingu{#2}}!}\keyexplain[#1]{#2 #3}{\csname pinguopt#4\endcsname}{\csname pingudefa#4\endcsname}% \textcolor{gray}{\small This is a shortcut for: \texttt{\keyref[#1]{#2}{\small\ =\ {\optstyle#3}}}. The \enquote{\texttt{\textit{\csname pinguopt#4\endcsname}}} argument is passed to \keyref[#1]{#4}.} \endkeyexplain} \newcommand*\shortcuts[4][/pingu/]{\begingroup \protected@edef\@tmp{#3}% \def\explaincolor{@softexplaincolor}% \foreach \type in \@tmp {% \edef\tmp{\noexpand\singleshortcut{#1}{#2}\type{#4}}\tmp }\endgroup} \newcommand*\keyref[2][/pingu/]{\hyperref[pk:#1#2]{\lpingu{#1#2}}} \newcommand*\dkeyref[2][/pingu/]{\hyperref[pk:#1#2]{\lpingu{#2}}} \newcommand*\cmdref[1]{\hyperref[pk:/pingu/:bs:#1]{\lpingu{\\#1}}} \newcommand*\cmddef[1]{\DefineKey{\\#1}\cmdref{#1}\nobreak} % master-cmd | cmd \newif\ifsubcmddefprint \newcommand*\subcmddef{\@ifstar{\subcmddefprintfalse\@subcmddef}{\subcmddefprinttrue\@subcmddef}} \def\@subcmddef#1#2{\begingroup {\def\\{}\protected@xdef\@subidxkey{#1}\@gobblekey{\@subidxkey}}%% backslash should not interfere with keys \def\cursub{\@subidxkey?\hyperref[pk:/pingu/_\@subidxkey]{\protect\lpingu{\\#1}}!}% \ifsubcmddefprint\cmddef{#2}\else\DefineKey{\\#2}\fi% \endgroup} \newcommand*\cmdcoldef[1]{\cmddef{pingu@color@#1}} \newcommand*\cmd[1]{\texttt{\small\doccmd{#1}}} \colorlet{@softexplaincolor}{gray!8!white} \def\pingu@nokeyindent{0pt} \def\pingu@softexplaincolor{@softexplaincolor} \newenvironment{subkeyexplain}[5][/pingu/]{% \begingroup \let\explaincolor\pingu@softexplaincolor\let\keyexplainindent\pingu@nokeyindent% \def\cursub{#2?\hyperref[pk:#1#2]{\protect\lpingu{#2}}!}% \keyexplain[#1]{#3}{#4}{#5}% {\@declaredcolor{gray}\footnotesize This command is only in effect if \keyref[#1]{#2} is active.}\par }{\endkeyexplain\endgroup} \newenvironment{commandexplain}[3][]{% \begingroup \def\@labelhack{/pingu/}% \def\mand##1{\texttt{\{\textsf{\small##1}\}}}% \def\@pingu@command@keypartner{#1}% % #1 is the default \newcommand\opt[2][]{\texttt{\textit{[\textsf{\small##2\ifx!##1!\else\textcolor{gray}{\small\sffamily=##1}\fi}]}}}% \def\@explainsuff{#3}% \keyexplain[]{\\#2}{}{}% \ifx\@pingu@command@keypartner\@empty\else {\@declaredcolor{gray}\footnotesize Do \textbf{not} redefine this command, it is controlled by \keyref{#1}.}\par\fi }{\endkeyexplain\endgroup} \newenvironment{subcommandexplain}[4][]{% \begingroup \def\explaincolor{@softexplaincolor}\def\keyexplainindent{0em}% {\def\\{}\protected@xdef\@subidxkey{#2}\@gobblekey{\@subidxkey}}%% backslash should not interfere with keys \def\cursub{\@subidxkey?\hyperref[pk:_\@subidxkey]{\protect\lpingu{\\#2}}!}% \commandexplain[#1]{#3}{#4}% {\@declaredcolor{gray}\footnotesize This command is only usable in combination with \cmdref{#2}.}\par }{\endcommandexplain\endgroup} \def\consumeshowkeyexplain#1(#2){\ShowcaseThis[#2]{#1}} \newenvironment{showkeyexplain}[4][/pingu/]{% \keyexplain[#1]{#2}{#3}{#4}% \@ifnextchar({\consumeshowkeyexplain{#2}}{\consumeshowkeyexplain{#2}()} }{\endkeyexplain} \newcommand\keyalias[3][/pingu/]{\begingroup \def\explaincolor{@softexplaincolor}\def\keyexplainindent{0em}% \def\cursub{#3?\hyperref[pk:#1#3]{\protect\lpingu{#3}}!}% \keyexplain[#1]{#2}{\csname pinguopt#3\endcsname}{\csname pingudefa#3\endcsname}% {\@declaredcolor{gray}\small This is an alias for \keyref[#1]{#3}.}% \endkeyexplain\endgroup} \newcommand\subkeyalias[4][/pingu/]{\begingroup \def\explaincolor{@softexplaincolor}\def\keyexplainindent{0em}% \def\cursub{#4?\hyperref[pk:#1#4]{\protect\lpingu{#4}}!#3?\hyperref[pk:#1#3]{\protect\lpingu{#3}}!}% \keyexplain[#1]{#2}{\csname pinguopt#3\endcsname}{\csname pingudefa#3\endcsname}% {\@declaredcolor{gray}\small This is an alias for \keyref[#1]{#3}.}% \endkeyexplain\endgroup} \def\lib#1{\tikz[baseline=-.6ex]\node[draw=teal,fill=teal!3!white,very thick,rounded corners=2pt,inner ysep=0pt]{\sffamily\strut#1};} \def\TikZ{Ti\textit{k}Z} \def\tikzpingus{\TikZ pingus} \tcbset{external/prefix=sub_} \tcbEXTERNALIZE % we do not need the other configurations in the externalized images :D \hfuzz=25pt % this should not happen in the external images \AtBeginDocument{% % we do not use foreach to avoid groups \count@=\allcmdsmin \edef\@cntmax@{\the\numexpr\allcmdsmax+1\relax}% \@whilenum\count@<\@cntmax@\do{% \edef\i{\number\count@}\relax \ifcsname allcmds@\i\endcsname \edef\allcmds{\csname allcmds@\i\endcsname}% if undefined => empty \expandafter\CreateCodeHyperLink\expandafter{\allcmds}{\i}% \csxdef{allcmds@\i}{}% \fi% csx kill to stop infinite \global\advance\count@\@ne }% } \def\TypesetShowcases{\@tempcnta\z@ \begingroup\parskip\z@ \parindent\z@ \@for\@elem:=\pengu@all@showcases\do{% \advance\@tempcnta\@ne \ifnum\@tempcnta>5 \global\@tempcnta\@ne\par\fi \ifx\@elem\@empty\else % space to space cmd \edef\@tmp{\noexpand\ShowcasePengu\@elem;}\hfill\@tmp\hfill \fi}% \endgroup\global\let\pengu@all@showcases\@empty} \def\PenguinTitle{% \setbox0=\hbox{\tikz{\pingu[body type=tilt-right,eyes wink,conical hat,cane right,bow tie=pingu@purple,left wing grab,cup=doc-main]}}% \begin{tikzpicture}[overlay,remember picture] \node[below left=1.5cm,rotate=-10] at (current page.north east) {\box0}; \end{tikzpicture}% } \title{The \texorpdfstring{\tikzpingus}{tikzpingus} package} % \subtitle{Penguins with \TikZ} \author{% \texorpdfstring{Florian Sihler\\* \url{https://github.com/EagleoutIce/tikzpingus} }{Florian Sihler}} \date{Version v1.1 \textendash{} 2023/09/17} \begin{document} \maketitle \PenguinTitle \begingroup \vspace*{-4em}\newsavebox\pinguboxA \savebox\pinguboxA{\tikz{\pingu[wings raise,santa hat,eyes wink,bow tie=pingu@yellow]}} \newsavebox\pinguboxB \savebox\pinguboxB{\tikz{\pingu[wings raise,head band,eyes angry,sunglasses,bow tie=doc-main,body type=chubby]}} \begin{center} \begin{tikzpicture} \node[text width=.95\linewidth, inner sep=11pt] (m) {% For my slides at university, I started to use the famous \LaTeX-package \textsl{\href{https://github.com/samcarter/tikzducks}{tikzducks}} a few years ago. Yet, it seemed somewhat of a necessity to extend the range of available \say{cute} animals in \LaTeX. Therefore I started writing this package: \textsl{tikzpingus}.\footnotemark\medskip\\ \textit{Please note:} While tikzpingus is certainly inspired by tikzducks, it does offer a different set of features (e.g., multiple wing positions,~\ldots).\medskip\\ I would be happy for any feedback or issues on the \href{https://github.com/EagleoutIce/tikzpingus}{tikzpingus}-GitHub. }; \pgfonlayer{background} \node[below,xshift=1.1cm,yshift=19.5pt,scale=.4] at(m.south west) {\usebox\pinguboxA}; \node[below,xshift=-1cm,yshift=13.5pt,scale=.4] at(m.south east) {\usebox\pinguboxB}; \draw[rounded corners,gray,fill=white] (m.north west) -- (m.north east) -- (m.south east) -- ++(-.45cm,0) to[bend right=40] ++(-1.2cm,0) -- ([xshift=1.65cm]m.south west) to[bend right=40] ++(-1.2cm,0) -- ++(-.45cm,0) -- cycle; \endpgfonlayer \node[above=3mm,font=\bfseries\sffamily\Large] at(current bounding box.north) {Motivation}; \end{tikzpicture}\vspace*{-\baselineskip} \end{center} \footnotetext{Why \say{pingu} and not \say{pengu}? Well, this is the third try on achieving cute penguins without using any templates or vector formats as a basis. As a German, the short form \say{pingu} was merely a typo that originated from the German word \say{pinguin} for \say{penguin}. It somewhat stuck\ldots} \endgroup\vfill \begin{center} \newsavebox\pinguA \newsavebox\pinguB \newsavebox\pinguC \newsavebox\pinguD \newsavebox\pinguE \newsavebox\pinguF \newsavebox\pinguG \def\Table#1(#2)#3{\scope[shift={(#2)},xshift=1.75cm,yshift=1.75cm]\pingu[#1]\endscope\pgfonlayer{foreground}\draw[lightgray,line width=6pt,rounded corners=2pt,line cap=round](#2) |- ++(4.5,1.35) -- ++(0,-1.35);\fill[draw=lightgray,fill=white,line width=3pt,rounded corners=2pt] (#2)++(3pt-1.5pt,-3pt+1.5pt+2mm) rectangle ++(1.15,1.15) node[midway,centered]{\Large$\mathsf{#3}$};\endpgfonlayer}% \setbox\pinguA=\hbox{\tikz{\pingu[santa hat,santa beard,eyes vertical,blush]}}% \setbox\pinguB=\hbox{\tikz{\pingu[:back,right wing wave,rook=pingu@silver!80!white,rook hatch=false]}}% \resizebox*!{4.5cm}{\begin{tikzpicture} \Table{right wing wave,horse right,crown, eyes wink, crown position={1:(-.1cm,-.255cm){1.33}}}(2.5,3.5){\text{\sffamily f}(x)} \Table{right wing wave,eyes wink,shirt=gray,tie,blush}(0,0)+ \Table{right wing wave,eyes vertical,cloak=gray,body type=legacy,cup,left wing grab,blush}(5,0)* \Table{right wing wave,left wing shock,eyes shock,halo,heart=gray!40!pingu@white}(-2.5,-4)\div \Table{right wing wave,cake-hat,eyes wink,flag right}(2.5,-4)\ln \pgfonlayer{foreground} \node[scale=.125,circle,fill=white] at (a) {\rotatebox{13}{\copy\pinguA}}; % a sets flag core \endpgfonlayer \Table{right wing wave,vr-headset,vr-headset hair}(7.5,-4)\bmod \pgfonlayer{foreground} \node[scale=2] at([yshift=-3.45cm]current bounding box.south) {\copy\pinguB}; \endpgfonlayer \end{tikzpicture}}\hskip6em% % todo: regroup that \setbox\pinguA=\hbox{\tikz{% \pingu[wings wave,name=pingu,eyes wink,body type=legacy,eye patch right] \draw[line cap=round,lightgray,line width=1.5pt] (pingu-wing-right-tip) circle[radius=2mm]; \draw[line cap=round,lightgray,line width=1.5pt] (pingu-head-back-con-left) circle[radius=3mm]; \draw[line cap=round,lightgray,line width=1.5pt] (pingu-waist-right) circle[radius=4mm]; \draw[line cap=round,lightgray,line width=1.5pt] (pingu-foot-left) circle[radius=3.5mm]; \draw[line cap=round,lightgray,line width=1.5pt] (pingu-head) circle[radius=2.5mm]; \draw[line cap=round,-Kite,lightgray,line width=1.5pt] ([xshift=1mm,yshift=-1mm]pingu-wing-left-tip) to[bend left] ++(3mm,-1cm); \draw[line cap=round,Kite-Kite,lightgray,line width=1.5pt] ([xshift=4mm]pingu-foot-left) -- ++(1cm,0); \draw[line cap=round,Kite-Kite,lightgray,line width=1.5pt] ([yshift=-1.75cm]pingu-head-top)++(60:1.75cm and 2cm) arc(60:120:1.75cm and 2cm); }}% \newsavebox\whitepingu \setbox\whitepingu=\hbox{\tikz{\pingu[@block/.style={fill=pingu@white,draw=pingu@white},wings wave]}} \setbox\pinguB=\hbox{\rlap{\kern2.8pt\box\whitepingu}\tikz{ \pingu[wings wave,:line,name=pingu] \path[line width=1.5pt] (pingu-wing-right-tip) circle[radius=2mm]; }}% \setbox\pinguC=\hbox{\tikz{\pingu[eyes shiny,hat, hat position={1:(0cm,-.09cm){1.33}}]}}% \setbox\pinguD=\hbox{\tikz{\pingu[eyes shiny,lightsaber right=pingu@purple,hat, hat position={1:(0cm,-.09cm){1.33}},right item angle=-13,medal]}}% \setbox\pinguE=\hbox{\tikz{\pingu[eyes shiny,hat,cane left, hat position={1:(0cm,-.09cm){1.33}},left item angle=-13,tie,tie dots]}}% \setbox\pinguF=\hbox{\tikz{\pingu[eyes shiny,hat,cane left, hat position={1:(0cm,-.09cm){1.33}},left item angle=-13,shirt=gray,second shirt,bill=flat,tie,tie dots]}}% \setbox\pinguG=\hbox{\tikz{\pingu}} \resizebox*!{4.5cm}{\begin{tikzpicture} \node[scale=2] (a) at(0,0) {\copy\pinguA}; \node[above=1.5cm,scale=2] at(a.north) {\small\copy\pinguB}; \node[right] (x) at(7.5,8) {\copy\pinguC}; \node[below right=1cm](e) at(x.south) {\copy\pinguE}; \node[below left=1cm] (d) at(x.south) {\copy\pinguD}; \node[below=1cm] (f) at(e.south) {\copy\pinguF}; \node[above left=1cm] (g) at(x.north) {\copy\pinguG}; \draw[lightgray,line width=3pt,{Triangle[round,open,fill=white,scale=1.42]}-] (g) -- (x); \draw[lightgray,line width=3pt,{Triangle[round,open,fill=white,scale=1.42]}-] (x) -- (e); \draw[lightgray,line width=3pt,{Triangle[round,open,fill=white,scale=1.42]}-] (x) -- (d); \draw[lightgray,line width=3pt,{Triangle[round,open,fill=white,scale=1.42]}-] (e) -- (f); \end{tikzpicture}} \end{center} \vfill\null \clearpage \tableofcontents \clearpage \section{Introduction} \subsection{Dependencies} As this package is constantly work in progress, the concrete dependencies may change any time. At the moment, it loads \href{https://www.ctan.org/pkg/pgf}{\TikZ}, which loads a lot of other packages (e.g.\ \href{https://www.ctan.org/pkg/xcolor}{xcolor}), and \href{https://www.ctan.org/pkg/etoolbox}{etoolbox}. Furthermore, the following \TikZ-Libraries are in use:\footnote{A lot of the libraries loaded are important only for specific extras. I plan on cleaning them up.} \textit{intersections}, \textit{shadings}, \textit{patterns.meta}, \textit{decorations.pathmorphing}, and \textit{shapes.symbols}. \subsection{Copyright} Copyright \textcopyright\ \textit{Florian Sihler}. Permission is granted to copy, distribute and\slash or modify this software under the terms of the GNU General Public License, version~3.0 (to be found online at: \url{https://opensource.org/licenses/gpl-3.0.html}).\\* The shown example penguins are purely fictional characters, any resemblance to real penguins or real persons is purely coincidental and no copyright infringement is intended. \section{Usage}\label{Usage} If you just want a penguin, import the package and start with the following: \begin{tcblisting}{title={One small penguin},externalize listing=small-pengu} \begin{tikzpicture} \pingu \end{tikzpicture} \end{tcblisting} There are \textit{a lot} of configuration-options which can be passed as an optional argument via the known |=|-style. See \autoref{Gadget-Overview} for a complete gadget overview. \begin{tcblisting}{title={Happy penguin with cup!},externalize listing=happy-cup} \begin{tikzpicture} \pingu[left wing wave, right wing grab, eyes shiny, cup] \end{tikzpicture} \end{tcblisting} Please note, that \say{left} and \say{right} have been chosen from the penguin-perspective. \begin{commandexplain}{pingu}{\opt{penguin keys}} The command to draw the penguin! \end{commandexplain} \clearpage Besides the keys defined by this package, you can use the keys of \TikZ\ and |pgf| as well (the duck was generated by the lovely \href{https://github.com/samcarter/tikzducks}{tikzducks} package): \begin{tcblisting}{title={The Reunion},externalize listing=pengu-duck} \begin{tikzpicture} \duck \pingu[xshift=2.7cm, yshift=14mm, eyes wink] \end{tikzpicture} \end{tcblisting} \subsection{Using the Coordinates} \label{mrk:coordinates}While there are a lot of gadgets available already, every penguin is accompanied by \textit{several} adaptive coordinates to place custom items, texts,~\ldots\ % TODO: links They can be visualized by the \keyref{meta-dots} option. Furthermore, some extras create further coordinates themselves! All coordinates are available with |-|. While the default name of a penguin is \say{pingu}, it can be changed with the name option: \begin{tcblisting}{title={Lotta dots},externalize listing=dotted-pengu} \begin{tikzpicture} \pingu[meta dots,left wing wave, right wing grab, name=paula] \node at (paula-belly-center) {X}; \node at (paula-foot-left) {Foot}; \end{tikzpicture} \end{tcblisting} \phantomsection\label{pingu-coordinates}Lets look at those coordinates in more detail (all labels are to be prefixed by |<|\keyref{name}|>-|): \newsavebox\pinguwingright \savebox\pinguwingright{% \begin{tikzpicture}% \scope \path[clip] (.25,-1.25) rectangle (-1.1,.7); \pgfonlayer{foreground}\path[clip] (.25,-1.25) rectangle (-1.1,.7);\endpgfonlayer \pingu[@block/.append style={fill=#1!35!white},wings hug,eyes shiny,heart=gray!30!white,feet=none] \path[draw,pink,thick] (pingu-wing-right-start) -- (pingu-wing-right); \endscope \foreach \c/\a/\n in {wing-right/left/.75mm,wing-right-low/left/.75mm,wing-right-up/above/.75mm,wing-right-start-low/below left/1.75mm,wing-right-start-up/above left/.75mm} { \path[fill=teal] (pingu-\c) circle [radius=1.125pt]; \node[\a=\n,font=\ttfamily,scale=.35,inner sep=2.5pt] (expl-\c) at (pingu-\c) {\c}; \draw[teal,thin] (expl-\c) -- (pingu-\c); } \end{tikzpicture}} \newsavebox\pinguwingleft \savebox\pinguwingleft{% \begin{tikzpicture}% \scope \path[clip] (\pingu@w@half*2-.25cm,-1.25) rectangle ++(1.25,1.95); \pgfonlayer{foreground}\path[clip] (\pingu@w@half*2-.25cm,-1.25) rectangle ++(1.25,1.95);\endpgfonlayer \pingu[@block/.append style={fill=#1!35!white}, wings wave,eyes shiny,heart=gray!30!white,feet=none] \path[draw,pink,thick] (pingu-wing-left-start) -- (pingu-wing-left); \endscope \foreach \c/\a/\n in {wing-left/right/.75mm,wing-left-low/below right/.75mm,wing-left-up/above/.75mm,wing-left-start-low/below right/1.25mm,wing-left-start-up/below right/1.5mm} { \path[fill=teal] (pingu-\c) circle [radius=1.125pt]; \node[\a=\n,font=\ttfamily,scale=.35,inner sep=1.5pt] (expl-\c) at (pingu-\c) {\c}; \draw[teal,thin] (expl-\c) -- (pingu-\c); } \end{tikzpicture}% } \vfill \def\PinguCoords#1{\begin{tikzpicture} \pingu[@block/.append style={fill=##1!35!white}, wings wave,eyes shiny,heart=gray!30!white,#1] \pgfonlayer{foreground} \foreach \c/\a in {belly-center/above,head/below,head-top/above,foot-left/right,foot-right/left,eye-right/above left,eye-left/above right,bill/right,bill-bottom/below,wings-side-left/right,wings-side-right/left,wing-left-start/below right,wing-left-tip/right,wing-right-start/below left,wing-right-tip/left,head-right/left,head-left/right,head-center/below,head-back-con-left/above right,head-back-con-right/above left,bottom-center/above,waist-left/right,waist-right/left} { \path[fill=green] (pingu-\c) circle [radius=1.125pt]; \node[\a=.5mm,font=\ttfamily,scale=.35,inner sep=1.5pt] (expl-\c) at (pingu-\c) {\c}; \draw[green,thin] (expl-\c) -- (pingu-\c); } \endpgfonlayer \end{tikzpicture}}% \begin{center} \edef\measurepage{\the\dimexpr\pagegoal-\pagetotal-2\baselineskip\relax}% \ifdim\measurepage<4\baselineskip\clearpage\edef\measurepage{\the\dimexpr\pagegoal-\pagetotal-2\baselineskip\relax}\fi \resizebox*!{\measurepage}{% \PinguCoords{}% } \end{center} \paragraph{The Wings} This view excluded a lot of special data collected on the wings! While there is more information stored for each wing, the following five coordinates are the most important to place items into penguins hand:\vspace*{-1.5em} \begin{center} \null\hfill\parbox[c]{2.5\wd\pinguwingright}{\scalebox{2.5}{\usebox\pinguwingright}}\hfill\parbox[c]{4cm}{\centering\small\@declaredcolor{gray}\sffamily And yes, the wings are deliberately placed asymmetrical.\endgraf}\hfill \parbox[c]{2.5\wd\pinguwingleft}{\scalebox{2.5}{\usebox\pinguwingleft}}\hfill\null \end{center} \paragraph{The Body} Similarly to the wing position, different body types can change the coordinates (left the \keyref{body type} \textit{chubby} and right the \keyref{body type} \textit{legacy}): \begin{center} \resizebox\linewidth!{% \PinguCoords{body type=chubby,wings hug}\quad\PinguCoords{body type=legacy,wings hug} } \end{center} \subsection{Colors} \label{Colors}A lot of options allow for a color to be passed. In general, you can provide any color that \TikZ\ is happy with! Yet, there are some predefined pingu-colors shipped with this package: \def\getCol#1{\pgfmathparse{int(round(#1*255))}\pgfmathresult} \def\parseRGB#1,#2,#3;{r:~\getCol{#1}, g:~\getCol{#2}, b:~\getCol{#3}} \begin{multicols}{4} \begin{itemize} \foreach \col in {main,black,silver,bronze,white,yellow,lightblue,blue,green,red,purple} { \item[{\tikz[baseline=-.6ex]{\fill[pingu@\col,semithick,draw=black] circle (4pt);}}] \footnotesize\strut % somehow outputs, therefore box \setbox0=\hbox{\colorInfoRGB{pingu@\col}\xdef\colorValue{\colorValue}}\rlap{\smash{\raisebox{-2.9mm}{\sffamily\@declaredcolor{gray}\tiny\expandafter\parseRGB\colorValue;}}}% \texttt{pingu@\col}% } \item[] \footnotesize\strut% buffer \end{itemize} \end{multicols} Furthermore, there is the special color \say{\expandafter\ipingu\expandafter{\@pingu@none}} (\cmdref{@pingu@none}) which is available for most\footnote{Why just \say{most}? Well, this package is work in progress and I have added the option late, so I may have forgotten to patch some keys.} extras and wing-items. This color prohibits the compartments from being drawn. To be more precise, the package defines the macro \ltex{\\@pingu@none}, which is matched against the selected color. As an example, lets take a look at the \keyref{cup}-extra, which provides an additional key \keyref{cup straw} to color the straw: \begin{tcblisting}{title={Cup without a straw},externalize listing=extra-options} \begin{tikzpicture} \pingu[wings grab, cup=pingu@purple, cup straw=pingu@blue] \pingu[wings grab, cup, xshift=2.7cm, cup straw=!hide] \end{tikzpicture} \end{tcblisting} As you can see, using \lpingu{!hide}, the straw will not be drawn. \subsection{Setting the defaults} You do not have to re-state every key. With \cmdref{pingudefaults} and \cmdref{pingudefaultsappend} (similar, but extends the current options) you can set default-options for all penguins to come: \begin{tcblisting}{title={Change the mainstream},externalize listing=update-defaults} \begin{tikzpicture} \pingudefaults{wings grab, eyes shiny} \pingu \pingu[left wing shock, xshift=2.7cm] \end{tikzpicture} \end{tcblisting} \begin{commandexplain}{pingudefaults}{\mand{penguin keys}} Sets the given \textit{penguin keys} as defaults for the local group. Overwrites any previews defaults (see \cmdref{pingudefaultsappend}). \end{commandexplain} \begin{commandexplain}{pingudefaultsappend}{\mand{penguin keys}} Appends the given \textit{penguin keys} as defaults for the local group. To overwrite these keys, see \cmdref{pingudefaults}. \end{commandexplain} \subsection{Libraries} \label{Libraries}\index{Libraries}I've split the penguin features into a set of libraries. While all of them are loaded by default, the |bare| package-option disables the automatic loading of all libraries. They can be loaded (locally to the current group) using \cmdref{pinguloadlibrary} and \cmdref{pinguloadlibraries} passing on a comma separated list of desired libraries. See the full reference or the index to learn which key comes from which library. Please note that~--- at the moment~--- not all components of a library are labeled correctly. % TODO: already count that? % global let? \foreach[count=\i] \l/\xs in \pingu@defaultlibs{\xdef\pingu@defaultlibs@count{\i}}% Currently there are the following libraries: \foreach[count=\i] \l/\xs in \pingu@defaultlibs{% \ifx\l\empty\else \index[\current@indexfile]{Libraries!\textit{\l}}\textit{\l}\ifnum\numexpr\pingu@defaultlibs@count-1>\i,\space\else \ifnum\pingu@defaultlibs@count=\i\else,~and\space\fi\fi \fi }. \begin{commandexplain}{pinguloadlibrary}{\mand{library}} Load a penguin library (actually, due to the implementation, you can use this command just like \cmdref{pinguloadlibraries} and load multiple libraries). \end{commandexplain} \begin{commandexplain}{pinguloadlibraries}{\mand{libraries}} Load multiple penguin libraries, separated by a comma. For example: \texttt{\cmdref{pinguloadlibraries}\{shirts, glasses\}}. \end{commandexplain} \subsection{Changing the wings} \label{subsec:wings}As already demonstrated, it is possible to change the wing positions! All selected wing-items will adapt to the wing-position (although not all wing-items will make sense with every wing-position). Currently, there are the following wing-positions: \typesetselection{leftwing}. \say{none} is a special wing-position: it omits the drawing of wings (teaser: every selection has a none-option, which prohibits the part from being drawn)! For each valid wing-position you can use |wings | to change both wings or |left wing | and |right wing | to change only one wing respectively. The default wing-position is \say{normal}. If you supply multiple options for a wing, only the last one survives.\footnote{For the sake of completeness: \ipingu{wings }, \ipingu{left wing }, and \ipingu{right wing } are just alternatives i prefer: \ipingu{wings=}, \ipingu{left wing=} and \ipingu{right wing=}.} This is shown in Box~\say{\nameref{wing-showcase}}. \begin{tcblisting}{sidebyside=false, title=Wing-Showcase,nameref=Wing-Showcase,externalize listing=wings-showcase,float,phantomlabel=wing-showcase} \begin{tikzpicture} \pingu[left wing none, heart=green] \pingu[wings wave, heart=teal, xshift=3.5cm] \pingu[wings hug, heart=orange, xshift=7cm] \pingu[left wing grab, right wing shock, heart=purple, xshift=10.5cm] \end{tikzpicture} \end{tcblisting} \subsection{Changing the eyes} \label{mrk:pengu-eye}Just like the wings, there are a couple of different eye-styles to choose from: \typesetselection{lefteye}. Similar to the wings, there is a \say{none} and a \say{normal}-option (which is the default). Furthermore, the convenient selectors |eyes