[Tex/LaTex] Using BibTex as a general database for generating a table

bibtexdatabasetables

I want to create an overview table of some data. More specifically, I have some named objects and for each of these I have some properties.

Example data and schematic of output:

+ -------+--------+-------+--------+
| Object | Edible | Color | Size   |
+ -------+--------+-------+--------+
| Apple  | yes    | green | small  |
| Cat    | no     | brown | medium |
+ -------+--------+-------+--------+

Instead of entering the table manually, I'd like to create something like a database and then generate the table based on a format description.

I thought this could maybe be done with BibTex.

I would create a bib file with content like this:

@misc{apple,
    name={Apple},
    edible={yes},
    color={green},
    size={small}
}
@misc{cat,
    name={Cat},
    edible={no},
    color={brown}
    size={medium}
}

And then create a (very) custom bibliography style to turn this into a table.

I could create some external script to transform the bib file into a table (JSON would probably be a better data format then) but I'd like to use TeX tools.

How can I get from this (or similar) bib to a table instead of a list (like usually with references)?

Best Answer

Unless you know how to write in bibtex's stack-based language, I wouldn't recommend doing it that way. If you just want to use TeX tools without relying on external scripts, you can use datatool. Here's an example:

\documentclass{article}

\usepackage{datatool}

\begin{filecontents*}{test.csv}
Object,Edible,Color,Size
Apple,yes,green,small
Cat,no,brown,medium
Aardvark,no,grey,medium
\end{filecontents*}

\DTLloaddb{mydata}{test.csv}

% Define a command to access a field in `mydata' in the row identified by a
% given object:

% Syntax: \field{object}{column label} 
\newcommand{\field}[2]{%
  \dtlgetrowforvalue{mydata}{\dtlcolumnindex{mydata}{Object}}{#1}%
  \dtlgetentryfromcurrentrow{\thisvalue}{\dtlcolumnindex{mydata}{#2}}%
  \thisvalue
}

% Syntax: \boolfield{object}{column label}{true part}{false part}
\newcommand{\boolfield}[4]{%
  \dtlgetrowforvalue{mydata}{\dtlcolumnindex{mydata}{Object}}{#1}%
  \dtlgetentryfromcurrentrow{\thisvalue}{\dtlcolumnindex{mydata}{#2}}%
  \DTLifstringeq{\thisvalue}{yes}{#3}{#4}%
}

\begin{document}

List the data in a tabular environment:

\DTLdisplaydb{mydata}

Sort on `Object' column.
\DTLsort{Object}{mydata}

List sorted data in a tabular environment:

\DTLdisplaydb{mydata}

Access data: an apple is \field{Apple}{Size} and \field{Apple}{Color}.
It \boolfield{Apple}{Edible}{is}{isn't} edible.

Access data: a cat is \field{Cat}{Size} and \field{Apple}{Color}.
It \boolfield{Cat}{Edible}{is}{isn't} edible.

\end{document}

The above example produces:

Image of result

(I suggest putting \DTLdisplaydb inside a table or use \DTLdisplaylongdb if it's longer than a page.)