1

How is it possible to insert a Ornaments with Tikz in ConTeXt Mk IV? For example, in the manual of ornaments package, at p. 12:

\begin{tikzpicture} % to be changed in \starttikzpicture
\foreach \a in {0,45,...,315}
\node[anchor=west,rotate=\a,inner sep=0pt] {%
\pgfornament[width=1cm]{88}};
\end{tikzpicture} % to be changed in \stopttikzpicture

The problem is that \pgfornament[width=1cm]{88}}; it is not recognized as command.

If it is not possible to solve the problem, do you know if there is the source code of these ornaments, which from what I understand were made with Tikz?

Thank you

1
  • 2
    pgfornaments is a latex package which does not support ConTeXt. Looking at the code, it looks that it should be easy to write it in a generic manner, but I don't understand the internals of PGF well. Perhaps @HenriMenke could comment on that. – Aditya Oct 13 '20 at 3:39
2

A sketchy attempt to port pgfornament from pgfornament.sty to ConTeXt (t-pgfornament.mkiv). It works (for now) both in ConTeXt Mark IV and ConTeXt LMTX:

%Suggestion
%Save this in /texmf-modules/tex/context/third/pgfornament/t-pgfornament.mkiv
\startmodule[pgfornament]
\setupmodule[object=vectorian]
\writestatus{pgfornament}{2020/05/26 v1.2 vector ornaments}
\usemodule[tikz]
\let\typeout\writestring
\edef\pgfornamentcurrentobject{\currentmoduleparameter{object}}
\def\makeatletter{\catcode`\@=11}
\def\makeatother{\catcode`\@=12}
\gdef\pgfOrnamentsObject{pgflibraryvectorian.code.tex} 
\gdef\OrnamentsFamily{vectorian}  
\pgfkeys{%
  /pgfOrnaments/object/.cd,
  /pgfOrnaments/object/.code = \gdef\pgfOrnamentsObject{pgflibrary#1.code.tex}
                               \gdef\OrnamentsFamily{#1}%
}
\pgfkeys{/pgfOrnaments/object=\pgfornamentcurrentobject}
\input{\pgfOrnamentsObject}%
\makeatletter 
\def\startnewfamily{\dosingleempty\dostartnewfamily}
\def\dostartnewfamily[#1]{%
\global\let\SavedOrnamentsFamily\OrnamentsFamily
\iffirstargument 
\newpgfornamentfamily{#1}
\else
\newpgfornamentfamily{vectorian}
\fi
}
\def\stopnewfamily{\newpgfornamentfamily{\SavedOrnamentsFamily}}%

\def\pgf@@ornament#1{%
\begingroup
\def\ubb{\pgfusepath{use as bounding box}}
\def\i{\pgfusepath{clip}}%
\def\k{\pgfusepath{stroke}}%
\let\o\pgfpathclose
\let\s\pgfusepathqfillstroke
\def\p ##1##2{\pgfqpoint{##1bp}{##2bp}}%
\def\m ##1 ##2 {\pgfpathmoveto{\p{##1}{##2}}}%
\def\l ##1 ##2 {\pgfpathlineto{\p{##1}{##2}}}%
\def\r ##1 ##2 ##3 ##4 {\pgfpathrectangle{\p{##1}{##2}}{\p{##3}{##4}}}%
\def\c ##1 ##2 ##3 ##4 ##5 ##6 {%
\pgfpathcurveto{\p{##1}{##2}}{\p{##3}{##4}}{\p{##5}{##6}}}%
\input \OrnamentsFamily#1.pgf%
\endgroup}%  

\def\callornament#1{%
\begingroup
\def\ubb{\pgfusepath{use as bounding box}}
\def\i{\pgfusepath{clip}}%
\let\o\pgfpathclose
\let\s\pgfusepathqfillstroke
\def\p ##1##2{\pgfqpoint{##1bp}{##2bp}}%
\def\m ##1 ##2 {\pgfpathmoveto{\p{##1}{##2}}}%
\def\l ##1 ##2 {\pgfpathlineto{\p{##1}{##2}}}%
\def\r ##1 ##2 ##3 ##4 {\pgfpathrectangle{\p{##1}{##2}}{%
                       \p{##3}{##4}}}%
\def\c ##1 ##2 ##3 ##4 ##5 ##6 {%
\pgfpathcurveto{\p{##1}{##2}}{\p{##3}{##4}}{\p{##5}{##6}}}%
\input #1\relax
\endgroup}
\tikzset{pgfornamentstyle/.style={}}%  
\pgfkeys{%
  /ornament/.cd,
  scale/.code         =  {\def\pgfornamentscale{#1}},
  width/.code         =  {\def\pgfornamentwidth{#1}},
  height/.code        =  {\def\pgfornamentheight{#1}},
  color/.code         =  {\def\pgfornamentcolor{#1}},
  opacity/.code       =  {\def\pgfornamentopacity{#1}},
  anchor/.code        =  {\def\pgfornamentanchor{#1}},
  ydelta/.code        =  {\def\pgfornamentydelta{#1}}, 
  symmetry/.is choice,
  symmetry/v/.code     = {\tikzset{pgfornamentstyle/.append  
     style={cm={-1,0,0,1,(0,0)}}}},
  symmetry/c/.code     = {\tikzset{pgfornamentstyle/.append 
     style={cm={-1,0,0,-1,(0,0)}}}},
  symmetry/h/.code     = {\tikzset{pgfornamentstyle/.append 
     style={cm={1,0,0,-1,(0,0)}}}},
  symmetry/none/.code  = {\tikzset{pgfornamentstyle/.append style={cm={1,0,0,1,(0,0)}}}}%
}%
\def\pgfornament{\pgfutil@ifnextchar[{\pgf@ornament}{\pgf@ornament[]}}%
\def\pgf@ornament[#1]#2{%
\pgfkeys{%
  /ornament/.cd,
   scale    =  1,
   opacity  =  {},
   width    =  {},
   height   =  {},
   color    =  {},
   ydelta   =  0 pt,
   symmetry =  none ,
   anchor   =  center
   }% 
\pgfqkeys{/ornament}{#1}%
\ifx\pgfornamentcolor\empty 
    \tikzset{pgfornamentstyle/.append style={}}%
\else 
    \tikzset{pgfornamentstyle/.append style={color=\pgfornamentcolor}}%
\fi
\ifx\pgfornamentopacity\empty 
    \tikzset{pgfornamentstyle/.append style={}}%
\else 
    \tikzset{pgfornamentstyle/.append style={opacity=\pgfornamentopacity}}%
\fi
\ifx\pgfornamentwidth\empty
   \else
   \@pgfornamentDim{#2}
   \pgfmathsetmacro{\pgfornamentscale}{\pgfornamentwidth/\@pgfornamentX bp}%
\fi  
\ifx\pgfornamentheight\empty
   \else
    \@pgfornamentDim{#2}
    \pgfmathsetmacro{\pgfornamentscale}{\pgfornamentheight/\@pgfornamentY bp}%
\fi
\starttikzpicture[%
baseline={([yshift=\pgfornamentydelta]current bounding box.\pgfornamentanchor)},
   pgfornamentstyle]
   \pgftransformscale{\pgfornamentscale}%
   \pgf@@ornament{#2}%
\stoptikzpicture%
\tikzset{pgfornamentstyle/.style={cm={1,0,0,1,(0,0)}}}
}

\gdef\ornamenttopos{.5}
\gdef\ornamenttoanchor{center}
\gdef\ornamenttosymmetry{none} 
\tikzset{options default/.style={anchor=center,
                                 sloped,
                                 allow upside down,
                                 inner sep=0pt}}
\tikzset{ornament/at/.code={\def\ornamenttopos{#1}},
         options/.style={options default,#1},
         ornament symmetry/.code={\def\ornamenttosymmetry{#1}},
         node anchor/.code={\def\ornamenttoanchor{#1}}, 
         ornament/.style={%
         to path={%
\pgfextra{%
      \tikz@scan@one@point\pgfutil@firstofone(\tikztostart)\relax
         \pgf@xa=\pgf@x
         \pgf@ya=\pgf@y 
      \tikz@scan@one@point\pgfutil@firstofone(\tikztotarget)\relax
         \pgf@xb=\pgf@x
         \pgf@yb=\pgf@y
         \advance\pgf@xa by-\pgf@xb
         \advance\pgf@ya by-\pgf@yb
      \pgfmathveclen{\pgf@xa}{\pgf@ya}%
      \global\let\ornamentlen\pgfmathresult} 
       --  node [pos=\ornamenttopos,options,
              anchor=\ornamenttoanchor]{%
        \pgfornament[width    = \ornamentlen,
                 symmetry=\ornamenttosymmetry]{#1}}  
            (\tikztotarget)\tikztonodes   
    }
  }
}

\def\pgfornamenthline#1#2#3#4{%
  \pgfextractx{\pgf@x}{\pgfpointanchor{#1}{#3 east}}
  \pgf@xa=\pgf@x 
  \pgfextractx{\pgf@x}{\pgfpointanchor{#2}{#3 west}} 
  \pgf@xb=\pgf@x
  \advance\pgf@xb by -\pgf@xa
\node[inner sep=0pt] at ($(#1.#3 east)!.5!(#2.#3 west)$) {\pgfornament[width=\pgf@xb]{#4}} ;  
}
\def\pgfornamentvline#1#2#3#4{%
  \pgfextracty{\pgf@y}{\pgfpointanchor{#1}{south #3}}
  \pgf@ya=\pgf@y 
  \pgfextracty{\pgf@y}{\pgfpointanchor{#2}{north #3}} 
  \pgf@yb=\pgf@y
  \advance\pgf@yb by -\pgf@ya
\node[inner sep=0pt,rotate=90] at ($(#1.south #3)!.5!(#2.north #3)$) {\pgfornament[width=\pgf@yb]{#4}} ;  
}%
\def\getornamentlength#1#2#3#4{%
 \pgfpointdiff{\pgfpointanchor{#1}{#2}}%
              {\pgfpointanchor{#3}{#4}}%
   \pgf@xa=\pgf@x
   \pgf@ya=\pgf@y
   \pgfmathveclen{\pgf@xa}{\pgf@ya}%
   \global\let\ornamentlen\pgfmathresult 
}%
\def\getornamentangle#1#2#3{%
  \pgfpointdiff{\pgfpointanchor{#2}{center}}{\pgfpointanchor{#3}{center}}%
  \pgfmathsetmacro{#1}{atan2(\pgf@x,\pgf@y)}%
}%
\makeatother
\def\resetpgfornamentstyle{\tikzset{pgfornamentstyle/.style={}}}

\def\newpgfornamentfamily#1{%
  \edef\OrnamentsFamily{#1}
  \gdef\pgfOrnamentsObject{pgflibrary\OrnamentsFamily.code.tex}
  \input{\pgfOrnamentsObject}%
  }%

\makeatletter
\pgfkeys{/ornamentline/.cd,
         color/.store in                 = \ornamentcolor,
         color                           = black,
  /ornamentline/.search also={/tikz}}
\def\pgfornamentline{\pgfutil@ifnextchar[{\pgf@ornamentline}{\pgf@ornamentline[]}}%
\def\pgf@ornamentline[#1]#2#3#4#5{%

\pgfqkeys{/ornamentline}{#1}%
\pgfmathsetmacro\nbo{#4}
\path (#2) -- (#3) foreach \i in {0,...,\nbo} {coordinate[pos=\i/\nbo] (p\i)}
 [color=\ornamentcolor] foreach \i [count=\j]  in {0,...,\number\numexpr\nbo-1} { (p\i)  to [ornament=#5]   (p\j)};
}
\makeatother
\stopmodule
\endinput

And some tests

\usecolors[svg] %nice colors
\usemodule[tikz]
\usetikzlibrary[chains]
\usemodule[pgfornament][object=vectorian]
\startTEXpage 

\newpgfornamentfamily{pgfhan}
\pgfornament[width = 2cm, color = darkgreen]{59}
\newpgfornamentfamily{vectorian}
\pgfornament[width = 2cm, color = darkgreen]{59}

\startnewfamily[pgfhan]
    \starttikzpicture
    \node{ \pgfornament[color=gold,width=2cm]{1}};
    \stoptikzpicture
\stopnewfamily

\starttikzpicture[start chain=circle placed {at=(\tikzchaincount*30:2)}]
\foreach \i in {1,...,12} \node [on chain]%
{\pgfornament[width=1cm]{4}};
\stoptikzpicture

\stopTEXpage

enter image description here

I wait for feedback as I seldom use TikZ (except for tikzducks)

4
  • Great, man! I'll let you know as soon as possible. Thank you! – user225612 Oct 25 '20 at 6:26
  • @Zezzo I forgot to add: 1) in TeX Live is texmf-dist instead of texmf-modules and 2) you have to do mtxrun --generate and then context --make so ConTeXt finds your module. :) – Jairo A. del Rio Oct 25 '20 at 6:40
  • Hi, I have a problem. So, I created a .mkiv file in TeXworks. I copy-paste the code you wrote me. But I didn't understand which folder to put it in. – user225612 Oct 25 '20 at 9:45
  • @Zezzo In such a case, just put it in the same folder as your main file. It should work without additional steps. – Jairo A. del Rio Oct 25 '20 at 9:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy