Meta:Tools/Wiki conversions/Wiki to PDF/Latex and XSL

提供: wiki
移動先: 案内検索

Introduction

I've tidied up my script a little bit so here's the first release, a number of things a broke, including but not limited to:

1) images float around in odd places
2) notes dont linewrap for some reason
3) long monospaced lines dont line wrap
4) tables are not yet implemented


How To Use The Script

Here are all the files you will need:

Makefile (or see reference below)
blender.xsl (or see reference below)
structure_en.xml (or see reference below)
structure_it.xml (or see reference below)

If you want to see what the result is like so far then have a look at:

manual_en.pdf
manual_it.pdf


First you need to download all the html pages for a given translation and the images in the uploads directory, this can be done via "make download" in the script.

Then you either run "make en" or "make it" depending on what language you want.

The script requires saxon to run the XSLT script that turns the wiki into latex, and then it requires pdflatex to turn the latex into a pdf. The "make download" requires wget.

Conclusion

All that needs to be done now is to fix the few remaining bugs and then do a bit of styling on it to make it look a bit more trendy and less 1960's maths text book :)

Comments, questions and help are all appreciated

Alex (doc-board)

References

Makefile

LATEX = pdflatex -interaction=nonstopmode
XTRANSFORM = java net.sf.saxon.Transform

default: en

clean:
	rm -f *~ *.dvi *.pdf *.log *.aux *.toc *.out
veryclean: clean
	rm -f *.tex

# Download the wiki
download:
	wget -m -p -np http://mediawiki.blender.org/index.php/Manual

# English
en: texen pdfen

pdfen:
	$(LATEX) manual_en; $(LATEX) manual_en

texen:
	$(XTRANSFORM) structure_en.xml blender.xsl > manual_en.tex

# Italian
it: texit pdfit

texit:
	$(XTRANSFORM)  structure_it.xml blender.xsl > manual_it.tex

pdfit:
	$(LATEX) manual_it; $(LATEX) manual_it


#ODF

odf:
	$(XTRANSFORM) structure_en.xml blender2odf.xsl > blender_content.xml

blender.xsl

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE xsl:stylesheet [<!ENTITY nbsp "&#160;">]>
<!--
Blender Wiki to LaTeX converter
Copyright (C) 2006 Alexander Macdonald <alex@alexmac.cc>

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.
-->

<xsl:stylesheet version="2.0"
	xmlns:latex="latex"
	xmlns:wiki="wiki" 
	xmlns:html="http://www.w3.org/1999/xhtml"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	exclude-result-prefixes="html">

	<xsl:output method="text" omit-xml-declaration="yes"/>
	<xsl:variable name="parts" as="xs:string*" select="('PartI','PartII','PartIII','PartIV','PartV','PartVI','PartVII','PartVIII','PartIX','PartX','PartXI','PartXII','PartXIII','PartXIV','PartXV')"/>
	<xsl:variable name="base" as="xs:string" select="/wiki:structure/@base"/>
	<xsl:variable name="baseurl" as="xs:string" select="/wiki:structure/@baseurl"/>
	
	<!--=====================================================================-->
	<!--======================== Entry Point ================================-->
	<!--=====================================================================-->

	<xsl:template match="/">\documentclass[a4paper]{book}
\usepackage{amsmath}
\usepackage[pdftex]{graphicx}
\usepackage{wrapfig}
\usepackage[bookmarks=true]{hyperref}
\usepackage[left=1.5in,right=1.5in]{geometry}
\usepackage{eurosym}
\usepackage[utf8x]{inputenc}
\usepackage[<xsl:value-of select="/wiki:structure/wiki:language"/>]{babel}

\title{<xsl:value-of select="/wiki:structure/wiki:title"/>}

\pdfinfo{            
	/Title		(<xsl:value-of select="/wiki:structure/wiki:title"/>)
	/Author		(mediawiki.blender.org)
	/Keywords	(<xsl:value-of select="/wiki:structure/wiki:keywords"/>)
}
 
\begin{document}
\setlength{\parindent}{0cm}
\maketitle
\tableofcontents
		<xsl:for-each select="$parts">
			<xsl:apply-templates select="document(concat($baseurl, ., '.1'))" mode="part"/>
		</xsl:for-each>
