Optional XSL stylesheets and support - prototypes

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13566 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Neil Williams 2006-03-09 16:54:44 +00:00
parent 32cd6f4716
commit 1a775d7119
10 changed files with 3127 additions and 1 deletions

View File

@ -1,3 +1,20 @@
2006-03-09 Neil Williams <linux@codehelp.co.uk>
* src/optional/xsl : New directory for optional XSL
* src/optional/xsl/vcard-gnccustomer.pl : Perl script
to create QSF from VCards
* src/optional/xsl/gnucash-gnccustomer-vcard2.xsl :
XSL to generate vcards from QSF (gncCustomer)
* src/optional/xsl/gnucash-std.xsl : Common routines
for gnucash XSL stylesheets
* src/optional/xsl/Makefile.am : Don't build, just install.
* src/optional/xsl/string.xsl : xsltsl standard library XSL
in place until available as a package.
* src/optional/xsl/README : Notes on using XSL and examples.
* src/optional/xsl/date-time.xsl : xsltsl standard library.
* src/optional/Makefile.am : install only.
* configure.in : Add instruction to build a Makefile in
src/optional/xsl
2006-03-09 Neil Williams <linux@codehelp.co.uk>
* src/business/business-core/gncInvoice.c : Enable

View File

@ -2228,6 +2228,7 @@ AC_CONFIG_FILES(po/Makefile.in
src/optional/Makefile
src/optional/swig/Makefile
src/optional/swig/examples/Makefile
src/optional/xsl/Makefile
src/pixmaps/Makefile
src/quotes/Makefile
src/register/Makefile

View File

@ -6,4 +6,4 @@
# get this to work (automake 1.4p5).
SUBDIRS =
DIST_SUBDIRS = swig
DIST_SUBDIRS = swig xsl

View File

@ -0,0 +1,13 @@
xsldir = ${datadir}/xml/gnucash/xsl
xsl_DATA = \
README \
date-time.xsl \
gnucash-std.xsl \
string.xsl \
gnucash-gnccustomer-vcard2.xsl \
vcard-gnccustomer.pl
EXTRA_DIST = \
${xsl_DATA}

98
src/optional/xsl/README Normal file
View File

@ -0,0 +1,98 @@
GnuCash, XSL and QSF.
====================
If you need to convert gnucash QSF data into other formats, take a look at the example
stylesheets installed with gnucash. You are welcome to contribute new or amended
stylesheets - just post them on the QOF-devel mailing list.
http://lists.sourceforge.net/lists/listinfo/qof-devel
Depending on your package manager, the XSL stylesheets should be installed in
/usr/share/xml/gnucash/xsl/, or on Fink /sw/share/xml/gnucash/xsl/.
Current stylesheets are works in progress, but include:
· gnucash-gnccustomer-vcard2.xsl
This stylesheet converts QSF export gnucash customer data into a brief Vcard,
suitable for upload to Kaddressbook. Each VCard is written into a separate .vcf
file, named after the contact described in the pilot_address records. Spaces are
replaced with underscores. Specify the '-o dir/' option to xsltproc to output all
vcards into a directory.
· Others
Stylesheets for ICS, vcal and possibly LDAP are planned. Any plain text, XML or HTML
format can be generated, theoretically. If you have a request for an XSL stylesheet
or if you have a stylesheet you would like to make available to others, mention it
on the QOF-devel mailing list.
Also included is a perl script:
· vcard-gnccustomer.pl
The script uses the Text::vCard::Addressbook CPAN module to parse VCard files,
including those from other applications, into QSF XML that could be imported into
gnucash and merged into your gnucash customer list. With a few tweaks, this could
also be configured to create QSF XML suitable for gnucash vendor or employee records.
You are free to copy and modify these stylesheets to your own requirements, including
translations and customised formats. Depending on your package manager, this is often
best done by copying the installed file to a local directory before modifying it.
GnuCash does not reference these stylesheets directly. If your modifications could be
useful to others, please contribute them to gnucash via the QOF-devel mailing list or
gnucash-devel mailing list. Submitted stylesheets should be licenced under the GNU GPL.
LOCALISATION (l10N) OF STYLESHEET OUTPUT.
========================================
Later HTML stylesheets will support providing translatable strings and user-specific
encodings via external parameters. This can make the command line very long so is best
performed using a script. Each descriptive word in the output is configured as a string
parameter for the stylesheet and can be replaced with a translated version. HTML output
supports setting the HTML language (as would be specified in the <html> lang attribute)
and the encoding (as would be specified in the <meta> charset value in the content
attribute). If you use these stylesheets via a scripting language - like bash, PHP or
Perl - you could automate the translation by passing values obtained from a normal get-
text PO file. Copy the translatable strings into your script file as normal variables
then mark up those variables for translation by gettext. When the script is called, get-
text will assign the translated values to the variables and your script can simply echo
those values to the calls to the XSL parser routines.
It is important that the HTML language and the encoding match each other AND the
expected content of the HTML output generated from the gnucash QSF data.
When providing translated strings, the same constraints apply as if you were using get-
text and a normal PO file: the context and format of the translation should match the
intention expressed in the default value of the parameter. If the default is plural, the
translation should be plural. If the default is capitalised, the translation should be
capitalised - subject to grammatical rules for that language - even if the parameter
name itself is not capitalised.
Each stylesheet specifies the translatable strings in a block near the top of the file,
marked as for the attention of translators. Common settings, like the HTML language
parameter and the encoding support, are in the gnucash-std.xsl stylesheet and are
available in all HTML stylesheets by using the string parameters html_lang and encoding.
For more information, please ask on the gnucash-devel mailing list, the QOF-devel mailing
list or see the pilot-qof source: http://pilot-qof.sourceforge.net/
EXAMPLES
========
Convert a QSF XML file containing gncCustomer records, into individual VCard .vcf files
in the vcards/ directory - which must already exist. Files are named according to either
the company or name of the gncAddress record.
$ xsltproc -o vcards/ gnucash-gnccustomer-vcard2.xsl addresses.xml
This example is based on an "in-progress" QSF invoice stylesheet for gnucash that is based
on the existing pilot-qof HTML invoice stylesheet. It overrides the default mileage-rate
(0.30 currency units per unit distance) and the default hourly-rate (20 currency units per
hour) provided by the stylesheet with user specific values. The example is here just to
indicate how --stringparam would be used.
$ xsltproc --stringparam mileage-rate 0.45 --stringparam hourly-rate 21 -o invoices/
pilot-qof-invoice-xhtml.xsl invoice.xml

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:qof-qsf="http://qof.sourceforge.net/" xmlns:str="http://xsltsl.org/string" version="1.1">
<xsl:import href="string.xsl"/>
<!-- our own gnucash standard routines -->
<xsl:import href="gnucash-std.xsl"/>
<xsl:output method="text"/>
<!-- Representing QSF gncAddress data in a 2.1 extended VCard
This stylesheet converts the GnuCash output from Export Customers
into a simple Vcard, suitable for import into KAdddressbook. For other
VCard support (e.g. for mobile phones), see other vcard XSL stylesheets in the
gnucash collection.
Each VCard is written into a separate .vcf file, named after the
contact described in the gncAddress records. Spaces are replaced with
underscores. Specify the '-o dir/' option to xsltproc to output all vcards
into a directory.
-->
<!-- Licence
This file is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-->
<xsl:template match="/*/qof-qsf:book/qof-qsf:object[@type='gncAddress']">
<xsl:text>TEL;TYPE=WORK:</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='phone']"/>
<xsl:text>&#10;TEL;TYPE=FAX:</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='fax']"/>
<xsl:text>&#10;EMAIL:</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='email']"/>
<xsl:text>&#10;ADR;TYPE=work:;;</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='number']"/>
<xsl:text>;</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='street']"/>
<xsl:text>;</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='locality']"/>
<xsl:text>;</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='city']"/>
<xsl:text>&#10;N:</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='name']"/>
<xsl:text>&#10;</xsl:text>
</xsl:template>
<xsl:template match="/">
<xsl:for-each select="/*/qof-qsf:book/qof-qsf:object[@type='gncCustomer']">
<xsl:variable name="contactName">
<xsl:value-of select="qof-qsf:string[@type='name']"/>
</xsl:variable>
<xsl:variable name="card_title">
<xsl:call-template name="get_chunk_name">
<xsl:with-param name="entryName" select="$contactName"/>
</xsl:call-template>
</xsl:variable>
<!-- chunking support -->
<xsl:document href="{$card_title}.vcf" method="text">
<xsl:text>BEGIN:VCARD&#10;VERSION:2.1&#10;</xsl:text>
<xsl:call-template name="locate_child">
<xsl:with-param name="customer_object" select="."/>
</xsl:call-template>
<xsl:text>END:VCARD&#10;</xsl:text>
</xsl:document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,140 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:qof-qsf="http://qof.sourceforge.net/" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:dt="http://xsltsl.org/date-time" xmlns:str="http://xsltsl.org/string" version="1.0" exclude-result-prefixes="qof-qsf html dt str">
<xsl:import href="date-time.xsl"/>
<xsl:import href="string.xsl"/>
<!--This stylesheet contains standard templates for QOF QSF.-->
<!--This is only a working prototype -->
<!-- Licence
This file is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-->
<!-- Translation support via external parameters -->
<xsl:param name="html_lang">en</xsl:param>
<xsl:param name="encoding">iso-8859-15</xsl:param>
<!-- Convert gnc_numeric notation to an XSL number -->
<xsl:template name="numeric_to_double">
<xsl:param name="numeric_string"/>
<xsl:variable name="before" select="substring-before($numeric_string, '/')"/>
<xsl:variable name="after" select="substring-after($numeric_string, '/')"/>
<xsl:variable name="numeric" select="$before div $after"/>
<xsl:value-of select="number($numeric)"/>
</xsl:template>
<xsl:template name="get_chunk_name">
<xsl:param name="entryName"/>
<xsl:param name="entryCompany"/>
<xsl:variable name="result">
<xsl:choose>
<xsl:when test="$entryName = ''">
<xsl:call-template name="str:subst">
<xsl:with-param name="text" select="$entryCompany"/>
<xsl:with-param name="replace">
<xsl:text> </xsl:text>
</xsl:with-param>
<xsl:with-param name="with">
<xsl:text>_</xsl:text>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="temp">
<xsl:call-template name="str:subst">
<xsl:with-param name="text" select="$entryName"/>
<xsl:with-param name="replace">
<xsl:text> </xsl:text>
</xsl:with-param>
<xsl:with-param name="with">
<xsl:text>_</xsl:text>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="str:subst">
<xsl:with-param name="text" select="$temp"/>
<xsl:with-param name="replace">
<xsl:text>;</xsl:text>
</xsl:with-param>
<xsl:with-param name="with">
<xsl:text>_</xsl:text>
</xsl:with-param>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="$result"/>
</xsl:template>
<xsl:template name="prepare_address_div">
<xsl:param name="address_object" select="."/>
<xsl:comment>this address panel can be located precisely using CSS</xsl:comment>
<xsl:text>&#10;</xsl:text>
<div class="address">
<h2>Customer address</h2>
<p class="address_para">
<xsl:text>&#10;</xsl:text>
<b>
<xsl:value-of select="qof-qsf:string[@type='entryCompany']"/>
</b>
<br/>
<xsl:text>&#10;</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='entryAddress']"/>
<br/>
<xsl:text>&#10;</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='entryCity']"/>
<br/>
<xsl:text>&#10;</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='entryState']"/>
<br/>
<xsl:text>&#10;</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='entryZip']"/>
<br/>
<xsl:text>&#10;</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='entryCountry']"/>
<br/>
<br/>
<xsl:text>&#10;</xsl:text>
<xsl:value-of select="qof-qsf:string[@type='entryPhone1']"/>
</p>
</div>
</xsl:template>
<xsl:template name="vcard_safe">
<xsl:param name="address_string"/>
<xsl:variable name="safe_string">
<xsl:call-template name="str:subst">
<xsl:with-param name="text" select="$entryCompany"/>
<xsl:with-param name="replace">
<xsl:text>,</xsl:text>
</xsl:with-param>
<xsl:with-param name="with">
<xsl:text>\,</xsl:text>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$safe_string"/>
</xsl:template>
<!-- hierarchy support -->
<xsl:template name="locate_child">
<xsl:param name="customer_object"/>
<xsl:variable name="cust_addr_guid">
<xsl:value-of select="qof-qsf:guid[@type='addr']"/>
</xsl:variable>
<xsl:for-each select="/*/qof-qsf:book/qof-qsf:object[@type='gncAddress']">
<xsl:variable name="addr_guid">
<xsl:value-of select="qof-qsf:guid[@type='guid']"/>
</xsl:variable>
<xsl:if test="$addr_guid = $cust_addr_guid">
<xsl:variable name="set" select="."/>
<xsl:apply-templates select="$set"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

