taldcroft / asciitable

Extensible ASCII table reader
http://cxc.harvard.edu/contrib/asciitable/
36 stars 9 forks source link

Units in AASTex tables #23

Closed ghost closed 12 years ago

ghost commented 12 years ago

Hi Tom.

I am interested in adding units to an AASTex deluxetable. The standard, at least for AJ & ApJ, is to include the units as the second row of the table. For example:

http://aas.org/journals/authors/common_instruct#_Toc6

For a deluxetable, the way I have seen everybody do this is to add a second row of units to the \tablehead{}.

An example table of this is

\begin{deluxetable}{cc}
\tablehead{\colhead{col1} & \colhead{col2}\\
\colhead{cm} & \colhead{km}}
\startdata
0 & dog \\
1 & cat \\
2 & pig \\
\enddata
\end{deluxetable}

Where col1 has units of cm and col2 has units of km. I think the easiest want to achieve this for the deluxetable is to allow an additional optional entry 'units' to the latexdict. If 'units' is passed, it gets joined into the \tablehead{} with a newline separating the names form the units.

To accomplish this, I modified the file latex.py by adding at line 291 the following code.

        if 'units' in self.latex.keys():
            if len(self.latex['units']) != len(self.cols):
                raise Exception("There must be only as many units as there are columns.")
            tablehead += r'\\'+ '\n' + ' & '.join([r'\colhead{' + u + '}' for u in self.latex['units']])

With this addition, I can successfully create the example table using the following lines of code

import asciitable

table = {
    r'col1': [0, 1, 2],
    'col2': ['dog', 'cat', 'pig']
}

asciitable.write(table, sys.stdout, Writer=asciitable.AASTex,
                 names=[r'col1','col2'],
                 latexdict = dict(units=['cm', 'km']))

I am sorry, but my git skills are lacking, so I am unable to submit a pull request. But would you be willing to incorporate this new feature into your code? Or can you think of a better way to implement this.

All the best,

Joshua

taldcroft commented 12 years ago

Sorry, was preoccupied with other things. I'm going to ask the original author the latex tables extension to have a look. You might think about making units be a dict instead of list so that you only need to supply units for columns where they are available. That's not a huge deal, but sometimes for a wide table with lots of columns making sure everything lines up can be difficult. Also then you don't have to do the consistency check on the number of elements supplied for units: just go through each column name and if the corresponding key is in units then supply units, otherwise put in an empty string "".

hamogu commented 12 years ago

A field for units is a good idea. Actually, I was looking into this for AAS tables, I just could not figure out how to do that in LaTeX, because I did not know that I can do a second row of \colhead commands. So far, I always used standard LaTeX table if I needed units. We should add a units keyword as you suggest, in the form as dictionary. However, I want to make sure that it is symmetric to the standard LaTeX table and can be used there as well. This can be done in the same way as latexdict['caption']. If caption is present the writer puts a out a line \tablecaption{' + latexdict['caption'] +'}, but the user is free to set latexdict['preamble'] = r'\tablecaption{blabla}' instead.

That should be relatively fast to do. I'll take your code above, put that in and upload a new version to github soon.

hamogu commented 12 years ago

I made those changes. See issue 24 (pull request), which has a link to the modified code (I don't know how to attach a pull request to an issue that is already open).

ghost commented 12 years ago

I am thrilled you decided that this was a worthy feature. Good suggestion about passing in instead a dict. My preliminary testing of this code works perfectly!

For the record, the improved code sample from above is

import asciitable

table = {
    r'col1': [0, 1, 2],
    'col2': ['dog', 'cat', 'pig']
}

asciitable.write(table, sys.stdout, Writer=asciitable.AASTex,
                 names=[r'col1','col2'],
                 latexdict = dict(units=dict(col1='cm', col2='km')))

And the output is

\begin{deluxetable}{cc}
\tablehead{\colhead{col1} & \colhead{col2}\\ \colhead{cm} & \colhead{km}}
\startdata
0 & dog \\
1 & cat \\
2 & pig \\
\enddata
\end{deluxetable}

This code also works for a standard Latex table!

asciitable.write(table, sys.stdout, Writer=asciitable.Latex,
                 names=[r'col1','col2'],
                 latexdict = dict(units=dict(col1='cm', col2='km')))

and the output is

\begin{table}
\begin{tabular}{cc}
col1 & col2 \\
cm & km \\
0 & dog \\
1 & cat \\
2 & pig \\
\end{tabular}
\end{table}

Wonderful!