\NeedsTeXFormat{LaTeX2e} \ProvidesPackage{byrne}[2022/01/06 Byrne] \RequirePackage{xparse} \RequirePackage{ifmtarg} \RequirePackage{luamplib} % version v2.22.0 is required \mplibsetformat{metafun} \mplibglobaltextext{enable} \newcount\mpInst \mpInst = 0 \def\mpPre{} \def\mpPost{} \newif\ifCreateNewInstanceForPicture \CreateNewInstanceForPicturetrue \def\undefineList{} \directlua{ function byFormatImageName(s) local resultingName = s:gsub ("," , "") tex.print("instanceOffspringPicture"..resultingName) end } \def\formatImageName#1{\directlua{byFormatImageName("#1")}} \DeclareDocumentCommand{\defineNewPicture}{o o m}{% \IfNoValueTF{#1}% {\global\def\sfA{1/3}}% {\global\def\sfA{#1}}% \IfNoValueTF{#2}% {\global\def\sfB{defaultScaleFactor}}% {\global\def\sfB{#2}}% \undefineList% \def\undefineList{}% \ifCreateNewInstanceForPicture% \global\advance \mpInst by 1% \global\def\currentInstance{byInstance\the\mpInst}% \fi% \setbox0\vbox{% \everymplib[\currentInstance]{beginfig(0);}% \everyendmplib[\currentInstance]{endfig;}% \begin{mplibcode}[\currentInstance]% picture instanceMainPicture; input byrne; \mpPre instanceMainPicture := image( startMainPictureMode; projectionAngle := (0, 0, 0); linecap := butt; scaleFactor := \sfB; #3 scaleFactor := \sfA; generateAngleSynonyms; generateLineSynonyms; stopMainPictureMode; ); \mpPost \end{mplibcode}% }\global\addToUndefineList{#2}% } \def\drawImageFromCurrentInstance#1{ \begin{mplibcode}[\currentInstance]% draw #1; \end{mplibcode}% } % Every time some simple picture is drawn, new macro is defined % with \markPictAsReady. If macro is defined, predefined picture is used. % Every time new picture is added, instructions to undefine it are added with % \addToUndefineList. \undefineList is thus generated command, that, once executed, % undefines everything that was appended to it with \addToUndefineList. \def\unmarkPictAsReady#1{\expandafter\let\csname #1\endcsname\@undefined} \def\addToUndefineList#1{\expandafter\def\expandafter\undefineList\expandafter{\undefineList \unmarkPictAsReady{#1}}} \def\undefineList{} \addToUndefineList{lastPicture} % When larger picture is defined, we can visualize its parts with \drawFromCurrentPicture % First (optional) argument is for picture's vertical alignment relative to the string % Currently only `middle' and anything other (for `top') is working % Second (optional) argument is for picture's name for future reuse % If picture with the same name exists, it's not defined again. % Third argument is MP code for picture itself. % To actually define an inline picture \defineFromCurrentPicture is called. % The latter can also be called separately, which can be convenient % if one wants to define multiple inline pictures in one place. % Whenever everything is defined, \drawDefinedPicture macro is called for \def\defineFromCurrentPicture#1#2#3{% \begin{mplibcode}[\currentInstance]% picture \formatImageName{#2}; \formatImageName{#2} = image( startOffspringPictureMode; linecap := butt; #3 stopOffspringPictureMode; ); \end{mplibcode}% \global\def\lastPict{#2}% \global\expandafter\edef\csname\lastPict\endcsname{{\noexpand\drawDefinedPicture{\expandafter\lastPict}{\expandafter#1}}}} \DeclareDocumentCommand{\drawFromCurrentPicture}{o o m}{% \IfNoValueTF{#1}% {\global\def\currentInlinePicturePlacement{middle}}% {\global\def\currentInlinePicturePlacement{#1}}% \IfNoValueTF{#2}% {\defineFromCurrentPicture{\currentInlinePicturePlacement}{lastPicture}{#3}}% {\expandafter\ifx\csname #2\endcsname\relax% \defineFromCurrentPicture{\currentInlinePicturePlacement}{#2}{#3}% \global\addToUndefineList{#2}% \else% \global\def\lastPict{#2}% \fi}% \csname\lastPict\endcsname% } % \drawDefinedPicture draws defined and named picture, aligned as needed and, % possibly, with margins modified with \offsetPicture (i. e., if we want picture to act as if it's less tall that it actually is, % we put some value as its first argument, if we want picture to be less deep, we use second argument, and place picture % itself as third). \newdimen\pictOffsetTop \newdimen\pictOffsetBottom \pictOffsetTop=0pt \pictOffsetBottom=0pt \def\offsetPicture#1#2#3{{\pictOffsetTop=#1\pictOffsetBottom=#2#3\pictOffsetTop=0pt\pictOffsetBottom=0pt}} \newdimen\midht \newdimen\middp \def\drawDefinedPicture#1#2{% \setbox0\vbox{\drawImageFromCurrentInstance{\formatImageName{#1}}}% \ifdim\ht0<\baselineskip\advance\pictOffsetTop by 1pt\advance\pictOffsetBottom by 1pt\fi% \setbox0\vbox{\vskip2pt\vskip-\pictOffsetTop\box0\vskip2pt\vskip-\pictOffsetBottom}% \def\tmpmiddle{middle}% \def\tmpalignment{#2}% \ifx\tmpalignment\tmpmiddle% \middp=0.5\ht0 \midht=0.5\ht0 \advance\middp by -3pt \advance\midht by 3pt \else% \middp=0pt \midht=\ht0 \advance\middp by 3pt \advance\midht by -3pt \fi% \advance\middp by 0.5\pictOffsetTop \advance\midht by -0.5\pictOffsetTop \advance\middp by -0.5\pictOffsetBottom \advance\midht by 0.5\pictOffsetBottom \dp0=\middp \ht0=\midht \nobreak\hskip0pt\nobreak\,\nobreak\box0\,% } % Some convenient shorthand macros for commonly used derivations of definition picture are defined below \def\drawCurrentPicture{\drawImageFromCurrentInstance{instanceMainPicture}} \DeclareDocumentCommand{\drawUnitLine}{o m}{% \IfNoValueTF{#1}% {\drawFromCurrentPicture[middle][uline#2]{startAutoLabeling;draw byNamedCompoundLine(1cm, 0)(#2);stopAutoLabeling;}}% {\drawFromCurrentPicture[middle][uline#2#1]{startAutoLabeling;draw byNamedCompoundLine(#1, 0)(#2);stopAutoLabeling;}}% } \def\drawProportionalLine#1{\drawFromCurrentPicture[middle][pline#1]{startAutoLabeling;draw byNamedCompoundLine(1cm, 1)(#1);stopAutoLabeling;}} \DeclareDocumentCommand{\drawSizedLine}{o m}{% \IfNoValueTF{#1}% {\drawFromCurrentPicture[middle][sline#2]{startAutoLabeling;draw byNamedCompoundLine(2cm, 2)(#2);stopAutoLabeling;}}% {\drawFromCurrentPicture[middle][sline#2#1]{startAutoLabeling;draw byNamedCompoundLine(#1, 2)(#2);stopAutoLabeling;}}% } \DeclareDocumentCommand{\drawUnitRay}{o m}{% \IfNoValueTF{#1}% {\drawFromCurrentPicture[middle][uray#2]{startAutoLabeling;draw byNamedCompoundRay(1cm, 0)(#2);stopAutoLabeling;}}% {\drawFromCurrentPicture[middle][uray#2#1]{startAutoLabeling;draw byNamedCompoundRay(#1, 0)(#2);stopAutoLabeling;}}% } \def\drawProportionalRay#1{\drawFromCurrentPicture[middle][pray#1]{startAutoLabeling;draw byNamedCompoundRay(1cm, 1)(#1);stopAutoLabeling;}} \DeclareDocumentCommand{\drawSizedRay}{o m}{% \IfNoValueTF{#1}% {\drawFromCurrentPicture[middle][sray#2]{startAutoLabeling;draw byNamedCompoundRay(2cm, 2)(#2);stopAutoLabeling;}}% {\drawFromCurrentPicture[middle][sray#2#1]{startAutoLabeling;draw byNamedCompoundRay(#1, 2)(#2);stopAutoLabeling;}}% } \def\drawProportionalIndLine#1{\drawFromCurrentPicture[middle][lineindprop#1]{startAutoLabeling;draw byNamedCompoundIndLine(1cm, 1)(#1);stopAutoLabeling;}} \DeclareDocumentCommand{\drawUnitIndLine}{o m}{% \IfNoValueTF{#1}% {\drawFromCurrentPicture[middle][lineindsized#2]{startAutoLabeling;draw byNamedCompoundIndLine(2cm, 2)(#2);stopAutoLabeling;}}% {\drawFromCurrentPicture[middle][lineindsized#2#1]{startAutoLabeling;draw byNamedCompoundIndLine(#1, 2)(#2);stopAutoLabeling;}}% } \def\drawRightAngle{% \drawFromCurrentPicture[middle][onerightangle]{draw rightAngle;}} \def\drawTwoRightAngles{% \drawFromCurrentPicture[middle][tworightangles]{draw twoRightAngles;}} \def\drawAngle#1{\drawFromCurrentPicture[middle][angle#1]{startAutoLabeling;draw byNamedAngleWithDummySides(#1);stopAutoLabeling;}} \def\drawAngleWithSides#1{\drawFromCurrentPicture[middle][anglewithsides#1]{startAutoLabeling;draw byNamedAngleSides(#1)();stopAutoLabeling;}} \DeclareDocumentCommand{\drawPolygon}{o o m}{% \IfNoValueTF{#1}% {\global\def\plal{middle}}% {\global\def\plal{#1}}% \IfNoValueTF{#2}% {\drawFromCurrentPicture[\plal][polygon#3]{startAutoLabeling;draw byNamedPolygon(#3);stopAutoLabeling;}}% {\drawFromCurrentPicture[\plal][#2]{startAutoLabeling;draw byNamedPolygon(#3);stopAutoLabeling;}}% } \DeclareDocumentCommand{\drawCircle}{o o m}{% \IfNoValueTF{#1}% {\global\def\plal{middle}}% {\global\def\plal{#1}}% \IfNoValueTF{#2}% {\drawFromCurrentPicture[\plal][circle#3]{startAutoLabeling;draw byNamedCircle(#3);stopAutoLabeling;}}% {\drawFromCurrentPicture[\plal][circle#3]{ startAutoLabeling; startTempScale(#2); draw byNamedCircle(#3); stopTempScale; stopAutoLabeling; }}% } \DeclareDocumentCommand{\drawArc}{o o m}{% \IfNoValueTF{#1}% {\global\def\plal{middle}}% {\global\def\plal{#1}}% \IfNoValueTF{#2}% {\drawFromCurrentPicture[\plal][arc#3]{startAutoLabeling;draw byNamedArc(#3);stopAutoLabeling;}}% {\drawFromCurrentPicture[\plal][arc#3]{ startAutoLabeling; startTempScale(#2); draw byNamedArc(#3); stopTempScale; stopAutoLabeling; }}% } \DeclareDocumentCommand{\drawLine}{o o m}{% \IfNoValueTF{#1}% {\global\def\plal{middle}}% {\global\def\plal{#1}}% \IfNoValueTF{#2}% {\drawFromCurrentPicture[\plal][line#3]{startAutoLabeling;draw byNamedLineSeq(0)(#3);stopAutoLabeling;}}% {\drawFromCurrentPicture[\plal][#2]{startAutoLabeling;draw byNamedLineSeq(0)(#3);stopAutoLabeling;}}% } \def\drawPointM#1{\drawFromCurrentPicture[middle][pointm#1]{startAutoLabeling; draw byNamedPointMark(#1); stopAutoLabeling;}} \DeclareDocumentCommand{\drawPointL}{o o m}{% \IfNoValueTF{#1}% {\global\def\plal{middle}}% {\global\def\plal{#1}}% \IfNoValueTF{#2}% {\drawFromCurrentPicture[\plal][pointl#3]{startAutoLabeling; draw byNamedPointLines(#3,""); stopAutoLabeling;}}% {\drawFromCurrentPicture[\plal][pointl#3Minus#2]{startAutoLabeling; draw byNamedPointLines(#3,"#2"); stopAutoLabeling;}}% } \DeclareDocumentCommand{\drawPoint}{o o m}{% \IfNoValueTF{#1}% {\global\def\plal{middle}}% {\global\def\plal{#1}}% \IfNoValueTF{#2}% {\drawFromCurrentPicture[\plal][point#3]{ startAutoLabeling; draw byNamedPointLines(#3,""); stopAutoLabeling; draw byNamedPointMark(#3); }}% {\drawFromCurrentPicture[\plal][point#3Minus#2]{ startAutoLabeling; draw byNamedPointLines(#3,"#2"); stopAutoLabeling; draw byNamedPointMark(#3); }}% } \DeclareDocumentCommand{\drawMagnitude}{o o m}{% \IfNoValueTF{#1}% {\global\def\plal{middle}}% {\global\def\plal{#1}}% \IfNoValueTF{#2}% {\drawFromCurrentPicture[\plal][magnitude#3]{startAutoLabeling;draw byNamedMagnitude(0)(#3);stopAutoLabeling;}}% {\drawFromCurrentPicture[\plal][magnitude#2#3]{startAutoLabeling;draw byNamedMagnitude(#2)(#3);stopAutoLabeling;}}% }