mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
502 lines
20 KiB
XML
502 lines
20 KiB
XML
<xsl:stylesheet version="1.0"
|
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
xmlns:dcq="http://purl.org/dc/qualifiers/1.0/"
|
|
xmlns:fo="http://www.w3.org/1999/XSL/Format">
|
|
<xsl:output method="html"/>
|
|
<!-- Set to 1 to show explanations by default. Set to 0 to hide them -->
|
|
<xsl:variable name="show_explanation_default" select="0" />
|
|
<!-- The characters within the Webdings font that show the triangles -->
|
|
<xsl:variable name="show_button_text" select="'▶'" />
|
|
<xsl:variable name="hide_button_text" select="'▽'" />
|
|
<!-- The suffix for names -->
|
|
<xsl:variable name="button_suffix" select="'__button'"/>
|
|
<xsl:variable name="body_suffix" select="'__body'"/>
|
|
<!-- For easy reference, the name of the button -->
|
|
<xsl:variable name="show_hide_all_button" select="'show_hide_all_button'"/>
|
|
|
|
<!-- The top-level element -->
|
|
<xsl:template match="GUIDE">
|
|
<HTML>
|
|
<HEAD>
|
|
<TITLE><xsl:value-of select="@title"/></TITLE>
|
|
<META http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
|
<LINK HREF="http://www.google.com/favicon.ico" type="image/x-icon"
|
|
rel="shortcut icon"/>
|
|
<LINK HREF="styleguide.css"
|
|
type="text/css" rel="stylesheet"/>
|
|
|
|
<SCRIPT language="javascript" type="text/javascript">
|
|
|
|
function ShowHideByName(bodyName, buttonName) {
|
|
var bodyElements = document.getElementsByName(bodyName);
|
|
if (bodyElements.length != 1) {
|
|
alert("ShowHideByName() got the wrong number of bodyElements: " + bodyElements.length);
|
|
} else {
|
|
var bodyElement = bodyElements[0];
|
|
var buttonElements = document.getElementsByName(buttonName);
|
|
var buttonElement = buttonElements[0];
|
|
if (bodyElement.style.display == "none" || bodyElement.style.display == "") {
|
|
bodyElement.style.display = "inline";
|
|
buttonElement.innerHTML = '<xsl:value-of select="$hide_button_text"/>';
|
|
} else {
|
|
bodyElement.style.display = "none";
|
|
buttonElement.innerHTML = '<xsl:value-of select="$show_button_text"/>';
|
|
}
|
|
}
|
|
}
|
|
|
|
function ShowHideAll() {
|
|
var allButtons = document.getElementsByName("show_hide_all_button");
|
|
var allButton = allButtons[0];
|
|
if (allButton.innerHTML == '<xsl:value-of select="$hide_button_text"/>') {
|
|
allButton.innerHTML = '<xsl:value-of select="$show_button_text"/>';
|
|
SetHiddenState(document.body.childNodes, "none", '<xsl:value-of select="$show_button_text"/>');
|
|
} else {
|
|
allButton.innerHTML = '<xsl:value-of select="$hide_button_text"/>';
|
|
SetHiddenState(document.body.childNodes, "inline", '<xsl:value-of select="$hide_button_text"/>');
|
|
}
|
|
}
|
|
|
|
// Recursively sets state of all children
|
|
// of a particular node.
|
|
function SetHiddenState(root, newState, newButton) {
|
|
for (var i = 0; i != root.length; i++) {
|
|
SetHiddenState(root[i].childNodes, newState, newButton);
|
|
if (root[i].className == 'showhide_button') {
|
|
root[i].innerHTML = newButton;
|
|
}
|
|
if (root[i].className == 'stylepoint_body') {
|
|
root[i].style.display = newState;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
window.onload = function() {
|
|
// if the URL contains "?showall=y", expand the details of all children
|
|
{
|
|
var showHideAllRegex = new RegExp("[\\?&](showall)=([^&#]*)");
|
|
var showHideAllValue = showHideAllRegex.exec(window.location.href);
|
|
if (showHideAllValue != null) {
|
|
if (showHideAllValue[2] == "y") {
|
|
SetHiddenState(document.body.childNodes, "inline", '<xsl:value-of select="$hide_button_text"/>');
|
|
} else {
|
|
SetHiddenState(document.body.childNodes, "none", '<xsl:value-of select="$show_button_text"/>');
|
|
}
|
|
}
|
|
var showOneRegex = new RegExp("[\\?&](showone)=([^&#]*)");
|
|
var showOneValue = showOneRegex.exec(window.location.href);
|
|
if (showOneValue != null) {
|
|
var body_name = showOneValue[2] + '<xsl:value-of select="$body_suffix"/>';
|
|
var button_name = showOneValue[2] + '<xsl:value-of select="$button_suffix"/>';
|
|
ShowHideByName(body_name, button_name);
|
|
}
|
|
|
|
}
|
|
}
|
|
</SCRIPT>
|
|
</HEAD>
|
|
<BODY>
|
|
<H1><xsl:value-of select="@title"/></H1>
|
|
<xsl:apply-templates/>
|
|
</BODY>
|
|
</HTML>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="OVERVIEW">
|
|
<xsl:variable name="button_text">
|
|
<xsl:choose>
|
|
<xsl:when test="$show_explanation_default">
|
|
<xsl:value-of select="$hide_button_text"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$show_button_text"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<DIV style="margin-left: 50%; font-size: 75%;">
|
|
<P>
|
|
Each style point has a summary for which additional information is available
|
|
by toggling the accompanying arrow button that looks this way:
|
|
<SPAN class="showhide_button" style="margin-left: 0;"><xsl:value-of select="$show_button_text"/></SPAN>.
|
|
You may toggle all summaries with the big arrow button:
|
|
</P>
|
|
<DIV style=" font-size: larger; margin-left: +2em;">
|
|
<SPAN class="showhide_button" style="font-size: 180%;">
|
|
<xsl:attribute name="onclick"><xsl:value-of select="'javascript:ShowHideAll()'"/></xsl:attribute>
|
|
<xsl:attribute name="name"><xsl:value-of select="$show_hide_all_button"/></xsl:attribute>
|
|
<xsl:attribute name="id"><xsl:value-of select="$show_hide_all_button"/></xsl:attribute>
|
|
<xsl:value-of select="$button_text"/>
|
|
</SPAN>
|
|
Toggle all summaries
|
|
</DIV>
|
|
</DIV>
|
|
<xsl:call-template name="TOC">
|
|
<xsl:with-param name="root" select=".."/>
|
|
</xsl:call-template>
|
|
<H2>Overview</H2>
|
|
<xsl:apply-templates/>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="PARTING_WORDS">
|
|
<H2>Parting Words</H2>
|
|
<xsl:apply-templates/>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="CATEGORY">
|
|
<SPAN>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<H2>
|
|
<xsl:variable name="category_name">
|
|
<xsl:call-template name="anchorname">
|
|
<xsl:with-param name="sectionname" select="@title"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:attribute name="name"><xsl:value-of select="$category_name"/></xsl:attribute>
|
|
<xsl:attribute name="id"><xsl:value-of select="$category_name"/></xsl:attribute>
|
|
<xsl:value-of select="@title"/>
|
|
</H2>
|
|
<xsl:apply-templates/>
|
|
</SPAN>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="STYLEPOINT">
|
|
<SPAN>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<xsl:variable name="stylepoint_name">
|
|
<xsl:call-template name="anchorname">
|
|
<xsl:with-param name="sectionname" select="@title"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="button_text">
|
|
<xsl:choose>
|
|
<xsl:when test="$show_explanation_default">
|
|
<xsl:value-of select="$hide_button_text"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$show_button_text"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<H3>
|
|
<A>
|
|
<xsl:attribute name="name"><xsl:value-of select="$stylepoint_name"/></xsl:attribute>
|
|
<xsl:attribute name="id"><xsl:value-of select="$stylepoint_name"/></xsl:attribute>
|
|
<xsl:value-of select="@title"/>
|
|
</A>
|
|
</H3>
|
|
<xsl:variable name="buttonName">
|
|
<xsl:value-of select="$stylepoint_name"/><xsl:value-of select="$button_suffix"/>
|
|
</xsl:variable>
|
|
<xsl:variable name="onclick_definition">
|
|
<xsl:text>javascript:ShowHideByName('</xsl:text>
|
|
<xsl:value-of select="$stylepoint_name"/><xsl:value-of select="$body_suffix"/>
|
|
<xsl:text>','</xsl:text>
|
|
<xsl:value-of select="$buttonName"/>
|
|
<xsl:text>')</xsl:text>
|
|
</xsl:variable>
|
|
<SPAN class="showhide_button">
|
|
<xsl:attribute name="onclick"><xsl:value-of select="$onclick_definition"/></xsl:attribute>
|
|
<xsl:attribute name="name"><xsl:value-of select="$buttonName"/></xsl:attribute>
|
|
<xsl:attribute name="id"><xsl:value-of select="$buttonName"/></xsl:attribute>
|
|
<xsl:value-of select="$button_text"/>
|
|
</SPAN>
|
|
<xsl:apply-templates>
|
|
<xsl:with-param name="anchor_prefix" select="$stylepoint_name" />
|
|
</xsl:apply-templates>
|
|
</SPAN>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="SUMMARY">
|
|
<xsl:param name="anchor_prefix" />
|
|
<SPAN>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<xsl:apply-templates/>
|
|
</SPAN>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="BODY">
|
|
<xsl:param name="anchor_prefix" />
|
|
<SPAN>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<BR/>
|
|
<SPAN class="stylepoint_body">
|
|
<xsl:attribute name="name"><xsl:value-of select="$anchor_prefix"/><xsl:value-of select="$body_suffix"/></xsl:attribute>
|
|
<xsl:attribute name="id"><xsl:value-of select="$anchor_prefix"/><xsl:value-of select="$body_suffix"/></xsl:attribute>
|
|
<xsl:attribute name="style">
|
|
<xsl:choose>
|
|
<xsl:when test="$show_explanation_default">display: inline</xsl:when>
|
|
<xsl:otherwise>display: none</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:attribute>
|
|
<SPAN class="link_button">
|
|
<A>
|
|
<xsl:attribute name="href">?showone=<xsl:value-of select="$anchor_prefix"/>#<xsl:value-of select="$anchor_prefix"/></xsl:attribute>
|
|
link
|
|
</A>
|
|
</SPAN>
|
|
<xsl:apply-templates/>
|
|
</SPAN>
|
|
</SPAN>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="DEFINITION">
|
|
<P>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<SPAN class="stylepoint_section">Definition: </SPAN>
|
|
<xsl:apply-templates/>
|
|
</P>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="PROS">
|
|
<P>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<SPAN class="stylepoint_section">Pros: </SPAN>
|
|
<xsl:apply-templates/>
|
|
</P>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="CONS">
|
|
<P>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<SPAN class="stylepoint_section">Cons: </SPAN>
|
|
<xsl:apply-templates/>
|
|
</P>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="DECISION">
|
|
<P>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<SPAN class="stylepoint_section">Decision: </SPAN>
|
|
<xsl:apply-templates/>
|
|
</P>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="TODO">
|
|
<P>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<SPAN style="font-size: 150%;">TODO:
|
|
<xsl:apply-templates/>
|
|
</SPAN>
|
|
</P>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="SUBSECTION">
|
|
<P>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<SPAN class="stylepoint_subsection"><xsl:value-of select="@title"/> </SPAN>
|
|
<xsl:apply-templates/>
|
|
</P>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="CODE_SNIPPET">
|
|
<SPAN>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<PRE><xsl:call-template name="print_without_leading_chars">
|
|
<xsl:with-param name="text" select="."/>
|
|
<xsl:with-param name="strip" select="1"/>
|
|
<xsl:with-param name="is_firstline" select="1"/>
|
|
<xsl:with-param name="trim_count">
|
|
<xsl:call-template name="num_leading_spaces">
|
|
<xsl:with-param name="text" select="."/>
|
|
<xsl:with-param name="max_so_far" select="1000"/>
|
|
</xsl:call-template>
|
|
</xsl:with-param>
|
|
</xsl:call-template></PRE>
|
|
</SPAN>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="BAD_CODE_SNIPPET">
|
|
<SPAN>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<PRE class="badcode"><xsl:call-template name="print_without_leading_chars">
|
|
<xsl:with-param name="text" select="."/>
|
|
<xsl:with-param name="strip" select="1"/>
|
|
<xsl:with-param name="is_firstline" select="1"/>
|
|
<xsl:with-param name="trim_count">
|
|
<xsl:call-template name="num_leading_spaces">
|
|
<xsl:with-param name="text" select="."/>
|
|
<xsl:with-param name="max_so_far" select="1000"/>
|
|
</xsl:call-template>
|
|
</xsl:with-param>
|
|
</xsl:call-template></PRE>
|
|
</SPAN>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="SYNTAX">
|
|
<I>
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<xsl:apply-templates/>
|
|
</I>
|
|
</xsl:template>
|
|
|
|
<!-- This passes through any HTML elements that the
|
|
XML doc uses for minor formatting -->
|
|
<xsl:template match="a|address|blockquote|br|center|cite|code|dd|div|dl|dt|em|hr|i|li|ol|p|pre|span|table|td|th|tr|ul|var|A|ADDRESS|BLOCKQUOTE|BR|CENTER|CITE|CODE|DD|DIV|DL|DT|EM|HR|I|LI|OL|P|PRE|SPAN|TABLE|TD|TH|TR|UL|VAR">
|
|
<xsl:element name="{local-name()}">
|
|
<xsl:copy-of select="@*"/>
|
|
<xsl:apply-templates/>
|
|
</xsl:element>
|
|
</xsl:template>
|
|
|
|
<!-- Builds the table of contents -->
|
|
<xsl:template name="TOC">
|
|
<xsl:param name="root"/>
|
|
<DIV class="toc">
|
|
<DIV class="toc_title">Table of Contents</DIV>
|
|
<TABLE>
|
|
<xsl:for-each select="$root/CATEGORY">
|
|
<TR valign="top">
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<TD>
|
|
<DIV class="toc_category">
|
|
<A>
|
|
<xsl:attribute name="href">
|
|
<xsl:text>#</xsl:text>
|
|
<xsl:call-template name="anchorname">
|
|
<xsl:with-param name="sectionname" select="@title"/>
|
|
</xsl:call-template>
|
|
</xsl:attribute>
|
|
<xsl:value-of select="@title"/>
|
|
</A>
|
|
</DIV>
|
|
</TD><TD>
|
|
<DIV class="toc_stylepoint">
|
|
<xsl:for-each select="./STYLEPOINT">
|
|
<SPAN style="padding-right: 1em; white-space:nowrap;">
|
|
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
|
|
<A>
|
|
<xsl:attribute name="href">
|
|
<xsl:text>#</xsl:text>
|
|
<xsl:call-template name="anchorname">
|
|
<xsl:with-param name="sectionname" select="@title"/>
|
|
</xsl:call-template>
|
|
</xsl:attribute>
|
|
<xsl:value-of select="@title"/>
|
|
</A>
|
|
</SPAN>
|
|
<xsl:text> </xsl:text>
|
|
</xsl:for-each>
|
|
</DIV>
|
|
</TD>
|
|
</TR>
|
|
</xsl:for-each>
|
|
</TABLE>
|
|
</DIV>
|
|
</xsl:template>
|
|
|
|
<xsl:template name="TOC_one_stylepoint">
|
|
<xsl:param name="stylepoint"/>
|
|
</xsl:template>
|
|
|
|
<!-- Creates a standard anchor given any text.
|
|
Substitutes underscore for characters unsuitable for URLs -->
|
|
<xsl:template name="anchorname">
|
|
<xsl:param name="sectionname"/>
|
|
<xsl:value-of select="translate($sectionname,' ()#','____')"/>
|
|
</xsl:template>
|
|
|
|
<!-- Given text, evaluates to the number of leading spaces. -->
|
|
<!-- TODO(csilvers): deal well with leading tabs (treat as 8 spaces?) -->
|
|
<xsl:template name="num_leading_spaces_one_line">
|
|
<xsl:param name="text"/>
|
|
<xsl:param name="current_count"/>
|
|
<xsl:choose>
|
|
<xsl:when test="starts-with($text, ' ')">
|
|
<xsl:call-template name="num_leading_spaces_one_line">
|
|
<xsl:with-param name="text" select="substring($text, 2)"/>
|
|
<xsl:with-param name="current_count" select="$current_count + 1"/>
|
|
</xsl:call-template>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$current_count"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<!-- Given a block of text, each line terminated by \n, evaluates to
|
|
the indentation-level of that text; that is, the largest number
|
|
n such that every non-blank line starts with at least n spaces. -->
|
|
<xsl:template name="num_leading_spaces">
|
|
<xsl:param name="text"/>
|
|
<xsl:param name="max_so_far"/>
|
|
<!-- TODO(csilvers): deal with case text doesn't end in a newline -->
|
|
<xsl:variable name="line" select="substring-before($text, '
')"/>
|
|
<xsl:variable name="rest" select="substring-after($text, '
')"/>
|
|
<xsl:variable name="num_spaces_this_line">
|
|
<xsl:choose>
|
|
<xsl:when test="$line=''">
|
|
<xsl:value-of select="$max_so_far"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:call-template name="num_leading_spaces_one_line">
|
|
<xsl:with-param name="text" select="$line"/>
|
|
<xsl:with-param name="current_count" select="0"/>
|
|
</xsl:call-template>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<xsl:variable name="new_max_so_far">
|
|
<xsl:choose>
|
|
<xsl:when test="$num_spaces_this_line < $max_so_far">
|
|
<xsl:value-of select="$num_spaces_this_line"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$max_so_far"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<!-- now check if we're on the last line, and if not, recurse -->
|
|
<xsl:if test="$rest=''">
|
|
<xsl:value-of select="$new_max_so_far"/>
|
|
</xsl:if>
|
|
<xsl:if test="not($rest='')">
|
|
<xsl:call-template name="num_leading_spaces">
|
|
<xsl:with-param name="text" select="$rest"/>
|
|
<xsl:with-param name="max_so_far" select="$new_max_so_far"/>
|
|
</xsl:call-template>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
<!-- Given a block of text, each line terminated by \n, and a number n,
|
|
emits the text with the first n characters of each line
|
|
deleted. If strip==1, then we omit blank lines at the beginning
|
|
and end of the text (but not the middle!) -->
|
|
<!-- TODO(csilvers): deal well with leading tabs (treat as 8 spaces?) -->
|
|
<xsl:template name="print_without_leading_chars">
|
|
<xsl:param name="text"/>
|
|
<xsl:param name="trim_count"/>
|
|
<xsl:param name="strip"/>
|
|
<xsl:param name="is_firstline"/>
|
|
<!-- TODO(csilvers): deal with case text doesn't end in a newline -->
|
|
<xsl:variable name="line" select="substring-before($text, '
')"/>
|
|
<xsl:variable name="rest" select="substring-after($text, '
')"/>
|
|
<xsl:choose>
|
|
<!-- $line (or $rest) is considered empty if we'd trim the entire line -->
|
|
<xsl:when test="($strip = '1') and ($is_firstline = '1') and
|
|
(string-length($line) <= $trim_count)">
|
|
</xsl:when>
|
|
<xsl:when test="($strip = '1') and
|
|
(string-length($rest) <= $trim_count)">
|
|
<xsl:value-of select="substring($line, $trim_count+1)"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="substring($line, $trim_count+1)"/>
|
|
<xsl:text>
</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:if test="not($rest='')">
|
|
<xsl:call-template name="print_without_leading_chars">
|
|
<xsl:with-param name="text" select="$rest"/>
|
|
<xsl:with-param name="trim_count" select="$trim_count"/>
|
|
<xsl:with-param name="strip" select="$strip"/>
|
|
<xsl:with-param name="is_firstline" select="0"/>
|
|
</xsl:call-template>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
</xsl:stylesheet>
|
|
|