Newer
Older
XML / oracle-docs.perl
#!/usr/bin/perl
#
# Basic script for generating XML markup for the major sections of the Oracle Documentation, and XSLT templates (and meta-templates, for both output formats) for transforming it.
# 
# To do:
#  * Maybe modify the script to work for any URL-based hyperlinks (e.g. <Blackboard/>, <OtagoUniversity/>).  This would mean ditching the automatic "Ora" prefix, but wouldn't require much else to implement.
#  * Generalise so that the LaTeX output is split to use a separate hyperlink for each word in the link label (to allow the links to be wrapped across lines).  HTML version doesn't need to be changed.
 

# I figure this is also a sensible place to store the root of the Oracle documentation on the department's Web server.
# Should this have a trailing slash (appropriate for standalone URL) or not (appropriate for a prefix for composite URLs)?
$oracle_documentation_root = "http://info-nts-12.otago.ac.nz/docs/oracle11gr1/";


# Here's the raw data.
# Each entry has a name (marked up as XML), a unique, short, space-less code name for it, and the actual URL.
# It's probably sensible to have the full URL here, rather than prefixing the Oracle document root, because it's easier to copy the entire URL from the Web browser when updating.
@references =
(
	# Name(0)	Code(1)	URL(2)
	"Documentation											Docs			${oracle_documentation_root}",
	"Database Administrator<apostrophe />s Guide			Admin			${oracle_documentation_root}server.111/b28310/toc.htm",
	"2 Day Developer<apostrophe />s Guide					AppDev2Day		${oracle_documentation_root}appdev.111/b28843/toc.htm",
	"Advanced Application Developer<apostrophe />s Guide	AppDevAdv		${oracle_documentation_root}appdev.111/b28424/toc.htm",
	"Object-Relational Developer<apostrophe />s Guide		AppDevOR		${oracle_documentation_root}appdev.111/b28371/toc.htm",
	"Database Concepts										Concepts		${oracle_documentation_root}server.111/b28318/toc.htm",
	"Data Warehousing Guide									DataWarehousing	${oracle_documentation_root}server.111/b28313/toc.htm",
	"Database Error Messages								Errors			${oracle_documentation_root}server.111/b28278/toc.htm",
	"SQL Reference											SQL				${oracle_documentation_root}server.111/b28286/toc.htm",
	"Java Developer<apostrophe />s Guide					Java			${oracle_documentation_root}java.111/b31225/toc.htm",
	"JDBC Developer<apostrophe />s Guide and Reference		JDBC			${oracle_documentation_root}java.111/b31224/toc.htm",
	"Database Master Glossary								Glossary		${oracle_documentation_root}mix.111/b14388/toc.htm",
	"Performance Tuning Guide								Tuning			${oracle_documentation_root}server.111/b28274/toc.htm",
	"PL/SQL Language Reference								PLSQL			${oracle_documentation_root}appdev.111/b28370/toc.htm",
	"PL/SQL Packages and Types Reference					PLSQLPkgTyp		${oracle_documentation_root}appdev.111/b28419/toc.htm",
	"Database Master Index									Index			${oracle_documentation_root}mix.111/b14387/toc.htm",
	"Database Reference										Reference		${oracle_documentation_root}server.111/b28320/toc.htm"
);

# Prefix to use in the generated template names:
$oracle_prefix = "Ora";