\end{document}
	</xsl:template>

	<!--=====================================================================-->
	<!--============================= Part ==================================-->
	<!--=====================================================================-->
	
	<xsl:template match="/" mode="part">
		<xsl:apply-templates select="html:html/html:body" mode="#current"/>
	</xsl:template>

	<xsl:template match="html:body" mode="part">
		<xsl:for-each-group select="//html:div[@id = 'bodyContent']/*" group-starting-with="html:h1 | html:h2">
			<xsl:if test="exists(current-group()[1][self::html:h1])">\part{<xsl:value-of select="latex:sanitize(substring-after(current-group()[1], '-'))"/>}<xsl:apply-templates select="current-group()[position() gt 1]" mode="#current"/></xsl:if>
			<xsl:if test="exists(current-group()[1][self::html:h2])">
				<xsl:for-each select="current-group()[2]/html:li/html:a">
					<xsl:apply-templates select="document(concat($base, @href))" mode="chapter"/>
				</xsl:for-each>
			</xsl:if>
		</xsl:for-each-group>
	</xsl:template>
	
	<!--=====================================================================-->
	<!--============================ Chapter ================================-->
	<!--=====================================================================-->
	
	<xsl:template match="/" mode="chapter">
		<xsl:apply-templates select="html:html/html:body" mode="#current"/>
	</xsl:template>
	
	<xsl:template match="html:body" mode="chapter">
		<xsl:for-each-group select="//html:div[@id = 'bodyContent']/*" group-starting-with="html:h1">
			<xsl:if test="exists(current-group()[1][self::html:h1])">\chapter{<xsl:value-of select="latex:sanitize(current-group()[1])"/>}
				<xsl:for-each-group select="current-group()[position() gt 1]" group-starting-with="html:h2 | html:h3 | html:h4">
					<xsl:choose>
						<xsl:when test="exists(current-group()[1][self::html:h2])">\section{<xsl:value-of select="latex:sanitize(current-group()[1])"/>}<xsl:apply-templates select="current-group()[position() gt 1]" mode="#current"/></xsl:when>
						<xsl:when test="exists(current-group()[1][self::html:h3])">\subsection{<xsl:value-of select="latex:sanitize(current-group()[1])"/>}<xsl:apply-templates select="current-group()[position() gt 1]" mode="#current"/></xsl:when>
						<xsl:when test="exists(current-group()[1][self::html:h4])">\subsubsection{<xsl:value-of select="latex:sanitize(current-group()[1])"/>}<xsl:apply-templates select="current-group()[position() gt 1]" mode="#current"/></xsl:when>
						<xsl:otherwise>
							<xsl:apply-templates select="current-group()" mode="#current"/>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:for-each-group>
			</xsl:if>
		</xsl:for-each-group>
	</xsl:template>


	<!--=====================================================================-->
	<!--============================== Markup ===============================-->
	<!--=====================================================================-->
	
	<xsl:function name="latex:sanitize" as="xs:string">
		<xsl:param name="string" as="xs:string"/>
		<xsl:sequence select="normalize-space(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace($string,'\\', '\\\\'),'\$', '\\\$'), '&gt;', '\$&gt;\$'), '&lt;', '\$&lt;\$'), '&amp;', '\\&amp;'), '\}', '\\}'), '\{', '\\{'), '\^', '\\^'), '#', '\\#'),'%', '\\%'),'_', '\\_'))"/>
	</xsl:function>
	
	<xsl:function name="latex:imagewidth" as="xs:double">
		<xsl:param name="width" as="xs:double"/>
		<xsl:param name="height" as="xs:double"/>
		<xsl:sequence select="$width * min(((if ($width ge 500) then (500 div $width) else 1.0), (if ($height ge 750) then (750 div $height) else 1.0)))"/>
	</xsl:function>

	<!-- ignore junk -->
	<xsl:template match="html:*" mode="part chapter table"></xsl:template>

	<!-- replace some special chars with latex equivalents -->
	<xsl:template match="text()" mode="part chapter table"><xsl:sequence select="latex:sanitize(.)"/></xsl:template>

	<xsl:template match="html:div[@class = 'thumb tright']" mode="part chapter">
\begin{wrapfigure}{R}{0pt}
\includegraphics[width=<xsl:value-of select="latex:imagewidth(((.//html:img)[1]/@width div 2, 100)[1], ((.//html:img)[1]/@height div 2, 100)[1])"/>pt]{mediawiki.blender.org<xsl:value-of select="(.//html:img)[1]/@src"/>}
\caption{<xsl:value-of select="latex:sanitize((.//html:div[@class='thumbcaption'])[1])"/>}
\end{wrapfigure}
	</xsl:template>
	
	<xsl:template match="html:div[@class = 'thumb tnone'] | html:div[@class = 'thumb tleft']" mode="part chapter">
\begin{wrapfigure}{L}{0pt}
\includegraphics[width=<xsl:value-of select="latex:imagewidth(((.//html:img)[1]/@width div 2, 100)[1], ((.//html:img)[1]/@height div 2, 100)[1])"/>pt]{mediawiki.blender.org<xsl:value-of select="(.//html:img)[1]/@src"/>} \\
\caption{<xsl:value-of select="latex:sanitize((.//html:div[@class='thumbcaption'])[1])"/>}
\end{wrapfigure}
	</xsl:template>
	
	<xsl:template match="html:div[@class = 'thumb tnone']" mode="table">\includegraphics[width=<xsl:value-of select="latex:imagewidth((.//html:img)[1]/@width div 2, (.//html:img)[1]/@height div 2)"/>pt]{mediawiki.blender.org<xsl:value-of select="(.//html:img)[1]/@src"/>}</xsl:template>
	
	<xsl:template match="html:div[@class = 'thumb center']" mode="part chapter">
