Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

statico (5018)

statico
  ian.langworthNO@SPAMgmail.com
http://langworth.com/
AOL IM: eisforian (Add Buddy, Send Message)

PAUSE-ID: IAN [cpan.org]

Co-author of Perl Testing: A Developer's Notebook [oreilly.com]

Journal of statico (5018)

Monday May 02, 2005
10:17 AM

bibtex2html

[ #24487 ]

Today I wanted an HTML page of links with all the articles I had collected for my project this weekend. All of the resources are stored in a BibTeX database, so each has a URL and title field. Unfortunately, I couldn't get Text::BibTeX to install so I decided to write a parser using Parse::RecDescent as a fun exercise.

The resulting tool, bibtex2html, can't handle comments, plus I didn't even look at the btparse source code for what the real grammar is. Maybe I can do this over the correct way and create Text::BibTeX::PurePerl.

#!/usr/bin/perl
 
use strict;
use warnings;
 
use Parse::RecDescent;
use Template;
 
my $grammar = <<'ENDGRAMMAR';
 
    entries :   Entry(s) /\Z/
                { $item[1] }
 
    Entry   :   '@' Key '{' Key ',' Tuple(s) '}'
                {
                    {
                        category => lc $item[2],
                        key      => lc $item[4],
                        map { @$_ } @{ $item[6] }
                    }
                }
 
    Tuple   :   Key '=' Value /,?/
                {
                    for ( $item[3] ) {
                        s/\n/ /gs;
                        s/\s{3,}/ /gs;
                    }
                    [ lc $item[1], $item[3] ];
                }
 
    Value   :   Key
            |   String
 
    Key     :   /[\w-]+/
 
    String  :   /".+?(?<!\\)"/s
                {
                    substr( $item[1], 1, -1 )
                }
 
ENDGRAMMAR
 
my $entries = Parse::RecDescent->new($grammar)->entries(
    do { local $/; <> }
    )
    or die "Couldn't parse input\n";
 
my $tt = Template->new;
$tt->process( \*DATA, { entries => $entries } )
    or die "Couldn't process template: " . $tt->error;
 
__DATA__
<html>
  <head>
    <title>BibTeX Entries</title>
    <style type="text/css">
    body { font-family: sans-serif }
    dd { margin-bottom: 0.5em }
    </style>
  </head>
  <body>
    <dl>
    [% FOREACH entry IN entries %]
        <dt>
            <a href="http://[% entry.url | uri %]">[% entry.title | html %]</a>
            <a name="[% entry.key %]"></a>
        </dt>
        <dd>
            [% entry.author | html %]<br/>
            <em><small> [% entry.note | html %] </small></em>
        </dd>
    [% END %]
    </dl>
  </body>
</html>

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.