+++ /dev/null
-#!/usr/bin/perl -w
-
-
-# my $me = "adcmon.pl";
-
-use strict;
-use warnings;
-use POSIX;
-# use CGI ':standard';
-# use CGI::Carp qw(fatalsToBrowser);
-# use HTML::Entities;
-use Data::Dumper;
-use FileHandle;
-
-
-
-use FindBin;
-use lib "$FindBin::Bin/..";
-# my $entityFile = "../../daqtools/xml-db/cache/CbController.entity";
-# my $xmldb = AccessXmlDb->new( entityFile => $entityFile );
-# print any2hex(1234);
-# print join(":",@{$xmldb->channelList()});
-# print "\n";
-#
-
-my $xml_cbctrl_entity = "/home/micha/mnt/55local1/htdocs/daqtools/xml-db/cache/CbController.entity";
-
-my $daqopserver="jspc55:88";
-$ENV{'DAQOPSERVER'} = $daqopserver;
-
-
-my $xmldb = xmlDbMethods->new( entityFile => $xml_cbctrl_entity);
-
-
-
-
-
-$xmldb->dumpItem('EnaA');
-$xmldb->dumpItem('MiscConf');
-
-my $list = $xmldb->unfoldTree('CbUcRegs');
-# my $list = $xmldb->unfoldTree('MiscConf');
-
-my $data = [];
-
-for my $name (@$list) { # processing the list
- my $node = $xmldb->{entity}->{$name};
- my $type = $node->{type};
- my $repeat = $node->{repeat} || 1;
- my $stepsize = $node->{stepsize}||0;
-
- my $bits = "";
- if ($type ne 'register'){
- my $start = $node->{start};
- my $stop = $node->{start}+$node->{bits}-1;
- if ($start == $stop){
- $bits = $start;
- } else {
- $bits = "$start--$stop";
- }
- }
-
- #indent register fields
- if ($type eq 'field'){
- $name= '\quad '.$name;
- }
-
- for (my $i=0;$i<$repeat;$i++){
- my $name_ = $name;
- if ($repeat > 1) {
- $name_ = $name.".$i";
- }
- my $addr_ = $node->{address}+$i*$stepsize;
- my $hexaddr = sprintf("0x%04x",$addr_ );
- push(@{$data},{%$node, name => $name_, addr => $hexaddr, bits => $bits});
- }
-}
-
-@$data = sort { $a->{bits} cmp $b->{bits} } @$data;
-@$data = sort { $a->{addr} cmp $b->{addr} } @$data;
-
-my $table = textabular->new();
-
-for my $item (@$data){
-$table->addData(%$item);
-}
-
-
-
-
-
-
-$table->{dataKeys} = [ 'name', 'addr', 'bits', 'description' ];
-$table->{format} = '@{} l l l p{8cm} @{}';
-$table->{caption} = 'registers, maan';
-
-my $tablefile = FileHandle->new("./table.tex", 'w');
-print $tablefile $table->generateString();
-$tablefile->close();
-
-print $table->generateString();
-
-package xmlDbMethods;
-
-use Storable qw(lock_store lock_retrieve);
-use Data::Dumper;
-
-sub new {
- my $class = shift;
- my %options = @_;
- my $self = {
- entityFile => '/dev/null',
- %options
- };
- bless($self, $class);
- $self->{entity} = lock_retrieve($self->{entityFile});
- die "cannot open xml-db entity file ".$self->{entityFile}."\n" unless defined $self->{entity};
- return $self;
-}
-
-sub channelParm {
- my $self = shift;
- my $chip = shift;
- my $channel = shift;
-
- my $parm;
- %{$parm}= %{$self->{entity}->{$channel."D"}};
-
- die "entry $channel does not exist for chip=".$chip."\n" if ($chip ge $parm->{repeat});
-
- $parm->{address} += $chip * $parm->{stepsize};
- return $parm;
-}
-
-sub dumpItem { # for debug
- my $self = shift;
- my $item = shift;
- unless (defined($item)){
- print Dumper $self->{entity};
- } else {
- print Dumper $self->{entity}->{$item};
- }
-}
-
-sub channelList {
- my $self = shift;
- return $self->{entity}->{AdcSensor}->{children};# returns a reference to an array
-}
-
-sub unfoldTree {
- my $self = shift;
- my $name = shift;
- my $depth = shift||0;
- my $list = shift || [];
-
- my $node = $self->{entity}->{$name};
-
-# for (my $i = 0; $i<$depth; $i++){
-# print " ";
-# }
-# print $node->{type}."\t$name\n";
- unless($node->{type} eq 'group'){
- push(@{$list},$name);
- }
-
- if ($node->{type} eq 'group' || $node->{type} eq 'register' ){
- for my $child (@{$node->{'children'}}){
-# print $child."\n";
- $self->unfoldTree($child,$depth+1,$list);
- }
- }
-
- return $list;
-}
-
-1;
-
-package textabular;
-
-
-sub new {
- my $class = shift;
- my %options = @_;
- my $self = {
-# entityFile => '/dev/null',
- dataKeys => [],
- header => [],
- data => [],
- %options
- };
- bless($self, $class);
- return $self;
-}
-
-sub addData {
- my $self = shift;
- my %data = @_;
- push(@{$self->{data}}, \%data);
- return $self;
-}
-
-sub generateString {
- my $self = shift;
- my $str = "";
-
-# $str.='\begin{table}[tbp]
-# \centering';
-# $str .= '\begin{center}';
-
-
- $str .= '\begin{longtable}'."\n";
- $str .="{".($self->{format}||"")."}\n";
-
-# $str.='\caption{'.$self->{caption}.'}' if defined $self->{caption}."\n";
- $str .= '\\\\';
- $str.='\toprule'."\n";
-# $str.='\hline'."\n";
- if ( @{$self->{header}} ){ # if no header list ...
- $str.= " ".join(" & ",@{$self->{header}}).' \\\\'."\n";
- } else { # print the keys instead
- $str.= " ".join(" & ",@{$self->{dataKeys}}).' \\\\'."\n";
- }
- $str.='\midrule'."\n";
- $str.='\hline'."\n";
- $str.='\endfirsthead';
-
-
- $str.='\hline \multicolumn{'.scalar(@{$self->{dataKeys}}).'}{r}{\textit{Continued on next page}} \\\\
- \endfoot
- \hline
- \endlastfoot';
-
- for my $data (@{$self->{data}}){
- 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;
- }
- $str.='\bottomrule'."\n";
-# $str.='\hline'."\n";
-
- $str .='\caption{aoeiaeoi}'."\n";
- $str .='\label{tab:long}'."\n";
-
- $str.='\end{longtable}'."\n";
-
-# $str.='\label{'.$self->{label}.'}' if defined $self->{label}."\n";
-# $str.='\end{table}'."\n";
-# $str .= '\end{center}';
- return $str;
-}
\ No newline at end of file
--- /dev/null
+#!/usr/bin/perl -w
+
+
+package xmldb2tex;
+
+# my $me = "adcmon.pl";
+
+use strict;
+use warnings;
+use POSIX;
+use Data::Dumper;
+use FileHandle;
+use Getopt::Long;
+use File::Basename;
+# use Cwd;
+
+my $opt;
+
+Getopt::Long::Configure(qw(gnu_getopt));
+GetOptions(
+ 'help|h' => \$opt->{help},
+ 'caption|c=s' => \$opt->{caption},
+ 'label|l=s' => \$opt->{label},
+ 'group|g=s' => \$opt->{group},
+ 'entity|e=s' => \$opt->{entity},
+ 'output|o=s' => \$opt->{output},
+ 'pdf' => \$opt->{pdf},
+ 'standalone' => \$opt->{standalone}
+ );
+
+printHelpMessage() unless $opt->{entity} && $opt->{group};
+
+
+my $me = xmldb2tex->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->produceTable();
+
+
+
+if ($opt->{output}){
+ $me->writeTexFile($opt->{output}, $opt->{standalone} );
+} else {
+ $me->printTex();
+}
+
+if ($opt->{pdf}){
+ $me->pdflatex();
+}
+
+########### simple subs ########
+
+sub printHelpMessage{
+print <<EOF;
+xmldb2tex.pl -e <entityName> -g <group> [-o <output.tex>] [OPTIONS]
+
+Generates a latex table of an xml-db group.
+
+Options:
+ -h, --help brief help/usage message
+ -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
+ -c, --caption caption of the table
+ -l, --label latex label of the table
+
+ --standalone generate standalone compilable latex file
+ --pdf compile directly to pdf
+
+
+EOF
+exit;
+}
+
+
+########### object methods ########
+
+sub new {
+ my $class = shift;
+ my %options = @_;
+
+ my $self = {};
+
+ $self->{table} = textabular->new(); # create new latex table object
+
+ # default formatting of the table
+ $self->{table}->{dataKeys} = [ 'name', 'addr', 'bits', 'description' ];
+ $self->{table}->{format} = '@{} l l l p{8cm} @{}';
+
+ $self = {
+ %$self,
+ %options
+ };
+ bless($self, $class);
+ return $self;
+}
+
+sub setEntity {
+ my $self=shift;
+ my $entity=shift;
+
+ if(-e $entity) { # treat as /path/to/File
+ $self->{entityFile} = $entity;
+ } elsif (-e dirname($0)."/cache/".$entity.".entity"){
+ $self->{entityFile} = dirname($0)."/cache/".$entity.".entity";
+ } else {
+ die "Entity $entity not found (not even in xml-db/cache)\n";
+ }
+}
+
+sub produceTable {
+ my $self= shift;
+ my $xmldb = xmlDbMethods->new( entityFile => $self->{entityFile} );
+ my $list = $xmldb->unfoldTree($self->{group});
+ my $data = [];
+ for my $name (@$list) { # processing the list
+ my $node = $xmldb->{entity}->{$name};
+ my $type = $node->{type};
+ my $repeat = $node->{repeat} || 1;
+ my $stepsize = $node->{stepsize}||0;
+ my $bits = "";
+ if ($type ne 'register'){
+ my $start = $node->{start};
+ my $stop = $node->{start}+$node->{bits}-1;
+ if ($start == $stop){
+ $bits = $start;
+ } else {
+ $bits = "$start--$stop";
+ }
+ }
+ #indent register fields
+ if ($type eq 'field'){
+ $name= '\quad '.$name;
+ }
+ for (my $i=0;$i<$repeat;$i++){
+ my $name_ = $name;
+ if ($repeat > 1) {
+ $name_ = $name.".$i";
+ }
+ my $addr_ = $node->{address}+$i*$stepsize;
+ my $hexaddr = sprintf("0x%04x",$addr_ );
+ push(@{$data},{%$node, name => $name_, addr => $hexaddr, bits => $bits});
+ }
+ }
+
+ @$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
+
+
+
+ for my $item (@$data){
+ $self->{table}->addData(%$item); # fill it with the sorted data
+ }
+
+}
+
+sub printTex {
+ my $self = shift;
+ print $self->{table}->generateString();
+}
+
+
+sub writeTexFile {
+ my $self = shift;
+ my $pathToFile = shift;
+ my $standalone = shift;
+
+ my $tablefile = FileHandle->new($pathToFile, 'w');
+ if ($standalone){
+ print $tablefile q%
+ \documentclass[a4paper,11pt]{article}
+ \usepackage[T1]{fontenc}
+ \usepackage{lmodern}
+ \usepackage{booktabs}
+ \usepackage{longtable}
+ \geometry{verbose,tmargin=3cm,bmargin=3cm,lmargin=3cm,rmargin=3cm}
+ \begin{document}
+ %;
+ }
+ print $tablefile $self->{table}->generateString();
+
+ print $tablefile '\end{document}' if $standalone;
+ $tablefile->close();
+}
+
+sub pdflatex{
+
+ my $here = qx("pwd");
+ my $directory = "/dev/shm/xmldb2tex".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");
+ $me->writeTexFile($texfile, "standalone");
+ system("pdflatex $texfile");
+ system("pdflatex $texfile");
+ system("cp $pdffile $here/");
+ system("cd $here");
+ unlink $directory;
+
+}
+
+
+
+package xmlDbMethods;
+
+use Storable qw(lock_store lock_retrieve);
+use Data::Dumper;
+
+sub new {
+ my $class = shift;
+ my %options = @_;
+ my $self = {
+ entityFile => '/dev/null',
+ %options
+ };
+ bless($self, $class);
+ $self->{entity} = lock_retrieve($self->{entityFile});
+ die "cannot open xml-db entity file ".$self->{entityFile}."\n" unless defined $self->{entity};
+ return $self;
+}
+
+
+
+sub dumpItem { # for debug
+ my $self = shift;
+ my $item = shift;
+ unless (defined($item)){
+ print Dumper $self->{entity};
+ } else {
+ print Dumper $self->{entity}->{$item};
+ }
+}
+
+
+sub unfoldTree {
+ my $self = shift;
+ my $name = shift;
+ my $depth = shift||0;
+ my $list = shift || [];
+
+ my $node = $self->{entity}->{$name};
+ unless($node->{type} eq 'group'){
+ push(@{$list},$name);
+ }
+
+ if ($node->{type} eq 'group' || $node->{type} eq 'register' ){
+ for my $child (@{$node->{'children'}}){
+# print $child."\n";
+ $self->unfoldTree($child,$depth+1,$list);
+ }
+ }
+
+ return $list;
+}
+
+1;
+
+package textabular;
+
+
+sub new {
+ my $class = shift;
+ my %options = @_;
+ my $self = {
+ dataKeys => [],
+ header => [],
+ data => [],
+ caption => '',
+ label => '',
+ %options
+ };
+ bless($self, $class);
+ return $self;
+}
+
+sub addData {
+ my $self = shift;
+ my %data = @_;
+ push(@{$self->{data}}, \%data);
+ return $self;
+}
+
+sub generateString {
+ my $self = shift;
+ my $str = '% remember to include the following latex packages:
+ % booktabs
+ % longtable'."\n";
+
+ my $header;
+
+ if ( @{$self->{header}} ){ # if no header list ...
+ $header= " ".join(" & ",map { '\textbf{'.$_.'}' } @{$self->{header}}).' \\\\'."\n";
+ } else { # print the keys instead
+ $header= " ".join(" & ",map { '\textbf{'.$_.'}' } @{$self->{dataKeys}}).' \\\\'."\n";
+ }
+
+ $str .= '\begin{longtable}'."\n";
+ $str .="{".($self->{format}||"")."}\n";
+
+
+ # define first header
+ $str.='\toprule'."\n";
+ $str.= $header;
+ $str.='\midrule'."\n";
+ $str.='\endfirsthead';
+
+ # define (continued) header
+ $str.='\multicolumn{'.@{$self->{dataKeys}}.'}{c}';
+ $str.='{\tablename\ \thetable\ -- \textit{Continued from previous page}} \\\\';
+ $str.='\toprule'."\n";
+ $str.= $header;
+ $str.='\midrule'."\n";
+ $str.='\endhead';
+
+ $str.='\multicolumn{'.scalar(@{$self->{dataKeys}}).'}{r}{\textit{Continued on next page}} \\\\
+ \endfoot
+ \endlastfoot';
+
+ for my $data (@{$self->{data}}){
+ 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;
+ }
+ $str.='\bottomrule'."\n";
+# $str.='\hline'."\n";
+
+ $str.='\caption{'.$self->{caption}.'}' if $self->{caption}."\n";
+ $str.='\label{'.$self->{label}.'}' if $self->{label}."\n";
+
+ $str.='\end{longtable}'."\n";
+
+# $str.='\end{table}'."\n";
+ return $str;
+}
\ No newline at end of file