\begin{wrapfigure}L}{0pt}
\includegraphics[width=<xsl:value-of select="latex:imagewidth(((.//html:img)[1]/@width div 2, 100)[1], ((.//html:img)[1]/@height div 2, 100)[1])"/>pt]{mediawiki.blender.org<xsl:value-of select="(.//html:img)[1]/@src"/>} \\
\caption{<xsl:value-of select="latex:sanitize((.//html:div[@class='thumbcaption'])[1])"/>}
\end{wrapfigure}
	</xsl:template>

	<xsl:template match="html:img" mode="part chapter table">\includegraphics[width=<xsl:value-of select="latex:imagewidth((@width div 2, 100)[1], (@height div 2, 100)[1])"/>pt]{mediawiki.blender.org<xsl:value-of select="@src"/>}</xsl:template>

	<xsl:template match="html:p" mode="part chapter">
		<xsl:choose>
			<xsl:when test="starts-with(., '[[math:I')">$<xsl:sequence select="normalize-space(substring-before(substring-after(., '[[math:I'), ']]'))"/>$</xsl:when>
			<xsl:otherwise>
				<xsl:variable name="p"><xsl:apply-templates mode="#current"/></xsl:variable>
<xsl:if test="string-length(normalize-space($p)) gt 0">
<xsl:sequence select="$p"/>
\\

</xsl:if>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

	<xsl:template match="html:ul" mode="chapter">
\begin{itemize}
<xsl:apply-templates mode="#current"/>
\end{itemize}
	</xsl:template>

	<xsl:template match="html:ol" mode="chapter">
\begin{enumerate}
<xsl:apply-templates mode="#current"/>
\end{enumerate}
	</xsl:template>

	<xsl:template match="html:li" mode="part chapter">
		<xsl:variable name="text">
			<xsl:apply-templates mode="#current"/>
		</xsl:variable>
		<xsl:sequence select="concat('\item ', normalize-space($text))"/>
	</xsl:template>
	
	<xsl:template match="html:b" mode="part chapter table">
		<xsl:variable name="text">
			<xsl:apply-templates mode="#current"/>
		</xsl:variable>
		<xsl:sequence select="concat(' \textbf{', normalize-space($text), '}' )"/>
	</xsl:template>
	
	<xsl:template match="html:i" mode="part chapter table">
		<xsl:variable name="text">
			<xsl:apply-templates mode="#current"/>
		</xsl:variable>
		<xsl:sequence select="concat(' \textit{', normalize-space($text), '}' )"/>
	</xsl:template>

	<xsl:template match="html:font[@style='color:#003060; white-space:nowrap; font-family: monospace;'] | html:tt | html:code" mode="part chapter table">
		<xsl:variable name="text">
			<xsl:apply-templates mode="#current"/>
		</xsl:variable>
		<xsl:sequence select="concat(' \texttt{', normalize-space($text), '}' )"/>
	</xsl:template>

	<xsl:template match="html:div[@class='center'] | html:span | html:a | html:font" mode="part chapter"><xsl:apply-templates mode="#current"/></xsl:template>

<!-- not working just yet -->
<!--
	<xsl:template match="html:table" mode="part chapter">\begin{tabular}
<xsl:for-each select="html:tr">
	<xsl:variable name="row">
		<xsl:for-each select="html:td | html:th">
			<xsl:variable name="cell" as="xs:string">
				<xsl:variable name="temp">
					<xsl:apply-templates mode="table"/>
				</xsl:variable>
				<xsl:sequence select="latex:sanitize($temp)"/>
			</xsl:variable>
			<xsl:if test="position() != last() and string-length($cell) gt 0"><xsl:value-of select="$cell"/> &amp; </xsl:if>
		</xsl:for-each>
	</xsl:variable>
	<xsl:sequence select="normalize-space($row)"/>
	<xsl:if test="position() != last() and string-length($row) gt 0"><xsl:value-of select="$row"/> \\
</xsl:if>
</xsl:for-each>
\end{tabular}
	</xsl:template>
-->

	<!-- Framed note -->
	<xsl:template match="html:table[@style = 'width:400px; margin-top:5px; margin-bottom:5px; padding:5px; border:1px solid #AAA; background: #F9F9F9;']" mode="part chapter">
\framebox{<xsl:apply-templates mode="#current" select="html:tr/html:td/node()"/>}
\\

</xsl:template>

	<!-- This is junk -->
	<xsl:template match="html:table[@style = 'margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse;']" mode="part chapter"></xsl:template>

</xsl:stylesheet>

structure_en.xml

<wiki:structure base="mediawiki.blender.org" baseurl="mediawiki.blender.org/index.php/Manual/" xmlns:wiki="wiki">
	<wiki:language>english</wiki:language>
	<wiki:title>Blender User Manual</wiki:title>
	<wiki:keywords>Blender 3D Graphics CAD Lighting Texturing Modeling Rendering</wiki:keywords>
</wiki:structure>

structure_it.xml

<wiki:structure base="mediawiki.blender.org" baseurl="mediawiki.blender.org/index.php/Manual.it/" xmlns:wiki="wiki">
	<wiki:language>italian</wiki:language>
	<wiki:title>Blender Manuale Di Utente</wiki:title>
	<wiki:keywords>Blender 3D CAD Illuminazione Grafici Miscelatore Struttura Modellando Rappresentazione</wiki:keywords>
</wiki:structure>