2

I need to create a table where each cell is 1em x 1em. The contents of each cell in the table will be a single glyph from a special Unicode font. Each glyph is 1.1em x 1.1em. There is intentional overlap of 0.05em on each side and top and bottom. That overlap should not be clipped and should be centered. The assembly of all of the cells is the diagram of a rational link (in Knot Theory).

I do not have a working example other than using the normal tabular environment (with special structs to force a minimum row height). However, this doesn't work well, and since the font is not (yet) available on CTAN no example I provide could be built in any case.

I am using LuaLaTeX (although XeLaTeX should also work).

Here is an example of what I am doing now. The Logix package includes the glyphs used for the custom font.

\documentclass[10pt]{article}

\usepackage{mathtools}
\usepackage{fontspec}
\usepackage{unicode-math}
\usepackage{lualatex-math}

\setmainfont{STIX Two Text}[NFSSFamily=mainfont]
\setmathfont{STIX Two Math}[NFSSFamily=mathfont]

\include{Logix}         % Custom font

\begin{document}

   \begin{center}
      \begin{tabular}{ @{} c @{} r @{} c @{} c @{} l @{} c @{} }
          \KntLTSC & \KntTSFN & \KntXSUSO & \KntTSN   & \KntRFC & \KntEnd \\[-0.60em]
          \KntLJSC & \KntLQC  &           & \KntXSOSU &         & \KntEnd \\[-0.60em]
          \KntLBSC & \KntBSFN & \KntXSUSO & \KntBSN   & \KntRFC & \KntEnd     
         \end{tabular}
      \end{center}

   \end{document}

And here is a picture of the output

This is a trefoil knot

Here is the code that I used for the parbox suggestion.

\documentclass[10pt]{article}

\usepackage{mathtools}
\usepackage{fontspec}
\usepackage{unicode-math}
\usepackage{lualatex-math}

\setmainfont{STIX Two Text}[NFSSFamily=mainfont]
\setmathfont{STIX Two Math}[NFSSFamily=mathfont]

\include{Logix}         % Custom font

\begin{document}

   \begin{center}
      \begin{tabular}{ @{} c @{} r @{} c @{} c @{} l @{} }
          \parbox[c][1em]{1em}{\KntLTSC} & \parbox[c][1em]{1em}{\KntTSN} & \parbox[c][1em]{1em}{\KntHXSUSO} & \parbox[c][1em]{1em}{\KntTSN}    & \parbox[c][1em]{1em}{\KntRCS} \\
          \parbox[c][1em]{1em}{\KntLSN}  & \parbox[c][1em]{1em}{\KntLCS} &                                  & \parbox[c][1em]{1em}{\KntHXSOSU} &                               \\
          \parbox[c][1em]{1em}{\KntBLSC} & \parbox[c][1em]{1em}{\KntBSN} & \parbox[c][1em]{1em}{\KntHXSUSO} & \parbox[c][1em]{1em}{\KntBSN}    & \parbox[c][1em]{1em}{\KntRCS}
         \end{tabular}
      \end{center}

  \bigskip

   \begin{center}
      \parbox[c][1em]{1em}{\KntLTSC} \parbox[c][1em]{1em}{\KntTSN} \parbox[c][1em]{1em}{\KntHXSUSO} \parbox[c][1em]{1em}{\KntTSN}    \parbox[c][1em]{1em}{\KntRCS} \\
      \parbox[c][1em]{1em}{\KntLSN}  \parbox[c][1em]{1em}{\KntLCS} \parbox[c][1em]{1em}{}           \parbox[c][1em]{1em}{\KntHXSOSU} \parbox[c][1em]{1em}{}        \\
      \parbox[c][1em]{1em}{\KntBLSC} \parbox[c][1em]{1em}{\KntBSN} \parbox[c][1em]{1em}{\KntHXSUSO} \parbox[c][1em]{1em}{\KntBSN}    \parbox[c][1em]{1em}{\KntRCS}
      \end{center}

   \end{document}

And here is the output

enter image description here

