Change dbdToHtml.pl to parse POD from DBD comments

This commit is contained in:
Andrew Johnson
2012-08-30 00:55:22 -05:00
committed by Ralph Lange
parent 43393096ac
commit 874cebb63d
3 changed files with 531 additions and 195 deletions

View File

@@ -51,5 +51,8 @@ PERL_SCRIPTS += dbdExpand.pl
PERL_SCRIPTS += dbdToHtml.pl
PERL_SCRIPTS += registerRecordDeviceDriver.pl
HTMLS_DIR = std
HTMLS = style.css
include $(TOP)/configure/RULES

View File

@@ -1,5 +1,4 @@
#!/usr/bin/perl
#*************************************************************************
# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
@@ -17,6 +16,7 @@ use DBD::Parser;
use EPICS::Getopts;
use EPICS::macLib;
use EPICS::Readfile;
use Pod::Simple::HTML;
my $tool = 'dbdToHtml';
getopts('DI@o:') or
@@ -31,6 +31,12 @@ $infile =~ m/\.dbd$/ or
&ParseDBD($dbd, &Readfile($infile, 0, \@opt_I));
if (!$opt_o) {
($opt_o = $infile) =~ s/\.dbd$/.html/;
$opt_o =~ s/^.*\///;
$opt_o =~ s/dbCommonRecord/dbCommon/;
}
if ($opt_D) { # Output dependencies only
my %filecount;
my @uniqfiles = grep { not $filecount{$_}++ } @inputfiles;
@@ -39,214 +45,108 @@ if ($opt_D) { # Output dependencies only
exit 0;
}
my $out;
if ($opt_o) {
$out = $opt_o;
} else {
($out = $infile) =~ s/\.dbd$/.html/;
$out =~ s/^.*\///;
$out =~ s/dbCommonRecord/dbCommon/;
}
open $out, '>', $opt_o or die "Can't create $opt_o: $!\n";
open my $out, '>', $opt_o or die "Can't create $opt_o: $!\n";
print $out "<h1>$infile</h1>\n";
my @pod = map { s/^ //; $_ } $dbd->comments;
my $rtypes = $dbd->recordtypes;
my ($rn, $rtyp) = each %{$rtypes};
print $out "<h2>Record Name $rn</h2>\n";
my @fields = $rtyp->fields;
#create a Hash to store the table of field information for each GUI type
%dbdTables = (
"GUI_COMMON" => "",
"GUI_COMMON" => "",
"GUI_ALARMS" => "",
"GUI_BITS1" => "",
"GUI_BITS2" => "",
"GUI_CALC" => "",
"GUI_CLOCK" => "",
"GUI_COMPRESS" => "",
"GUI_CONVERT" => "",
"GUI_DISPLAY" => "",
"GUI_HIST" => "",
"GUI_INPUTS" => "",
"GUI_LINKS" => "",
"GUI_MBB" => "",
"GUI_MOTOR" => "",
"GUI_OUTPUT" => "",
"GUI_PID" => "",
"GUI_PULSE" => "",
"GUI_SELECT" => "",
"GUI_SEQ1" => "",
"GUI_SEQ2" => "",
"GUI_SEQ3" => "",
"GUI_SUB" => "",
"GUI_TIMER" => "",
"GUI_WAVE" => "",
"GUI_SCAN" => "",
"GUI_NONE" => ""
);
#Loop over all of the fields. Build a string that contains the table body
#for each of the GUI Types based on which fields go with which GUI type.
foreach $fVal (@fields) {
my $pg = $fVal->attribute('promptgroup');
while ( ($typ1, $content) = each %dbdTables) {
if ( $pg eq $typ1 or ($pg eq "" and $typ1 eq "GUI_NONE")) {
buildTableRow($fVal, $dbdTables{$typ1} );
}
while (my ($rn, $rtyp) = each %{$rtypes}) {
foreach my $_ ($rtyp->comments) {
s/^ //;
if (m/^=fields (.*)/) {
my @names = split /,\s*/, $1;
my @fields = map {
my $field = $rtyp->field($_);
print STDERR "Unknown field name '$_' in $infile POD\n" unless $field;
$field;
} @names;
my $html;
foreach $field (@fields) {
$html .= $field->htmlTableRow if $field;
}
push @pod, podTable($html);
}
else {
push @pod, $_;
}
}
}
#Write out each table
while ( ($typ2, $content) = each %dbdTables) {
printHtmlTable($typ2, $content);
my $podHtml = Pod::Simple::HTML->new();
$podHtml->html_css('style.css');
$podHtml->set_source(\@pod);
# $podHtml->index(1);
$podHtml->output_string(\my $html);
$podHtml->run;
print $out $html;
close $out;
sub podTable {
my $content = shift;
return ("=begin html\n", "\n",
"<blockquote><table border =\"1\"><tr>\n",
"<th>Field</th><th>Summary</th><th>Type</th><th>DCT</th>",
"<th>Default</th><th>Read</th><th>Write</th><th>CA PP</th></tr>\n",
$content, "</table></blockquote>\n",
"\n", "=end html\n");
}
#add a field to a table body. The specified field and table body are passed
#in as parameters
sub buildTableRow {
my ( $fld, $outStr) = @_;
$longDesc = "&nbsp;";
%htmlCellFmt = (
rowStart => "<tr><td rowspan = \"2\">",
nextCell => "</td><td>",
endRow => "</td></tr>",
nextRow => "<tr><td colspan = \"7\" align=left>"
);
my %cellFmt = %htmlCellFmt;
my $rowStart = $cellFmt{rowStart};
my $nextCell = $cellFmt{nextCell};
my $endRow = $cellFmt{endRow};
my $nextRow = $cellFmt{nextRow};
$outStr = $outStr . $rowStart;
$outStr = $outStr . $fld->name;
$outStr = $outStr . $nextCell;
$outStr = $outStr . $fld->attribute('prompt');
$outStr = $outStr . $nextCell;
my $recType = $fld->dbf_type;
$typStr = $recType;
if ($recType eq "DBF_STRING") {
$typStr = $recType . " [" . $fld->attribute('size') . "]";
}
$outStr = $outStr . $typStr;
$outStr = $outStr . $nextCell;
$outStr = $outStr . design($fld);
$outStr = $outStr . $nextCell;
my $initial = $fld->attribute('initial');
if ( $initial eq '' ) {$initial = "&nbsp;";}
$outStr = $outStr . $initial;
$outStr = $outStr . $nextCell;
$outStr = $outStr . readable($fld);
$outStr = $outStr . $nextCell;
$outStr = $outStr . writable($fld);
$outStr = $outStr . $nextCell;
$outStr = $outStr . processPassive($fld);
$outStr = $outStr . $endRow;
$outStr = $outStr . "\n";
$outStr = $outStr . $nextRow;
$outStr = $outStr . $longDesc;
$outStr = $outStr . $endRow;
$outStr = $outStr . "\n";
$_[1] = $outStr;
sub DBD::Recfield::htmlTableRow {
my $fld = shift;
my $html = '<tr><td class="cell">';
$html .= $fld->name;
$html .= '</td><td class="cell">';
$html .= $fld->attribute('prompt');
$html .= '</td><td class="cell">';
my $type = $fld->public_type;
$html .= $type;
$html .= ' [' . $fld->attribute('size') . ']'
if $type eq 'STRING';
$html .= ' (' . $fld->attribute('menu') . ')'
if $type eq 'MENU';
$html .= '</td><td class="cell">';
$html .= $fld->attribute('promptgroup') ? 'Yes' : 'No';
$html .= '</td><td class="cell">';
$html .= $fld->attribute('initial') || '&nbsp;';
$html .= '</td><td class="cell">';
$html .= $fld->readable;
$html .= '</td><td class="cell">';
$html .= $fld->writable;
$html .= '</td><td class="cell">';
$html .= $fld->attribute('pp') eq "TRUE" ? 'Yes' : 'No';
$html .= "</td></tr>\n";
return $html;
}
#Check if the prompt group is defined so that this can be used by clients
sub design {
my $fld = $_[0];
my $pg = $fld->attribute('promptgroup');
if ( $pg eq '' ) {
my $result = 'No';
}
else {
my $result = 'Yes';
}
# Native type presented to dbAccess users
sub DBD::Recfield::public_type {
my $fld = shift;
m/^=type (.+)$/i && return $1 for $fld->comments;
my $type = $fld->dbf_type;
$type =~ s/^DBF_//;
return $type;
}
#Check if this field is readable by clients
sub readable {
my $fld = $_[0];
if ( $fld->attribute('special') eq "SPC_DBADDR") {
$return = "Probably";
}
else{
if ( $fld->dbf_type eq "DBF_NOACCESS" ) {
$return = "No";
}
else {
$return = "Yes"
}
}
# Check if this field is readable
sub DBD::Recfield::readable {
my $fld = shift;
m/^=read (Yes|No)$/i && return $1 for $fld->comments;
return 'Probably'
if $fld->attribute('special') eq "SPC_DBADDR";
return $fld->dbf_type eq 'DBF_NOACCESS' ? 'No' : 'Yes';
}
#Check if this field is writable by clients
sub writable {
my $fld = $_[0];
my $spec = $fld->attribute('special');
if ( $spec eq "SPC_NOMOD" ) {
$return = "No";
}
else {
if ( $spec ne "SPC_DBADDR") {
if ( $fld->dbf_type eq "DBF_NOACCESS" ) {
$return = "No";
}
else {
$return = "Yes";
}
}
else {
$return = "Maybe";
}
}
# Check if this field is writable
sub DBD::Recfield::writable {
my $fld = shift;
m/^=write (Yes|No)$/i && return $1 for $fld->comments;
my $special = $fld->attribute('special');
return 'No'
if $special eq "SPC_NOMOD";
return 'Maybe'
if $special eq "SPC_DBADDR";
return $fld->dbf_type eq "DBF_NOACCESS" ? 'No' : 'Yes';
}
#Check to see if the field is process passive on caput
sub processPassive {
my $fld = $_[0];
$pp = $fld->attribute('pp');
if ( $pp eq "YES" or $pp eq "TRUE" ) {
$result = "Yes";
}
elsif ( $PP eq "NO" or $pp eq "FALSE" or $pp eq "" ) {
$result = "No";
}
}
#print the start row to define a table
sub printTableStart {
print $out "<table border =\"1\"> \n";
print $out "<caption><em>$_[0]</em></caption>";
print $out "<th>Field</th>\n";
print $out "<th>Summary</th>\n";
print $out "<th>Type</th>\n";
print $out "<th>DCT</th>\n";
print $out "<th>Default</th>\n";
print $out "<th>Read</th>\n";
print $out "<th>Write</th>\n";
print $out "<th>caPut=PP</th></tr>\n";
}
#print the tail end of the table
sub printTableEnd {
print $out "</table>\n";
}
# Print the table for a GUI type. The name of the GUI type and the Table body
# for this type are fed in as parameters
sub printHtmlTable {
my ($typ2, $content) = $_;
if ( (length $_[1]) gt 0) {
printTableStart($_[0]);
print $out "$_[1]\n";
printTableEnd();
}
}

433
src/tools/style.css Normal file
View File

@@ -0,0 +1,433 @@
BODY, .logo { background: white; }
BODY {
color: black;
font-family: arial,sans-serif;
margin: 0;
padding: 1ex;
}
TABLE {
border-collapse: collapse;
border-spacing: 0;
border-width: 0;
color: inherit;
}
IMG { border: 0; }
FORM { margin: 0; }
input { margin: 2px; }
.logo {
float: left;
width: 264px;
height: 77px;
}
.front .logo {
float: none;
display:block;
}
.front .searchbox {
margin: 2ex auto;
text-align: center;
}
.front .menubar {
text-align: center;
}
.menubar {
background: #006699;
margin: 1ex 0;
padding: 1px;
}
.menubar A {
padding: 0.8ex;
font: bold 10pt Arial,Helvetica,sans-serif;
}
.menubar A:link, .menubar A:visited {
color: white;
text-decoration: none;
}
.menubar A:hover {
color: #ff6600;
text-decoration: underline;
}
A:link, A:visited {
background: transparent;
color: #006699;
}
A[href="#POD_ERRORS"] {
background: transparent;
color: #FF0000;
}
TD {
margin: 0;
padding: 0;
}
DIV {
border-width: 0;
}
DT {
margin-top: 1em;
}
.credits TD {
padding: 0.5ex 2ex;
}
.huge {
font-size: 32pt;
}
.s {
background: #dddddd;
color: inherit;
}
.s TD, .r TD {
padding: 0.2ex 1ex;
vertical-align: baseline;
}
TH {
background: #bbbbbb;
color: inherit;
padding: 0.4ex 1ex;
text-align: left;
}
TH A:link, TH A:visited {
background: transparent;
color: black;
}
.box {
border: 1px solid #006699;
margin: 1ex 0;
padding: 0;
}
.distfiles TD {
padding: 0 2ex 0 0;
vertical-align: baseline;
}
.manifest TD {
padding: 0 1ex;
vertical-align: top;
}
.l1 {
font-weight: bold;
}
.l2 {
font-weight: normal;
}
.t1, .t2, .t3, .t4, .t5 {
background: #006699;
color: white;
}
.t4 {
padding: 0.2ex 0.4ex;
}
.t1, .t2, .t3 {
padding: 0.5ex 1ex;
}
/* IE does not support .box>.t1 Grrr */
.box .t1, .box .t2, .box .t3, .box .t5 {
margin: 0;
}
.t1 {
font-size: 1.4em;
font-weight: bold;
text-align: center;
}
.t2 {
font-size: 1.0em;
font-weight: bold;
text-align: left;
}
.t3 {
font-size: 1.0em;
font-weight: normal;
text-align: left;
}
.t5 {
font-size: 0.8em;
font-weight: normal;
text-align: center;
}
/* width: 100%; border: 0.1px solid #FFFFFF; */ /* NN4 hack */
.datecell {
text-align: center;
width: 17em;
}
.cell {
padding: 0.2ex 1ex;
text-align: left;
}
.label {
background: #aaaaaa;
color: black;
font-weight: bold;
padding: 0.2ex 1ex;
text-align: right;
white-space: nowrap;
vertical-align: baseline;
}
.categories {
border-bottom: 3px double #006699;
margin-bottom: 1ex;
padding-bottom: 3ex;
padding-top: 2ex;
}
.categories TABLE {
margin: auto;
}
.categories TD {
padding: 0.5ex 1ex;
vertical-align: baseline;
}
.path A {
background: transparent;
color: #006699;
font-weight: bold;
}
.pages {
background: #dddddd;
color: #006699;
padding: 0.2ex 0.4ex;
}
.path {
background: #dddddd;
border-bottom: 1px solid #006699;
color: #006699;
/* font-size: 1.4em;*/
margin: 1ex 0;
padding: 0.5ex 1ex;
}
.menubar TD {
background: #006699;
color: white;
}
.menubar {
background: #006699;
color: white;
margin: 1ex 0;
padding: 1px;
}
.menubar .links {
background: transparent;
color: white;
padding: 0.2ex;
text-align: left;
}
.menubar .searchbar {
background: black;
color: black;
margin: 0px;
padding: 2px;
text-align: right;
}
A.m:link, A.m:visited {
background: #006699;
color: white;
font: bold 10pt Arial,Helvetica,sans-serif;
text-decoration: none;
}
A.o:link, A.o:visited {
background: #006699;
color: #ccffcc;
font: bold 10pt Arial,Helvetica,sans-serif;
text-decoration: none;
}
A.o:hover {
background: transparent;
color: #ff6600;
text-decoration: underline;
}
A.m:hover {
background: transparent;
color: #ff6600;
text-decoration: underline;
}
table.dlsip {
background: #dddddd;
border: 0.4ex solid #dddddd;
}
.pod, .manifest { margin-right: 20ex; }
.pod PRE {
background: #eeeeee;
border: 1px solid #888888;
color: black;
padding: 1em;
white-space: pre;
}
.pod H1 {
background: transparent;
color: #006699;
font-size: large;
}
.pod H1 A { text-decoration: none; }
.pod H2 A { text-decoration: none; }
.pod H3 A { text-decoration: none; }
.pod H4 A { text-decoration: none; }
.pod H2 {
background: transparent;
color: #006699;
font-size: medium;
}
.pod H3 {
background: transparent;
color: #006699;
font-size: medium;
font-style: italic;
}
.pod H4 {
background: transparent;
color: #006699;
font-size: medium;
font-weight: normal;
}
.pod IMG {
vertical-align: top;
}
.pod .toc A {
text-decoration: none;
}
.pod .toc LI {
line-height: 1.2em;
list-style-type: none;
}
.faq DT {
font-size: 1.4em;
font-weight: bold;
}
.chmenu {
background: black;
color: red;
font: bold 1.1em Arial,Helvetica,sans-serif;
margin: 1ex auto;
padding: 0.5ex;
}
.chmenu TD {
padding: 0.2ex 1ex;
}
.chmenu A:link, .chmenu A:visited {
background: transparent;
color: white;
text-decoration: none;
}
.chmenu A:hover {
background: transparent;
color: #ff6600;
text-decoration: underline;
}
.column {
padding: 0.5ex 1ex;
vertical-align: top;
}
.datebar {
margin: auto;
width: 14em;
}
.date {
background: transparent;
color: #008000;
}
.footer {
margin-top: 1ex;
text-align: right;
color: #006699;
font-size: x-small;
border-top: 1px solid #006699;
line-height: 120%;
}
.front .footer {
border-top: none;
}
#permalink {
float: right
}
#permalink A {
font-size: small;
}
.sr {
font-size: inherit;
margin: 0;
}
.cpanstats {
float: left;
text-align: left;
color: #bbb;
white-space: pre;
}
form.tool {
margin: 1ex;
}
.styleswitch {
text-align: right;
}