9

How to set up a table with discontinuous horizontal rules? As an example I used a table from another answer:

referencetable

My table still lacks the interrupted rules. Another thing is the rule above “Total”. With the current setting \setupTABLE[row][9][bottomframe=on] the rule is too short. When \setupTABLE[row][last][topframe=on] is set, then the thickness of the rule changes from 0.03em to 0.08em. How to fix these both rules?

mytable

\startsetups table
  \setupTABLE [frame=off, rulethickness=.03em]

  % vertical alignment
  \setupTABLE [column]         [align=lohi]

  % column spacing
  \setupTABLE [column] [each]  [loffset=.5ex, roffset=.5ex]
  \setupTABLE [column] [first] [loffset=0mm]
  \setupTABLE [column] [last]  [roffset=0mm]

  % rules
  \setupTABLE [row]    [first] [topframe=on, rulethickness=.08em]
  \setupTABLE [row]    [2]     [topframe=on]
  \setupTABLE [row]    [last]  [bottomframe=on, rulethickness=.08em]

  \setupTABLE [row]    [6]     [topframe=on]
  \setupTABLE [row]    [last]  [align=middle]

  % wrong rule width (too short)
  \setupTABLE [row] [9] [bottomframe=on]

  % wrong rule thickness (should be .03em, but draws .8em)
  %\setupTABLE [row] [last] [topframe=on] % wrong rule thickness
\stopsetups

\starttext
\bTABLE [setups=table]
  \bTR\bTH Part \eTH\bTH Problem \eTH\bTH Score \eTH\bTH Sum \eTH\eTR

  % first part
  \bTR\bTD[nr=4] 1 \eTD\bTD 1a \eTD\bTD 2 \eTD\bTD[nr=4] 7 \eTD\eTR
  \bTR                 \bTD 2b \eTD\bTD 2 \eTD                 \eTR
  \bTR                 \bTD 3a \eTD\bTD 1 \eTD                 \eTR
  \bTR                 \bTD 5b \eTD\bTD 2 \eTD                 \eTR

  % second part
  \bTR\bTD[nr=4] 2 \eTD\bTD 6a \eTD\bTD 2 \eTD\bTD[nr=4] 7 \eTD\eTR
  \bTR                 \bTD 6b \eTD\bTD 2 \eTD                 \eTR
  \bTR                 \bTD 7a \eTD\bTD 1 \eTD                 \eTR
  \bTR                 \bTD 8b \eTD\bTD 2 \eTD                 \eTR

  % total
  \bTR\bTD[nc=3] Total                    \eTD\bTD 14      \eTD\eTR
\eTABLE
\stoptext
Mico
  • 506,678
Marco
  • 26,055

1 Answers1

5

Rule over the last line

When you use

\setupTABLE [row] [9] [bottomframe=on]

the rule only extends in the middle cells because internally the first and the last cell are not part of row 9. Visually, you can get a rule stretching over the whole line by using:

\setupTABLE [row] [9] [bottomframe=on]
\setupTABLE [first,last]   [6] [bottomframe=on]

Now, when you use

\setupTABLE [row] [last] [topframe=on]

you get a rule of 0.08em because earlier you have

\setupTABLE [row]    [last]  [bottomframe=on, rulethickness=.08em]

so the rule thickness is set to 0.08em. The only way to get top and bottom rules of different thickness is to either use metapost (background=....), or use custom frame renders. I show the latter, as I assume you already know how to use custom backgrounds.

\unprotect
\startuniqueMPgraphic {top_frame}
  draw topboundary OverlayBox 
    withpen pensquare scaled (\the\dimexpr\framedparameter{\c!top\c!rulethickness}\relax) 
    withcolor \MPcolor{\framedparameter{\c!top\c!framecolor}} ;

  setbounds currentpicture to OverlayBox ;
\stopuniqueMPgraphic

% Typo in pack-fen.mkiv
\let\setinstalledframedimensions\pack_framed_overlay_initialize_indeed

\installtopframerenderer{custom}{\uniqueMPgraphic{top_frame}}

\setupframed
  [
    \c!top\c!rulethickness=\framedparameter\c!rulethickness,
    \c!top\c!framecolor=\framedparameter\c!framecolor,
  ]
\protect

and then use

\setupTABLE [row]    [last]  [topframe=custom, toprulethickness=0.03em]

You can also define similar custom frames for left, right, and bottom frames.

Discontinuous rule

You can also define custom fences to have a short top border:

\startuniqueMPgraphic {tight_top_frame}
  draw (2*\the\dimexpr\framedparameter\c!loffset,OverlayHeight) -- (OverlayWidth - 2*\the\dimexpr\framedparameter\c!roffset, OverlayHeight)
    withpen pensquare scaled \overlaylinewidth
    withcolor \MPcolor{\overlaylinecolor} ;

  setbounds currentpicture to OverlayBox ;
\stopuniqueMPgraphic
\installtopframerenderer{tight}{\uniqueMPgraphic{tight_top_frame}}

(I am not sure why I need to multiply the loffset and roffset by 2.) and then use

\setupTABLE [row]    [2]     [topframe=tight]

Combining all this, we have:

\unprotect
\startuniqueMPgraphic {top_frame}
  draw topboundary OverlayBox 
    withpen pensquare scaled (\the\dimexpr\framedparameter{\c!top\c!rulethickness}\relax) 
    withcolor \MPcolor{\framedparameter{\c!top\c!framecolor}} ;

  setbounds currentpicture to OverlayBox ;
\stopuniqueMPgraphic

\startuniqueMPgraphic {tight_top_frame}
  draw (2*\the\dimexpr\framedparameter\c!loffset,OverlayHeight) -- (OverlayWidth - 2*\the\dimexpr\framedparameter\c!roffset, OverlayHeight)
    withpen pensquare scaled \overlaylinewidth
    withcolor \MPcolor{\overlaylinecolor} ;

  setbounds currentpicture to OverlayBox ;
\stopuniqueMPgraphic

% Typo in pack-fen.mkiv
\let\setinstalledframedimensions\pack_framed_overlay_initialize_indeed

\installtopframerenderer{custom}{\uniqueMPgraphic{top_frame}}
\installtopframerenderer{tight}{\uniqueMPgraphic{tight_top_frame}}

\setupframed
  [
    \c!top\c!rulethickness=\framedparameter\c!rulethickness,
    \c!top\c!framecolor=\framedparameter\c!framecolor,
  ]
\protect

with the table setup:

\startsetups table
  \setupTABLE [frame=off, rulethickness=.03em]

  % vertical alignment
  \setupTABLE [column]         [align=lohi]

  % column spacing
  \setupTABLE [column] [each]  [loffset=.5ex, roffset=.5ex]
  \setupTABLE [column] [first] [loffset=0mm]
  \setupTABLE [column] [last]  [roffset=0mm]

  % rules
  \setupTABLE [row]    [first] [topframe=on, rulethickness=.08em]
  \setupTABLE [row]    [2]     [topframe=tight]
  \setupTABLE [row]    [last]  [bottomframe=on, rulethickness=.08em]

  \setupTABLE [row]    [6]     [topframe=on]
  \setupTABLE [row]    [last]  [align=middle]

  \setupTABLE [row]    [last]  [topframe=custom, toprulethickness=0.03em]


\stopsetups

which gives:

enter image description here

Aditya
  • 62,301