Vertical glue is being added in both versions. The table version does not appear to be adding horizontal glue, but is also not positioning the parboxes correctly.

  • I have added an example with associated picture. This is a very simple example, most of the time they are much more complex. Note that at this specific size the diagram looks ok, at different sizes that is not always true. The adjustment at the end of the lines sometimes has to be different. These tables are generated by a computer program, so fine tuning by hand is not desirable. And sometimes, no fixed hand tuning works well. There are currently nearly 100 glyphs for this, with another 100 under preparation. – Michael Lee Finney May 25 at 18:34
  • Have you looked into the tikz knots library? – Teepeemm May 25 at 20:23
  • Yes, I have. However, they don't do what I want and automating them is much more of a challenge. This approach works perfectly (barring the minor alignment problem) for the restricted classes of knots I am using. In any case, even if the tikz knots package would work, that doesn't solve this problem. – Michael Lee Finney May 25 at 21:57
  • You can use TikZ to absolutely position a glyph. You can adjust vertical spacing with the optional argument to "\\": "\\[-1ex]". And within a tabular, you can use \renewcommand{\arraystretch}{.8} instead. – Teepeemm Jun 3 at 1:33
  • You may not have noticed that in my original example that is how I am adjusting the vertical layout. The problem there is that different knots may need slightly different adjustments because what is being adjusted is both the interline spacing and the overflow outside the 1em x 1em box. Using a strut at the end of the line (\KntEnd) helps with that, but without suppressing the automatic adjustment, variations will still occur. Which is why I want exact boxes with allowed overlap that does not affect the typesetting. – Michael Lee Finney Jun 3 at 3:09
4

To answer your literal question, you can use parbox to create a box of the height and width that you want, and put anything inside. (See What are the different kinds of boxes in (La)TeX? for a nice discussion.) In your case, that would end up being something like

\parbox[c][1em]{1em}{\includegraphics[width=1.1em,height=1.1em]{example-image-a}}

To overdo things to show what happens,

\documentclass[varwidth,border={.5cm 1cm 1.5cm 1cm}]{standalone}
\usepackage{graphicx}
\begin{document}
\noindent
\parbox[c][3em]{3em}{\includegraphics[width=6em,height=6em]{example-image-a}}%
\parbox[c][3em]{3em}{\includegraphics[width=6em,height=6em]{example-image-b}}\\
\parbox[c][3em]{3em}{\includegraphics[width=6em,height=6em]{example-image-c}}%
\parbox[c][3em]{3em}{\includegraphics[width=6em,height=6em]{example-image-a}}
\bigskip
\end{document}

results in

overlapping parboxes

You may need to play with the distances a bit; if you look closely, there's a bit more cut off of the right than off of the bottom (you can see one of the midlines, but not the other).

But I'm still going to come back to the statement that there are better ways to get the output you want. With tikz knots,

