# Multi-column table layout the right way

How do I create book-like multi-column table formatting for a long, narrow tables in a preferably elegant way? Should I be thinking of stylesheets, instead of formatting? I guess this is a solved problem, after all.

Row expression below is my own, feeble attempt to solve the problem. Although output is reasonably OK, I detest many details on the implementation; for instance, the magic constant 1.2 needed to make columns evenly tall.

Row[Pane[
Grid[#, Frame -> All, ItemSize -> {Automatic, 1.2},
ItemStyle -> FontFamily -> "Times",
Alignment -> {{Right, Left}, Center}],
ImageMargins -> 2] &
/@ Partition[#1, #2]] &[
{Round[#[[1]]], CityData[#[[2]], "FullName"]} &
/@ ({GeoDistance[\$GeoLocation, CityData[#, "Coordinates"]]/
1000, #} &
/@ CityData[]~Select~(CityData[#, "Population"] >= 100000 &))
~SortBy~First
~Take~(3*20),
20]


-
It is unclear what is detestable in the users own output. The "magic constant" 1.2 is simply the vertical item size -- not magic or a fudge factor or anything like that, just a standard way to size row heights. Some aesthetic changes could be made depending on personal preferences but the user has not indicated what these could be. –  Mike Honeychurch Oct 10 '12 at 22:49

Perhaps I am missing the subtlety of your formatting needs but I think you can make this a lot simpler.

With your two column table as dat try:

Grid[
dat ~Partition~ 20 ~Flatten~ {{2}, {1, 3}},
Dividers -> {{All, {3 -> Thick, 5 -> Thick}}, All},
Alignment -> {{{Right, Left}}, Center},
Spacings -> {{{1, 0.5}}},
BaseStyle -> {FontFamily -> "Times"}
]


If the separation between pairs of columns is desired you might use:

Row[
Grid[#,
Dividers -> All,
Alignment -> {{Right, Left}},
Spacings -> {{{1, 0.5}}},
BaseStyle -> {FontFamily -> "Times"}
] & /@
dat ~Partition~ 20
]


### Third try:

newdat = Flatten @ Riffle[#, Item[Spacer[0], Frame -> {False, True, False, True}]] & /@
Transpose[dat ~Partition~ 20];

Grid[
newdat,
Dividers -> All,
Alignment -> {{{Right, Left}}, Center},
Spacings -> {{{1, 0.5, 0.5}}},
BaseStyle -> {FontFamily -> "Times"}
]


Here is the inverse of the above (output looks the same); it may be more convenient sometimes.

newdat = Flatten @ Riffle[#, Spacer[0]] & /@
Transpose[Map[Item[#, Frame -> All] &, dat, {2}] ~Partition~ 20];

Grid[
newdat,
Alignment -> {{{Right, Left}}, Center},
Spacings -> {{{1, 0.5, 0.5}}},
BaseStyle -> {FontFamily -> "Times"}
]

-
@Mr.Wizard I'm wondering if something is missing from your separated example, since it renders without separation in my case. I can see what you're trying to do. The problem here is that while first one keeps lines aligned, there's no separation, and while second one has separation, it actually results unaesthetically unaligned columns when contents contain accented text. Getting rid of both of these is awkward or kludgy... –  kirma Oct 10 '12 at 22:52
@kirma try Row[ ...content..dat ~Partition~ 20, Spacer[5]] –  Mike Honeychurch Oct 10 '12 at 22:59
@kirma with accented text you are introducing a different line height. That is why the "magic constant" is useful. –  Mike Honeychurch Oct 10 '12 at 23:17
@kirma what do you mean by accented text? –  Mr.Wizard Oct 10 '12 at 23:31
@kirma I added a third example; please tell me if this is any better. –  Mr.Wizard Oct 10 '12 at 23:46