#!/usr/bin/perl -w
-package xmldb2tex;
-
-# my $me = "adcmon.pl";
+package this;
use strict;
use warnings;
use FileHandle;
use Getopt::Long;
use File::Basename;
+use File::Copy;
# use Cwd;
my $opt;
'standalone' => \$opt->{standalone}
);
+printHelpMessage() if $opt->{help};
printHelpMessage() unless $opt->{entity} && $opt->{group};
-my $me = xmldb2tex->new();
+my $me = this->new();
$me->setEntity($opt->{entity});
# $me->{entityFile} = "/home/micha/mnt/55local1/htdocs/daqtools/xml-db/cache/CbController.entity";
$me->{group} = $opt->{group};
-$me->{table}->{label} = $opt->{label}||"";
-$me->{table}->{caption} = $opt->{caption}||"";
+$me->{table}->{label} = $opt->{label}||"tab:".$opt->{group};
+$me->{table}->{caption} = $opt->{caption}||"Registers in group ".$opt->{group};
$me->produceTable();
-
-if ($opt->{output}){
- $me->writeTexFile($opt->{output}, $opt->{standalone} );
-} else {
- $me->printTex();
-}
+$me->writeTexFile($opt->{output}, $opt->{standalone} );
if ($opt->{pdf}){
- $me->pdflatex();
+ if ($opt->{output}){
+ $me->pdflatex($opt->{output});
+ } else {
+ die "\n\ncannot make pdf!\nno output file specified, use the -o <file.tex> argument!\n";
+ }
}
+
+
########### simple subs ########
sub printHelpMessage{
print <<EOF;
-xmldb2tex.pl -e <entityName> -g <group> [-o <output.tex>] [OPTIONS]
+xml-db2tex.pl -e <entityName> -g <group> [-o <output.tex>] [OPTIONS]
Generates a latex table of an xml-db group.
-e, --entity enter entity name or /path/to/entityName.entity
-g, --group the xml-db group to be transformed into a table
-o, --output write tex output to this file, if left out,
- print to STDOUT
+ will write tex code to STDOUT
+
-c, --caption caption of the table
-l, --label latex label of the table
# default formatting of the table
$self->{table}->{dataKeys} = [ 'name', 'addr', 'bits', 'description' ];
- $self->{table}->{format} = '@{} l l l p{8cm} @{}';
+ $self->{table}->{header} = [ 'Register', 'Addr', 'Bits', 'Description' ];
+# $self->{table}->{format} = '@{} l l l p{8cm} @{}';
+ $self->{table}->{format} = ' l l c p{8cm} ';
$self = {
%$self,
for (my $i=0;$i<$repeat;$i++){
my $name_ = $name;
if ($repeat > 1) {
- $name_ = $name.".$i";
+ $name_ = $name.".$i";
}
my $addr_ = $node->{address}+$i*$stepsize;
my $hexaddr = sprintf("0x%04x",$addr_ );
- push(@{$data},{%$node, name => $name_, addr => $hexaddr, bits => $bits});
+
+ if ($type eq 'register' || $type eq 'registerfield'){
+ #write register names bold
+ $name_ = '\textbf{'.$name_.'}';
+ }
+ if ($type eq 'field'){
+ $hexaddr = ''; # don't print addr it's already in the register
+ }
+
+ push(@{$data},{
+ %$node,
+ name => $name_,
+ addr => $hexaddr,
+ bits => $bits,
+ addr_uint => $addr_
+ });
}
}
- @$data = sort { $a->{bits} cmp $b->{bits} } @$data; # bit fields in ascending order
- @$data = sort { $a->{addr} cmp $b->{addr} } @$data; # addresses in ascending order
-
+ @$data = sort {
+ # sort numerically by first number in the bits string
+ $a->{bits} =~ m/^(\d+)/;
+ my $aa=$1;
+ $b->{bits} =~ m/^(\d+)/;
+ my $bb=$1;
+ return ($aa||-1) <=> ($bb||-1);
+ } @$data; # bit fields in ascending order
+
+ @$data = sort { $a->{addr_uint} cmp $b->{addr_uint} } @$data; # addresses in ascending order
+ # some more formatting
+
+ my $last_addr;
+ my $addr_counter=0;
for my $item (@$data){
+
+ # make hline at each new register
+ my $cur_addr = $item->{addr_uint};
+ if($last_addr){
+ if($last_addr != $cur_addr){
+# $self->{table}->addData(plain_code => '\hline');
+ $addr_counter++;
+ }
+ }
+
+
+# if($item->{type} eq 'register' || $item->{type} eq 'registerfield'){
+# $self->{table}->addData(plain_code => '\rowcolor{lightgray}');
+# }
+ if($addr_counter % 2){
+ $self->{table}->addData(plain_code => '\rowcolor{light-gray}');
+ }
$self->{table}->addData(%$item); # fill it with the sorted data
+ $last_addr = $cur_addr;
}
}
-sub printTex {
- my $self = shift;
- print $self->{table}->generateString();
-}
-
-
sub writeTexFile {
my $self = shift;
- my $pathToFile = shift;
+ my $output = shift;
my $standalone = shift;
- my $tablefile = FileHandle->new($pathToFile, 'w');
+
+ # unless specified by --output/-o, the print OUTPUT commands go to STDOUT
+ if ($output) {
+ open(OUTPUT, '>', $output) or die "could not open $output for writing!";
+ } else {
+ *OUTPUT = *STDOUT;
+ }
+
if ($standalone){
- print $tablefile q%
+ print OUTPUT q%
\documentclass[a4paper,11pt]{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{booktabs}
\usepackage{longtable}
+ \usepackage{geometry}
\geometry{verbose,tmargin=3cm,bmargin=3cm,lmargin=3cm,rmargin=3cm}
+ \usepackage[table]{xcolor}
+
+ \definecolor{light-gray}{gray}{0.90}
\begin{document}
%;
}
- print $tablefile $self->{table}->generateString();
+ print OUTPUT $self->{table}->generateString();
- print $tablefile '\end{document}' if $standalone;
- $tablefile->close();
+ print OUTPUT '\end{document}'."\n" if $standalone;
+# OUTPUT->close();
+ close(OUTPUT);
}
sub pdflatex{
-
+ my $self = shift;
+ my $output = shift||$me->{group};
my $here = qx("pwd");
- my $directory = "/dev/shm/xmldb2tex".rand();
+ $here =~ s/\n//g;
+ my $directory = "/dev/shm/xml-db2tex".rand();
unless(-e $directory or mkdir $directory) {
die "Unable to create $directory\n";
}
my $texfile = $me->{group}.".tex";
my $pdffile = $me->{group}.".pdf";
- system("cd $directory");
+
+ $output =~ s/\.(tex|pdf)//;
+ $output.= ".pdf";
+
+ chdir $directory;
$me->writeTexFile($texfile, "standalone");
system("pdflatex $texfile");
system("pdflatex $texfile");
- system("cp $pdffile $here/");
- system("cd $here");
- unlink $directory;
+ copy("$directory/$pdffile","$here/$output");
+ chdir $here;
+ system("rm -rf $directory");
}
$header= " ".join(" & ",map { '\textbf{'.$_.'}' } @{$self->{dataKeys}}).' \\\\'."\n";
}
+
$str .= '\begin{longtable}'."\n";
$str .="{".($self->{format}||"")."}\n";
$str.='\toprule'."\n";
$str.= $header;
$str.='\midrule'."\n";
+ $str.='\midrule'."\n";
$str.='\endfirsthead';
# define (continued) header
$str.='\toprule'."\n";
$str.= $header;
$str.='\midrule'."\n";
+ $str.='\midrule'."\n";
$str.='\endhead';
$str.='\multicolumn{'.scalar(@{$self->{dataKeys}}).'}{r}{\textit{Continued on next page}} \\\\
\endlastfoot';
for my $data (@{$self->{data}}){
- my @line;
- for my $dataKey (@{$self->{dataKeys}}){
- push(@line,$data->{$dataKey});
+
+ if ( $data->{plain_code} ) { #if there are strings in the data, just print them
+ $str.=$data->{plain_code}."\n";
+ } else {
+
+ my @line;
+ for my $dataKey (@{$self->{dataKeys}}){
+ push(@line,$data->{$dataKey});
+ }
+ my $line = " ".join(" & ", @line) . ' \\\\'."\n";
+ $line =~ s/_/\\_/g; # remove all stupid underscores
+ $str.=$line;
+
}
- my $line = " ".join(" & ", @line) . ' \\\\'."\n";
- $line =~ s/_/\\_/g; # remove all stupid underscores
- $str.=$line;
}
$str.='\bottomrule'."\n";
# $str.='\hline'."\n";