\documentclass[varwidth,border=1cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{
  knots,
  decorations.pathreplacing,
  shapes.geometric,
%  calc,
}
\tikzset{
  knot diagram/every strand/.append style={
    ultra thick,
  },
  show curve controls/.style={
    postaction=decorate,
    decoration={show path construction,
      curveto code={
        \draw [blue, dashed]
        (\tikzinputsegmentfirst) -- (\tikzinputsegmentsupporta)
        node [at end, draw, solid, black, inner sep=2pt]{};
        \draw [blue, dashed]
        (\tikzinputsegmentsupportb) -- (\tikzinputsegmentlast)
        node [at start, draw, solid, black, inner sep=2pt]{}
        node [at end, fill, blue, ellipse, inner sep=2pt]{}
        ;
      }
    }
  },
  show curve endpoints/.style={
    postaction=decorate,
    decoration={show path construction,
      curveto code={
        \node [fill, blue, ellipse, inner sep=2pt] at (\tikzinputsegmentlast) {}
        ;
      }
    }
  }
}
\begin{document}
\begin{tikzpicture}
\begin{knot}[
  consider self intersections=true,
%  draft mode=crossings, % to see the crossing numbers
  ignore endpoint intersections=false,
  flip crossing/.list={6,7,14,15},
  only when rendering/.style={
%    show curve controls
  }
  ]
\strand (1,3)..controls
        (3,3)..(3.5,2.5)..controls
        (4,2)..(4.5,2)..controls
        (5,2)..(5.5,1.5)..controls
        (6,1)..(6.5,1)..controls
        (7,1)..(7,.5)..controls
        (7,0)..(6,0)..controls
        (4,0)..(3.5,.5)..controls
        (3,1)..(2.5,1)..controls
        (2,1)..(2,1.5)..controls
        (2,2)..(2.5,2)..controls
        (3,2)..(3.5,2.5)..controls
        (4,3)..(5.5,3)..controls
        (7,3)..(7,2.5)..controls
        (7,2)..(6.5,2)..controls
        (6,2)..(5.5,1.5)..controls
        (5,1)..(4.5,1)..controls
        (4,1)..(3.5,.5)..controls
        (3,0)..(1.5,0)..controls
        (0,0)..(0,1.5)..controls
        (0,3)..(1.5,3)..controls
        (1,3)..cycle;
\end{knot}
\end{tikzpicture}
\end{document}

seems easily programmable (except possibly which crossings to flip). TikZ measures from the bottom left, so that this starts with the top left horizontal segment and goes clockwise. This results in

tikz knots example

Another possibility is to use xypic.

\documentclass[varwidth,border=1cm]{standalone}
\usepackage[all]{xy}
\begin{document}
\xymatrix@-2ex{
&&\ar@{-} `r _dr"3,9" '"2,8" `^r"3,11" `_dr"5,13" `^r"5,15" `_d"7,15"
 `_l"7,9" `_ul"5,7" '"6,8" `^l"5,5" `_u"3,5" `_r"3,7"
 `^ur"1,9" `_r"1,15" `_d"3,15" `_l"3,13" `^dl"5,11" '"4,12"
 `_l"5,9" `^dl"7,7" `_l"7,3" `_u"3,1" `_r"1,4" "1,4"
&&&&&&&&&&&&\\
&&&&&&&&&&&&&&\\
&&&&&&&&&&&&&&\\
&&&&&&&&&&&&&&\\
&&&&&&&&&&&&&&\\
&&&&&&&&&&&&&&\\
&&&&&&&&&&&&&&
}
\end{document}

Results in

xypic example of a knot diagram

This last one may require some explanation. We have defined a matrix with 7 rows and 15 columns, tightened a bit by the @-2ex. From row 1 column 3, we

\ar % create an arrow
@{-} % that's really a line
`r  % going to the right before turning
_ % clockwise
dr % in the Down/Right direction toward
"3,9" % the entry at row 3 column 9
' % having passed under
"2,8" % the entry at row 2 column 8
` % and then turning
^ % in the counterclockwise direction
r % to go in the Right direction toward
"3,11" % the entry at row 3 column 11
...
` % and then turning
_ % in the clockwise direction
r % to go in the Right direction toward
"1,4" % the entry at row 1 column 4
"1,4" % stop at row 1 column 4

That ends up being a complicated expression, but it essentially draws the line as you would with a pencil, so it should be entirely programmable. (One annoyance is that the coordinates are vertical from the top and then horizontal. Another is that every entry needs to be a positive integer, unlike the TikZ approach.)

  • Excellent answer. +1. – Sebastiano May 30 at 20:17
  • Sorry that it took me a while to get back to you, I was in the middle of a major update. First, the graphics solutions are not of interest. This same approach using the same font will be used in HTML pages. There, I can position glyphs absolutely, so there is no problem. The issue is doing the same thing or at least something similar in LaTex. I tried the parbox suggestion and it does not work. I tried it in a table and in plain text as you did. Neither works. The table is slightly better. Due to limited comment length I will update the original question. – Michael Lee Finney Jun 2 at 23:57
  • I added some suggestions, but how to do them will probably depend on your font, and sounds difficult. With HTML, I would prefer to use svg to draw the diagram instead of trying to place glyphs. – Teepeemm Jun 3 at 1:35
1

The solution for this is to first make each of the glyphs have the same depth and height so that the height of a row is predictable. Then, remove all padding between rows. The following examples shows the solution which does not have the drawback of having to customize the row spacing adjustment for each row or for a change in font size.

\documentclass[10pt]{article}

\usepackage{unicode-math}

\setmainfont{STIX Two Text}
\setmathfont{STIX Two Math}

\usepackage{logix}
\usepackage{collectbox}

\newcommand  \fixdim[1] {\collectbox*{\setlength{\depth}{0.238em}\setlength{\height}{0.762em}}{#1}}

\begin{document}

   \begin{center}
      \renewcommand*{\arraystretch}{0}
      \begin{tabular}{ @{} c @{} }
          $ \fixdim{\KntLTSC} \fixdim{\KntTSN} \fixdim{\KntHXSUSO} \fixdim{\KntTSN}    \fixdim{\KntRCS}   $\\
          $ \fixdim{\KntLSN}  \fixdim{\KntLCS} \fixdim{\KntSpace}  \fixdim{\KntHXSOSU} \fixdim{\KntSpace} $\\
          $ \fixdim{\KntBLSC} \fixdim{\KntBSN} \fixdim{\KntHXSUSO} \fixdim{\KntBSN}    \fixdim{\KntRCS}   $\\
         \end{tabular}
      \end{center}

   \end{document}

and this gives

enter image description here

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.