if ($#ARGV != 1)
{
	warn "usage: oracle-docs <section-code-regexp> (xml | xslt | xslt_html | xslt_latex | link | all)\n";
	exit;
}

$section_code = $ARGV[0];
$output_type = $ARGV[1];

if ($output_type eq "xslt") {
	print <<END_OF_HEADER
<?xml version="1.0"?>
<!-- Do not edit!  Automatically generated by oracle-docs.perl! -->
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

END_OF_HEADER
;
}

# One-off hard-coded template for a link to the root of the documentation set, using the URL as the anchor text.
# This is used in several places in the INFO 212 course book and updating them is more of a pain than implementing this!
if ($output_type eq "xslt") {
	print <<END_OF_TEMPLATE
	<xsl:template name="OraDocsURL" match="OraDocsURL">
		<xsl:call-template name="empty-hyperlink-url-internal">
			<xsl:with-param name="url">${oracle_documentation_root}</xsl:with-param>
		</xsl:call-template>
	</xsl:template>

END_OF_TEMPLATE
;
#	print "<xsl:template name=\"OraDocsURL\" match=\"OraDocsURL\"><xsl:apply-templates><xsl:element name=\"hyperlink\"><xsl:attribute name=\"url\">" . $oracle_documentation_root . "</xsl:attribute></xsl:element></xsl:apply-templates></xsl:template>\n";
}
	
foreach $current_record (@references) {
	@fields = split(/[	]+/, $current_record);
	# Only print the entries for the matching section:
	if (@fields[1] =~ /$section_code/) {
		# Print the requested stuff:
		if ($output_type eq "link") {
			print generate_doc_netlink(@fields[0], @fields[2]) . "\n";
		} elsif ($output_type eq "xml") {
			print generate_xml(@fields[1]) . "\n";
		} elsif ($output_type eq "xslt") {
			print generate_xsl_metatemplate(@fields[0], @fields[1], @fields[2]) . "\n";
		} elsif ($output_type eq "xslt_html") {
			print generate_xsl_template_for_html(@fields[0], @fields[1], @fields[2]) . "\n";
		} elsif ($output_type eq "xslt_latex") {
			print generate_xsl_template_for_latex(@fields[0], @fields[1], @fields[2]) . "\n";
		} elsif ($output_type eq "all") {
			print generate_doc_netlink(@fields[0], @fields[2]) . "\n";
			print generate_xsl_metatemplate(@fields[0], @fields[1], @fields[2]) . "\n";
			print generate_xsl_template_for_html(@fields[0], @fields[1], @fields[2]) . "\n";
			print generate_xsl_template_for_latex(@fields[0], @fields[1], @fields[2]) . "\n";
		} else {
			warn "Sorry - I don't know anything about a \"$output_type\" format.\n";
			exit;
		}
	}
}

if ($output_type eq "xslt") {
	print "</xsl:stylesheet>\n";
}



# what we really need to produce is a template that calls the hyperlink template when matched.  I think.
# Markup for a hyperlink (as defined in format-master.xml) looks like this:
# 
# 	<hyperlink url="http://wherever/">Some Web Site</hyperlink>
# 
# However, this will only match elements with a url attribute; we therefore need a new internal hyperlink that's parameterised.  Should be modal (but "call-templates" doesn't seem to like it when you give it a "mode" attribute).
# The derived xml2html.xsl and xml2latex.xsl files will need to call this hyperlink-internal template directly:
#
# 	<xsl:call-template name="hyperlink-internal" mode="hyperlink-internal">
#		<xsl:with-param name="url">http://wherever/</xsl:with-param>
#		<xsl:with-param name="label">Some Web Site</xsl:with-param>
#	</xsl:call-template>

# Generate an XSLT meta-template for generating either an HTML or a LaTeX producing template.
# Arguments: (<descriptive-label>, <entry-code>, <url>)
sub generate_xsl_metatemplate {
	return <<END_OF_TEMPLATE
	<xsl:template name="${oracle_prefix}${_[1]}" match="${oracle_prefix}${_[1]}">
		<xsl:call-template name="hyperlink-internal">
			<xsl:with-param name="url">${_[2]}</xsl:with-param>
			<xsl:with-param name="label">
				<xsl:call-template name="OracleServer" /> ${_[0]}
			</xsl:with-param>
		</xsl:call-template>
	</xsl:template>
END_OF_TEMPLATE
;
	# Nope, wrong tree here:
	return "<xsl:template name=\"" . $oracle_prefix . $_[1] . "\" match=\"" . $oracle_prefix . $_[1] . "\">" . 
		"<latex>" . "\\href{" . $_[2] . "}" . "{" . "<xsl:call-template name=\"OracleServer\" />" . " " . $_[0] . "}" . "</latex>" . 
		"<html>" . "<a href=\"" . $_[2]. "\">" . "<xsl:call-template name=\"OracleServer\" />" . " " . $_[0] . "</a>" . "</html>" . 
		"</xsl:template>";
}


# Produce the actual XML markup to be used in authoring (just to provide a handy list of them all):
# Arguments: (<entry-code>)
sub generate_xml {
	return "<" . $oracle_prefix . $_[0]. " />";
}

# Produce XML markup for a link to a section of the documentation (deprecated):
sub generate_doc_netlink {
	return "<netlink><label>" . $_[0] . "</label><target>" . $_[1] . "</target></netlink>";
}

# Generate an XSLT template for HTML output (deprecated):
sub generate_xsl_template_for_html {
		return "<xsl:template match=\"" . $_[0] . "\"><A><xsl:attribute name=\"HREF\">" . $_[1] . "</xsl:attribute>" . "<xsl:call-template name=\"OracleServer\" /> " . $_[2] . "</A></xsl:template>";
}

# Generate an XSLT template for LaTeX output (deprecated):
sub generate_xsl_template_for_latex {
	return "<xsl:template match=\"" . $_[0] . "\">\\href{" . $_[1] . "}{<xsl:call-template name=\"OracleServer\" /> " . $_[2] . "}</xsl:template>";
}