1233
src/optional/xsl/string.xsl Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,103 @@
#!/usr/bin/perl -w
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
use Text::vCard::Addressbook;
use strict;
use vars qw($address_book $hex_string $num $c $d $e $i $vcard $names $name $fullname $email $address $addresses $phones $phone $filename $usage $encoding);
############### USER CONFIGURATION ####################
# Change to the encoding for you locale if your VCF data
# contains accented characters etc.
$encoding = 'UTF-8';
############### END CONFIGURATION ####################
# About
#
# This is a very simple file and should be simple to customise.
# A similar file is included in pilot-qof. Currently, the script
# needs to be told where to find the VCF file to transform and
# expects the user to redirect output to a file:
# $ perl vcard-gnccustomer.pl contact.vcf > contact.xml
$usage = $#ARGV + 1;
if($usage < 1)
{
print ("Error: please specify a .vcf file.\n\n");
exit;
}
$filename = $ARGV[0];
$address_book = Text::vCard::Addressbook->new({
'source_file' => $filename, });
# generate a temporary GUID to relate the address to the customer
$hex_string = '';
for($d = 1;$d < 5;$d++)
{
for($c = 1; $c < 8; $c++)
{
$num = (int(rand(99)) + 1) * 10**$c;
}
$hex_string .= sprintf("%x", $num);
}
print "<?xml version=\"1.0\" encoding=\"$encoding\"?>\n";
print "<qof-qsf xmlns=\"http://qof.sourceforge.net/\">\n";
print " <book count=\"1\">\n";
print " <book-guid/>\n";
print " <object type=\"gncAddress\" count=\"1\">\n";
foreach $vcard ($address_book->vcards()) {
$names = $vcard->get({ 'node_type' => 'name' });
foreach $name (@{$names}){
if($name->given()) {
$fullname = $name->given() . " " . $name->family();
}
else {
$fullname = $name->family();
}
&wrap_in_qsf($fullname, "name");
}
$phones = $vcard->get('tel');
$i = 0;
foreach $phone (@{$phones}){
if($i == 0) {
&wrap_in_qsf($phone->value(), "phone");
}
if($i == 1) {
&wrap_in_qsf($phone->value(), "fax");
}
$i++;
}
$email = $vcard->get('email');
foreach $e (@{$email}){ &wrap_in_qsf($e->value(), "email"); }
$addresses = $vcard->get({ 'node_type' => 'addresses' });
foreach $address (@{$addresses}) {
&wrap_in_qsf($address->street(), "street");
&wrap_in_qsf($address->city(), "city");
&wrap_in_qsf($address->region(), "locality");
}
print " <guid type=\"guid\">$hex_string</guid>\n";
}
print " </object>\n";
print " <object type=\"gncCustomer\" count=\"1\">\n";
&wrap_in_qsf($fullname, "name");
print " <boolean type=\"active\">true</boolean\n";
print " <guid type=\"addr\">$hex_string</guid>\n";
print " </book>\n";
print "</qof-qsf>\n\n";
sub wrap_in_qsf()
{
if($_[0]) { print " <string type=\"$_[1]\">$_[0]</string>\n"; }
else { print " <string type=\"$_[1]\"/>\n"; }
};