From: <bob...@us...> - 2014-01-29 03:10:58
|
Revision: 9869 http://sourceforge.net/p/docbook/code/9869 Author: bobstayton Date: 2014-01-29 03:10:55 +0000 (Wed, 29 Jan 2014) Log Message: ----------- New Perl script to convert from namespace XSL to non-namespaced XSL, in preparation for making the namespaced XSL the source base. Added Paths: ----------- trunk/releasetools/xslnons-build Added: trunk/releasetools/xslnons-build =================================================================== --- trunk/releasetools/xslnons-build (rev 0) +++ trunk/releasetools/xslnons-build 2014-01-29 03:10:55 UTC (rev 9869) @@ -0,0 +1,514 @@ +#!/usr/bin/perl -w -- # -*- Perl -*- +# +# xslns-build - generate a parallel set of DocBook5 namespaced +# stylesheet directories from a directory of +# non-namespaced stylesheets. +# +# $Id: xslns-build 9483 2012-07-09 21:38:55Z bobstayton $ +# + +my $Usage = " +USAGE: + $0 input-dir output-dir + + where: + input-dir is the directory containing namespaced stylesheets + output-dir is the destination for the non-namespaced stylesheets + + Note: an existing output-dir will be completely removed + before creating new output. +"; + +####################################################### +# Modules to use +# +use strict; +use IO::File; +use File::Basename; +use File::Path; +use File::Find; +use File::Copy; + +####################################################### +# Global variables +# +my $srcdir; +my $destdir; + +my @dirlist; +my @passthru; +my @xslfiles; + +# Regular expressions + +# namespace name regexp +my $ns = "[A-Za-z]+"; +# other names +my $n = "[A-Za-z][A-Za-z0-9]+"; +# xml names +my $w = "[A-Za-z][-A-Za-z0-9._#]+"; +# docbook element names (lowercase and numbers) +my $dbname = "[a-z][a-z0-9]+"; + +# Don't add namespace to any xsl files in these directories +my @PassthruDirs = ( +'extensions', +'profiling', +'images', +'tools', +'build', +'slides', +'template', +'website', +'wordml', +); + +# Don't add namespace to these particular files +my @PassthruFiles = ( +'html-rtf.xsl', +'html2xhtml.xsl', +'xsl2profile.xsl', +'olink.xsl', +'addns.xsl', +'stripns.xsl', +); + +umask 002; + +####################################################### +# main +# + +# Get the source and output directories + +$srcdir = $ARGV[0]; +$destdir = $ARGV[1]; + +unless ( $srcdir ) { + print "ERROR: must specify input directory of non-namespaced " + . " stylesheets. Exiting.\n"; + die "$Usage\n"; +} + +unless ( -d $srcdir ) { + print "ERROR: specified input directory does not exist. Exiting.\n"; + die "$Usage\n"; +} + +unless ( $destdir ) { + print "ERROR: must specify output directory. Exiting.\n"; + die "$Usage\n"; + +} + +# Remove any previous output completely + +if ( -d $destdir) { + print "Removing old output directory $destdir.\n"; + + unless ( rmtree($destdir) ) { + die "ERROR: cannot remove previous output directory. Exiting.\n"; + } +} + +# Create new output directory. +print "Creating the output directory $destdir.\n"; + +unless ( mkpath($destdir) ) { + die "ERROR: cannot create output directory $destdir.\n"; +} + +copyDirectories($srcdir); + +copyPassthru(); + +copyXsl(); + +addFiles(); + + +####################################################### +# copyDirectories - create the output directories +# +sub copyDirectories { + + my ($src) = @_; + + # populate @dirlist + find(\&dirlist, $src ); + + foreach my $d (@dirlist) { + $d =~ s/$srcdir/$destdir/; + print "$d\n"; + mkdir $d; + } + + +} + +####################################################### +# dirlist - list directories (used by find) +# +sub dirlist { + + if ( -d $_ ) { + push(@dirlist, $File::Find::name); + } +} + +####################################################### +# copyPassthru - copy non-XSL files to output +# +sub copyPassthru { + + # populate @passthru + find(\&passthruFiles, $srcdir ); + + foreach my $f (@passthru) { + my $dest = $f; + $dest =~ s/$srcdir/$destdir/; + print STDOUT "$f\n"; + copy ($f, $dest); + } + + +} + +####################################################### +# passthruFiles - list non-xsl files to copy +# +sub passthruFiles { + + if ( -f $_ ) { + unless ( /\.xsl$/ or /\.ent$/ ) { + push(@passthru, $File::Find::name); + } + } +} + +####################################################### +# copyXsl - copy XSL files to output, possibly filtering +# +sub copyXsl { + + # populate @xslfiles + find(\&xslFiles, $srcdir ); + + foreach my $f (@xslfiles) { + my $dest = $f; + $dest =~ s/$srcdir/$destdir/; + print STDOUT "$f\n"; + + my $basename = basename $f; + my $dirname = dirname $f; + $dest =~ m|^$destdir/(.*?)/|; + my $dir = $1; + if ( grep /^$basename$/,@PassthruFiles ) { + copy($f, $dest); + } + elsif ( grep /^$dir$/, @PassthruDirs ) { + copy($f, $dest); + } + else { + nsfilter($f, $dest); + } + } + + +} + +####################################################### +# xslFiles - list xsl files to process +# +sub xslFiles { + + if ( -f $_ ) { + if ( /\.xsl$/ or /\.ent$/ ) { + push(@xslfiles, $File::Find::name); + } + } +} + +####################################################### +# nsfilter - delete namespace prefix to element names +# +sub nsfilter { + + my ($infile, $outfile) = @_; + + # Open and read the whole file into $_ variable for parsing + my $Filehandle = IO::File->new($infile) + or die "Can't open file $infile $!\n"; + read ($Filehandle, $_, -s $infile); + $Filehandle->close; + + my $Output = IO::File->new("> $outfile") + or die "Cannot write to output file $outfile.\n"; + + # Set to autoflush + select($Output); $| = 1; + + # delete the docbook5 namespace declaration in root element + + s|xmlns:d="http://docbook.org/ns/docbook"\n?||s; + + # remove namespace d from exclude-result-prefixes + # This version if only "d" + s| exclude-result-prefixes\s*=\s*"d"\n||s; + # This version if d added to others at end + s|(exclude-result-prefixes\s*=\s*".*?) d"|$1"|s; + + # Convert stripNS to addNS + s|href="../common/addns.xsl"|href="../common/stripns.xsl"|sg; + + # Convert addNS to stripNS + s|addns\.xsl|stripns.xsl|sg; + s|with\.namespace|no.namespace|sg; + s|addNS|stripNS|sg; + s|(namesp\.\s+)add|$1cut|sg; + s|added namespace before|stripped namespace before|sg; + s|(Unable to )add( the namespace from )DB4( document)|$1strip$2DB5$3|sg; + + # change namespace test from != to = + s|(namespace-uri\(/\*\)\s*)!=(\s*['"]http://docbook.org/ns/docbook['"])|$1=$2|sg; + + + # remove d: prefix to literal tocentry in maketoc.xsl + if ($infile =~ /maketoc/) { + s|d:(tocentry)|$1|sg; + } + + # Process certain XSL attributes to remove d: namespace if needed + # and output everything using this while loop. + + while ( /^(.*?)((match|select|test|count|from|use|elements)(\s*=\s*("|'))(.*?)(\5)|(select)(\s*=\s*("|'))(.*?)(\5))/sg ) { + + my $notname = $1; + my $attname = $3; + my $prefix = $4; + my $attvalue = $6; + my $post = $7; + my $rest = $'; + + &filter($notname, $Output); + + print $Output $attname . $prefix; + + # parse the attribute value + while ( $attvalue =~ /^(.*?)($ns:)($n)(.*$)/sg ) { + + # process the leading content which is not pass through + &addnamespace($1, $Output); + + if ( $2 eq 'd:' ) { + print $Output $3; + + } + else { + print $Output $2; + print $Output $3; + } + + $attvalue = $4; # and recurse + } + + &addnamespace($attvalue, $Output); + + print $Output $post; + + $_ = $rest; + + } + + # print the leftovers + &filter($_, $Output); + + close $Output; + +} + + +# fix any special case params like certain manpage params +# that put element names inside param string + +sub filter { + my ($string, $Output) = @_; + + # Fix up index ENTITY declarations + $string = &indexentitydecl($string); + + while ( $string =~ m|^(.*?)(<xsl:param([^>]+[^/])>)(.*?)(</xsl:param>)|sg ) { + my $before = $1; + my $starttag = $2; + my $startstuff = $3; + my $value = $4; + my $endtag = $5; + my $rest = $'; + + $startstuff =~ /name="(.*?)"/; + my $pname = $1; + + print $Output $before; + print $Output $starttag; + + # add namespace to elements inside these params + if ( $pname =~ /(^refentry.manual.fallback.profile$|^refentry.source.fallback.profile$|^refentry.version.profile$|^refentry.date.profile$)/ ) { + + # while ( $value =~ /^(.*?)(\$$w|$w\(|$ns:$n|$w:|db:$n|\@$n:$n|'.*?'|&$w;|\@$w|not \(|stringlength \(|normalize-space \()(.*$)/sg ) { + + while ( $value =~ /^(.*?)($ns:)($n)(.*$)/sg ) { + + # process the leading content which is not pass through + &addnamespace($1, $Output); + + if ( $2 eq 'd:' ) { + print $Output $3; + } + else { + print $Output $2; + print $Output $3; + } + $value = $4; # and recurse + } + + &addnamespace($value, $Output); + } + else { + print $Output $value; + } + + print $Output $endtag; + + $string = $rest; + + } + + print $Output $string; + +} + +sub indexentitydecl { + my ($string) = @_; + + my $newstring = ''; + + while ( $string =~ m@^(.*?)(<!ENTITY\s+([\w.]+)\s+('|"))(.*?)(\4\s*>)@sg ) { + my $before = $1; + my $entitystart = $2; + my $entityname = $3; + my $value = $5; + my $entityend = $6; + my $rest = $'; + + $newstring .= $before; + $newstring .= $entitystart; + + while ( $value =~ /^(.*?)($ns:)($n)(.*$)/sg ) { + + # process the leading content which is not pass through + $newstring .= &namespacefilter($1); + + if ( $2 eq 'd:' ) { + $newstring .= $3; + + } + else { + $newstring .= $2; + $newstring .= $3; + } + + $value = $4; # and recurse + + } + + $newstring .= &namespacefilter($value); + + $newstring .= $entityend; + + $string = $rest; + + } + + $newstring .= $string; + + return $newstring; +} + + +# prints a filtered string to the designated output +sub addnamespace { + my ($string, $Output) = @_; + + my $newstring = &namespacefilter($string); + print $Output $newstring; +} + +# Returns a new string with namespace prefixes added +sub namespacefilter { + + my ($string) = @_; + + my $newstring = ''; + + while ( $string =~ /^(.*?)d:($dbname)(.*$)/s ) { + + my $pre = $1; + my $name = $2; + my $rest = $3; + + $newstring .= $pre; + + # pass through XSL key words and mixed case names and olink elements + if ( $name =~ /(^mod$|^div$|^and$|^or$|^ttl$|^xreftext$|^dir$|^sitemap$|^obj$|^document$|^.*[A-Z].*$)/ ) { + + # pass this name through + $newstring .= $name; + } + # pass through man template temporary elements + elsif ( $name =~ /(^cell$|^notesource$|^bold$|^italic$|^div$|^p$|^substitution$)/ ) { + + # pass this name through + $newstring .= $name; + } + # pass through references to man temporary elements + elsif ( $name =~ /(^date$|^title$|^manual$|^source$)/ and $pre =~ /refentry\.metadata/ ) { + + # pass this name through + $newstring .= $name; + } + # Pass through if preceded or followed by uppercase letters + elsif ($pre =~ /[-._A-Z]$/ || $rest =~ /^[-._A-Z]/) { + $newstring .= "d:" . $name; + } + else { + # remove the namespace prefix + $newstring .= $name; + } + + $string = $rest; + } + + # print any leftovers + $newstring .= $string; + + return $newstring; +} + + +####################################################### +# addFiles - add some new files to db5xsl +# +sub addFiles { + my $miscdir = dirname $0; + $miscdir .= '/xslnsfiles'; + print STDOUT "miscdir is $miscdir" . "\n"; + # copy("$miscdir/manpages.table.xsl", "$destdir/manpages/table.xsl"); + # copy("$miscdir/titlepage.xsl", "$destdir/template/titlepage.xsl"); + # Copy the ns VERSION file, not the copy from non-ns + copy("$destdir/VERSION", "$destdir/VERSION.xsl"); + + # delete these obsolete files. + + # Replace stripns.xsl with addns.xsl in profiling module + &nsfilter("$srcdir/profiling/profile.xsl", "$destdir/profiling/profile.xsl"); +} Property changes on: trunk/releasetools/xslnons-build ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |