mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
458 lines
16 KiB
XML
458 lines
16 KiB
XML
|
<?xml version="1.0" encoding="utf-8"?>
|
||
|
|
||
|
<!--
|
||
|
|
||
|
svn2cl.xsl - xslt stylesheet for converting svn log to a normal
|
||
|
changelog
|
||
|
|
||
|
version 0.13
|
||
|
|
||
|
Usage (replace ++ with two minus signs which aren't allowed
|
||
|
inside xml comments):
|
||
|
svn ++verbose ++xml log | \
|
||
|
xsltproc ++stringparam strip-prefix `basename $(pwd)` \
|
||
|
++stringparam linelen 75 \
|
||
|
++stringparam groupbyday yes \
|
||
|
++stringparam separate-daylogs yes \
|
||
|
++stringparam include-rev yes \
|
||
|
++stringparam include-actions yes \
|
||
|
++stringparam breakbeforemsg yes/2 \
|
||
|
++stringparam reparagraph yes \
|
||
|
++stringparam authorsfile FILE \
|
||
|
++stringparam ignore-message-starting \
|
||
|
svn2cl.xsl - > ChangeLog
|
||
|
|
||
|
This file is based on several implementations of this conversion
|
||
|
that I was not completely happy with and some other common
|
||
|
xslt constructs found on the web.
|
||
|
|
||
|
Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Arthur de Jong.
|
||
|
|
||
|
Redistribution and use in source and binary forms, with or without
|
||
|
modification, are permitted provided that the following conditions
|
||
|
are met:
|
||
|
1. Redistributions of source code must retain the above copyright
|
||
|
notice, this list of conditions and the following disclaimer.
|
||
|
2. Redistributions in binary form must reproduce the above copyright
|
||
|
notice, this list of conditions and the following disclaimer in
|
||
|
the documentation and/or other materials provided with the
|
||
|
distribution.
|
||
|
3. The name of the author may not be used to endorse or promote
|
||
|
products derived from this software without specific prior
|
||
|
written permission.
|
||
|
|
||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||
|
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||
|
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||
|
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||
|
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
|
||
|
-->
|
||
|
|
||
|
<xsl:stylesheet
|
||
|
version="1.0"
|
||
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||
|
|
||
|
<xsl:output
|
||
|
method="text"
|
||
|
encoding="utf-8"
|
||
|
media-type="text/plain"
|
||
|
omit-xml-declaration="yes"
|
||
|
standalone="yes"
|
||
|
indent="no" />
|
||
|
|
||
|
<xsl:strip-space elements="*" />
|
||
|
|
||
|
<!-- the prefix of pathnames to strip -->
|
||
|
<xsl:param name="strip-prefix" select="'/'" />
|
||
|
|
||
|
<!-- the length of a line to wrap messages at -->
|
||
|
<xsl:param name="linelen" select="75" />
|
||
|
|
||
|
<!-- whether entries should be grouped by day -->
|
||
|
<xsl:param name="groupbyday" select="'no'" />
|
||
|
|
||
|
<!-- whether to seperate log messages by empty lines -->
|
||
|
<xsl:param name="separate-daylogs" select="'no'" />
|
||
|
|
||
|
<!-- whether a revision number should be included -->
|
||
|
<xsl:param name="include-rev" select="'no'" />
|
||
|
|
||
|
<!-- whether aaction labels should be added to files -->
|
||
|
<xsl:param name="include-actions" select="'no'" />
|
||
|
|
||
|
<!-- whether the log message should start on a new line -->
|
||
|
<xsl:param name="breakbeforemsg" select="'no'" />
|
||
|
|
||
|
<!-- whether the message should be rewrapped within one paragraph -->
|
||
|
<xsl:param name="reparagraph" select="'no'" />
|
||
|
|
||
|
<!-- whether certain messages should be ignored -->
|
||
|
<xsl:param name="ignore-message-starting" select="''" />
|
||
|
|
||
|
<!-- location of authors file if any -->
|
||
|
<xsl:param name="authorsfile" select="''" />
|
||
|
<xsl:key name="author-lookup" match="author" use="@uid" />
|
||
|
<xsl:variable name="authors-top" select="document($authorsfile)/authors" />
|
||
|
|
||
|
<!-- determin the path part to strip -->
|
||
|
<xsl:variable name="strip-path">
|
||
|
<!-- if strip-prefix does not start with a slash, prepend it -->
|
||
|
<xsl:if test="not(starts-with($strip-prefix,'/'))">
|
||
|
<xsl:text>/</xsl:text>
|
||
|
</xsl:if>
|
||
|
<!-- the prefix itself -->
|
||
|
<xsl:value-of select="$strip-prefix" />
|
||
|
<!-- if strip-prefix does not start with a slash, append it -->
|
||
|
<xsl:if test="substring($strip-prefix,string-length($strip-prefix),1)!='/'">
|
||
|
<xsl:text>/</xsl:text>
|
||
|
</xsl:if>
|
||
|
</xsl:variable>
|
||
|
|
||
|
<!-- match the topmost log entry -->
|
||
|
<xsl:template match="log">
|
||
|
<xsl:choose>
|
||
|
<xsl:when test="$ignore-message-starting != ''">
|
||
|
<!-- only handle logentries with don't contain the string -->
|
||
|
<xsl:apply-templates select="logentry[not(starts-with(msg,$ignore-message-starting))]" />
|
||
|
</xsl:when>
|
||
|
<xsl:otherwise>
|
||
|
<xsl:apply-templates select="logentry" />
|
||
|
</xsl:otherwise>
|
||
|
</xsl:choose>
|
||
|
<!-- add newlines at the end of the changelog -->
|
||
|
<xsl:text> </xsl:text>
|
||
|
</xsl:template>
|
||
|
|
||
|
<!-- format one entry from the log -->
|
||
|
<xsl:template match="logentry">
|
||
|
<xsl:choose>
|
||
|
<!-- if we're grouping we should omit some headers -->
|
||
|
<xsl:when test="$groupbyday='yes'">
|
||
|
<!-- fetch previous entry's date -->
|
||
|
<xsl:variable name="prevdate">
|
||
|
<xsl:apply-templates select="preceding-sibling::logentry[position()=1]/date" />
|
||
|
</xsl:variable>
|
||
|
<!-- fetch previous entry's author -->
|
||
|
<xsl:variable name="prevauthor">
|
||
|
<xsl:value-of select="normalize-space(preceding-sibling::logentry[position()=1]/author)" />
|
||
|
</xsl:variable>
|
||
|
<!-- fetch this entry's date -->
|
||
|
<xsl:variable name="date">
|
||
|
<xsl:apply-templates select="date" />
|
||
|
</xsl:variable>
|
||
|
<!-- fetch this entry's author -->
|
||
|
<xsl:variable name="author">
|
||
|
<xsl:value-of select="normalize-space(author)" />
|
||
|
</xsl:variable>
|
||
|
<!-- check if header is changed -->
|
||
|
<xsl:if test="($prevdate!=$date) or ($prevauthor!=$author)">
|
||
|
<!-- add newline -->
|
||
|
<xsl:if test="not(position()=1)">
|
||
|
<xsl:text> </xsl:text>
|
||
|
</xsl:if>
|
||
|
<!-- date -->
|
||
|
<xsl:value-of select="$date" />
|
||
|
<!-- two spaces -->
|
||
|
<xsl:text>  </xsl:text>
|
||
|
<!-- author's name -->
|
||
|
<xsl:apply-templates select="author" />
|
||
|
<!-- two newlines -->
|
||
|
<xsl:text> </xsl:text>
|
||
|
<xsl:if test="$separate-daylogs!='yes'"><xsl:text> </xsl:text></xsl:if>
|
||
|
</xsl:if>
|
||
|
</xsl:when>
|
||
|
<!-- write the log header -->
|
||
|
<xsl:otherwise>
|
||
|
<!-- add newline -->
|
||
|
<xsl:if test="not(position()=1)">
|
||
|
<xsl:text> </xsl:text>
|
||
|
</xsl:if>
|
||
|
<!-- date -->
|
||
|
<xsl:apply-templates select="date" />
|
||
|
<!-- two spaces -->
|
||
|
<xsl:text>  </xsl:text>
|
||
|
<!-- author's name -->
|
||
|
<xsl:apply-templates select="author" />
|
||
|
<!-- two newlines -->
|
||
|
<xsl:text> </xsl:text>
|
||
|
</xsl:otherwise>
|
||
|
</xsl:choose>
|
||
|
<!-- get paths string -->
|
||
|
<xsl:variable name="paths">
|
||
|
<xsl:apply-templates select="paths" />
|
||
|
</xsl:variable>
|
||
|
<!-- get revision number -->
|
||
|
<xsl:variable name="rev">
|
||
|
<xsl:if test="$include-rev='yes'">
|
||
|
<xsl:text>[r</xsl:text>
|
||
|
<xsl:value-of select="@revision" />
|
||
|
<xsl:text>] </xsl:text>
|
||
|
</xsl:if>
|
||
|
</xsl:variable>
|
||
|
<!-- trim trailing newlines -->
|
||
|
<xsl:variable name="msg">
|
||
|
<!-- add a line break before the log message -->
|
||
|
<xsl:choose>
|
||
|
<xsl:when test="$breakbeforemsg='yes'">
|
||
|
<xsl:text> </xsl:text>
|
||
|
</xsl:when>
|
||
|
<xsl:when test="number($breakbeforemsg)>0">
|
||
|
<xsl:call-template name="newlines">
|
||
|
<xsl:with-param name="count" select="number($breakbeforemsg)" />
|
||
|
</xsl:call-template>
|
||
|
</xsl:when>
|
||
|
</xsl:choose>
|
||
|
<xsl:call-template name="trim-newln">
|
||
|
<xsl:with-param name="txt" select="msg" />
|
||
|
</xsl:call-template>
|
||
|
</xsl:variable>
|
||
|
<!-- add newline here if separate-daylogs is in effect -->
|
||
|
<xsl:if test="$groupbyday='yes' and $separate-daylogs='yes'"><xsl:text> </xsl:text></xsl:if>
|
||
|
<!-- first line is indented (other indents are done in wrap template) -->
|
||
|
<xsl:text>	* </xsl:text>
|
||
|
<!-- set up the text to wrap -->
|
||
|
<xsl:variable name="txt">
|
||
|
<xsl:value-of select="$rev" />
|
||
|
<xsl:if test="$paths!=''">
|
||
|
<xsl:value-of select="concat($paths,': ')" />
|
||
|
</xsl:if>
|
||
|
<xsl:value-of select="$msg" />
|
||
|
</xsl:variable>
|
||
|
<!-- print the paths and message nicely wrapped -->
|
||
|
<xsl:call-template name="wrap">
|
||
|
<xsl:with-param name="txt" select="$txt" />
|
||
|
</xsl:call-template>
|
||
|
</xsl:template>
|
||
|
|
||
|
<!-- format date -->
|
||
|
<xsl:template match="date">
|
||
|
<xsl:variable name="date" select="normalize-space(.)" />
|
||
|
<!-- output date part -->
|
||
|
<xsl:value-of select="substring($date,1,10)" />
|
||
|
<!-- output time part -->
|
||
|
<xsl:if test="$groupbyday!='yes'">
|
||
|
<xsl:text> </xsl:text>
|
||
|
<xsl:value-of select="substring($date,12,5)" />
|
||
|
</xsl:if>
|
||
|
</xsl:template>
|
||
|
|
||
|
<!-- format author -->
|
||
|
<xsl:template match="author">
|
||
|
<xsl:variable name="uid" select="normalize-space(.)" />
|
||
|
<!-- try to lookup author in authorsfile -->
|
||
|
<xsl:choose>
|
||
|
<xsl:when test="$authorsfile!=''">
|
||
|
<xsl:for-each select="$authors-top">
|
||
|
<xsl:variable name="author" select="key('author-lookup',$uid)" />
|
||
|
<!-- present result -->
|
||
|
<xsl:choose>
|
||
|
<xsl:when test="string($author/.)">
|
||
|
<xsl:apply-templates select="$author/node()" mode="copy" />
|
||
|
</xsl:when>
|
||
|
<xsl:otherwise>
|
||
|
<xsl:value-of select="$uid" />
|
||
|
</xsl:otherwise>
|
||
|
</xsl:choose>
|
||
|
</xsl:for-each>
|
||
|
</xsl:when>
|
||
|
<xsl:otherwise>
|
||
|
<xsl:value-of select="$uid" />
|
||
|
</xsl:otherwise>
|
||
|
</xsl:choose>
|
||
|
</xsl:template>
|
||
|
|
||
|
<!-- copy but normalize text -->
|
||
|
<xsl:template match="text()" mode="copy">
|
||
|
<xsl:value-of select="normalize-space(.)" />
|
||
|
</xsl:template>
|
||
|
|
||
|
<!-- simple copy template -->
|
||
|
<xsl:template match="@*|node()" mode="copy">
|
||
|
<xsl:copy>
|
||
|
<xsl:apply-templates select="@*|node()" mode="copy" />
|
||
|
</xsl:copy>
|
||
|
</xsl:template>
|
||
|
|
||
|
<!-- present a list of paths names -->
|
||
|
<xsl:template match="paths">
|
||
|
<xsl:choose>
|
||
|
<!-- only handle paths that begin with the path and strip the path -->
|
||
|
<xsl:when test="$strip-prefix != ''">
|
||
|
<!-- filter on all entries within directory -->
|
||
|
<xsl:for-each select="path[starts-with(concat(normalize-space(.),'/'),$strip-path)]">
|
||
|
<xsl:sort select="normalize-space(.)" data-type="text" />
|
||
|
<!-- unless we are the first entry, add a comma -->
|
||
|
<xsl:if test="not(position()=1)">
|
||
|
<xsl:text>, </xsl:text>
|
||
|
</xsl:if>
|
||
|
<!-- get path part -->
|
||
|
<xsl:variable name="path" select="substring(normalize-space(.),string-length($strip-path)+1)" />
|
||
|
<!-- translate empty string to dot and print result -->
|
||
|
<xsl:if test="$path = ''">
|
||
|
<xsl:text>.</xsl:text>
|
||
|
</xsl:if>
|
||
|
<xsl:value-of select="$path" />
|
||
|
<!-- add the action flag -->
|
||
|
<xsl:if test="$include-actions='yes'">
|
||
|
<xsl:apply-templates select="." mode="action"/>
|
||
|
</xsl:if>
|
||
|
</xsl:for-each>
|
||
|
</xsl:when>
|
||
|
<!-- print a simple list of all paths -->
|
||
|
<xsl:otherwise>
|
||
|
<xsl:for-each select="path">
|
||
|
<xsl:sort select="normalize-space(.)" data-type="text" />
|
||
|
<!-- unless we are the first entry, add a comma -->
|
||
|
<xsl:if test="not(position()=1)">
|
||
|
<xsl:text>, </xsl:text>
|
||
|
</xsl:if>
|
||
|
<!-- print the path name -->
|
||
|
<xsl:value-of select="normalize-space(.)" />
|
||
|
<!-- add the action flag -->
|
||
|
<xsl:if test="$include-actions='yes'">
|
||
|
<xsl:apply-templates select="." mode="action"/>
|
||
|
</xsl:if>
|
||
|
</xsl:for-each>
|
||
|
</xsl:otherwise>
|
||
|
</xsl:choose>
|
||
|
</xsl:template>
|
||
|
|
||
|
<xsl:template match="path" mode="action">
|
||
|
<xsl:choose>
|
||
|
<xsl:when test="@action='D'">
|
||
|
<xsl:text>[DEL]</xsl:text>
|
||
|
</xsl:when>
|
||
|
<xsl:when test="@copyfrom-path">
|
||
|
<xsl:text>[CPY]</xsl:text>
|
||
|
</xsl:when>
|
||
|
<xsl:when test="@action='A'">
|
||
|
<xsl:text>[ADD]</xsl:text>
|
||
|
</xsl:when>
|
||
|
</xsl:choose>
|
||
|
</xsl:template>
|
||
|
|
||
|
<!-- string-wrapping template -->
|
||
|
<xsl:template name="wrap">
|
||
|
<xsl:param name="txt" />
|
||
|
<xsl:variable name="normtxt" select="normalize-space($txt)" />
|
||
|
<xsl:choose>
|
||
|
<xsl:when test="contains($txt,' ')">
|
||
|
<!-- text contains newlines, do the first line -->
|
||
|
<xsl:call-template name="wrap">
|
||
|
<xsl:with-param name="txt" select="substring-before($txt,' ')" />
|
||
|
</xsl:call-template>
|
||
|
<!-- print tab -->
|
||
|
<xsl:text>	  </xsl:text>
|
||
|
<!-- wrap the rest of the text -->
|
||
|
<xsl:call-template name="wrap">
|
||
|
<xsl:with-param name="txt" select="substring-after($txt,' ')" />
|
||
|
</xsl:call-template>
|
||
|
</xsl:when>
|
||
|
<xsl:when test="(string-length($normtxt) < (($linelen)-9)) or not(contains($normtxt,' '))">
|
||
|
<!-- this is easy, nothing to do -->
|
||
|
<xsl:value-of select="$normtxt" />
|
||
|
<!-- add newline -->
|
||
|
<xsl:text> </xsl:text>
|
||
|
</xsl:when>
|
||
|
<xsl:otherwise>
|
||
|
<!-- find the first line -->
|
||
|
<xsl:variable name="tmp" select="substring($normtxt,1,(($linelen)-9))" />
|
||
|
<xsl:variable name="line">
|
||
|
<xsl:choose>
|
||
|
<!-- if our attempt contains spaces wrap on that -->
|
||
|
<xsl:when test="contains($tmp,' ')">
|
||
|
<xsl:call-template name="find-line">
|
||
|
<xsl:with-param name="txt" select="$tmp" />
|
||
|
</xsl:call-template>
|
||
|
</xsl:when>
|
||
|
<!-- otherwise use the first non-space characters from the text -->
|
||
|
<xsl:otherwise>
|
||
|
<xsl:value-of select="substring-before($normtxt,' ')" />
|
||
|
</xsl:otherwise>
|
||
|
</xsl:choose>
|
||
|
</xsl:variable>
|
||
|
<!-- print line -->
|
||
|
<xsl:value-of select="$line" />
|
||
|
<!-- print newline and tab -->
|
||
|
<xsl:text> 	  </xsl:text>
|
||
|
<!-- wrap the rest of the text -->
|
||
|
<xsl:call-template name="wrap">
|
||
|
<xsl:with-param name="txt" select="normalize-space(substring($normtxt,string-length($line)+1))" />
|
||
|
</xsl:call-template>
|
||
|
</xsl:otherwise>
|
||
|
</xsl:choose>
|
||
|
</xsl:template>
|
||
|
|
||
|
<!-- template to trim line to contain space as last char -->
|
||
|
<xsl:template name="find-line">
|
||
|
<xsl:param name="txt" />
|
||
|
<xsl:choose>
|
||
|
<xsl:when test="substring($txt,string-length($txt),1)=' '">
|
||
|
<xsl:value-of select="substring($txt,1,string-length($txt)-1)" />
|
||
|
</xsl:when>
|
||
|
<xsl:otherwise>
|
||
|
<xsl:call-template name="find-line">
|
||
|
<xsl:with-param name="txt" select="substring($txt,1,string-length($txt)-1)" />
|
||
|
</xsl:call-template>
|
||
|
</xsl:otherwise>
|
||
|
</xsl:choose>
|
||
|
</xsl:template>
|
||
|
|
||
|
<!-- template to trim trailing and starting newlines -->
|
||
|
<xsl:template name="trim-newln">
|
||
|
<xsl:param name="txt" />
|
||
|
<xsl:choose>
|
||
|
<!-- find starting newlines -->
|
||
|
<xsl:when test="substring($txt,1,1) = ' '">
|
||
|
<xsl:call-template name="trim-newln">
|
||
|
<xsl:with-param name="txt" select="substring($txt,2)" />
|
||
|
</xsl:call-template>
|
||
|
</xsl:when>
|
||
|
<!-- find trailing newlines -->
|
||
|
<xsl:when test="substring($txt,string-length($txt),1) = ' '">
|
||
|
<xsl:call-template name="trim-newln">
|
||
|
<xsl:with-param name="txt" select="substring($txt,1,string-length($txt)-1)" />
|
||
|
</xsl:call-template>
|
||
|
</xsl:when>
|
||
|
<!-- if the message has paragraphs, find the first one -->
|
||
|
<xsl:when test="$reparagraph='yes' and contains($txt,' ')">
|
||
|
<!-- remove newlines from first paragraph -->
|
||
|
<xsl:value-of select="normalize-space(substring-before($txt,' '))" />
|
||
|
<!-- paragraph separator -->
|
||
|
<xsl:text> </xsl:text>
|
||
|
<!-- do the rest of the text -->
|
||
|
<xsl:call-template name="trim-newln">
|
||
|
<xsl:with-param name="txt" select="substring-after($txt,' ')" />
|
||
|
</xsl:call-template>
|
||
|
</xsl:when>
|
||
|
<!-- remove more single newlines -->
|
||
|
<xsl:when test="$reparagraph='yes'">
|
||
|
<xsl:value-of select="normalize-space($txt)" />
|
||
|
</xsl:when>
|
||
|
<!-- no newlines found, we're done -->
|
||
|
<xsl:otherwise>
|
||
|
<xsl:value-of select="$txt" />
|
||
|
</xsl:otherwise>
|
||
|
</xsl:choose>
|
||
|
</xsl:template>
|
||
|
|
||
|
<!-- insert a number of newlines -->
|
||
|
<xsl:template name="newlines">
|
||
|
<xsl:param name="count" />
|
||
|
<xsl:text> </xsl:text>
|
||
|
<xsl:if test="$count>1">
|
||
|
<xsl:call-template name="newlines">
|
||
|
<xsl:with-param name="count" select="($count)-1" />
|
||
|
</xsl:call-template>
|
||
|
</xsl:if>
|
||
|
</xsl:template>
|
||
|
|
||
|
</xsl:stylesheet>
|