Drupal: textová část zpráv (text/plain), základní funkční verze (XSLT+Java).
authorFrantišek Kučera <franta-hg@frantovo.cz>
Mon Oct 17 18:14:34 2011 +0200 (2011-10-17)
changeset 89c60625d58158
parent 88 cbf1a1153313
child 90 2ed2497d4559
Drupal: textová část zpráv (text/plain), základní funkční verze (XSLT+Java).
helpers/mimeTextPart.xsl
src/org/sonews/storage/DrupalMessage.java
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/helpers/mimeTextPart.xsl	Mon Oct 17 18:14:34 2011 +0200
     1.3 @@ -0,0 +1,199 @@
     1.4 +<?xml version="1.0" encoding="UTF-8"?>
     1.5 +<xsl:stylesheet version="2.0"
     1.6 +	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     1.7 +	xmlns:fn="http://www.w3.org/2005/xpath-functions"
     1.8 +	xmlns:h="http://www.w3.org/1999/xhtml">
     1.9 +	<xsl:output method="text" encoding="UTF-8"/>
    1.10 +	<xsl:strip-space elements="*"/>
    1.11 +	
    1.12 +	<xsl:output method="text" encoding="UTF-8"/>
    1.13 +	<xsl:strip-space elements="*"/>
    1.14 +	
    1.15 +	<xsl:variable name="urlBase" select="/h:html/h:head/h:base/@href"/>
    1.16 +	
    1.17 +	<!-- Celý dokument -->
    1.18 +	<xsl:template match="/">
    1.19 +		<xsl:apply-templates select="h:html/h:body"/>
    1.20 +	</xsl:template>
    1.21 +
    1.22 +	<xsl:template match="h:h1">
    1.23 +		<xsl:value-of select="text()"/>
    1.24 +		<xsl:text>&#10;</xsl:text>
    1.25 +		<xsl:for-each select="1 to string-length(.)">#</xsl:for-each>		
    1.26 +		<xsl:text>&#10;</xsl:text>
    1.27 +		<xsl:text>&#10;</xsl:text>
    1.28 +	</xsl:template>
    1.29 +	
    1.30 +	<xsl:template match="h:h2">
    1.31 +		<xsl:value-of select="text()"/>
    1.32 +		<xsl:text>&#10;</xsl:text>
    1.33 +		<xsl:for-each select="1 to string-length(.)">-</xsl:for-each>		
    1.34 +		<xsl:text>&#10;</xsl:text>
    1.35 +		<xsl:text>&#10;</xsl:text>
    1.36 +	</xsl:template>
    1.37 +	
    1.38 +	<xsl:template match="h:h3">
    1.39 +		<xsl:for-each select="1 to 3">#</xsl:for-each>
    1.40 +		<xsl:text> </xsl:text>
    1.41 +		<xsl:value-of select="text()"/>
    1.42 +		<xsl:text>&#10;</xsl:text>
    1.43 +		<xsl:text>&#10;</xsl:text>
    1.44 +	</xsl:template>
    1.45 +
    1.46 +	
    1.47 +	<xsl:template match="h:h4">
    1.48 +		<xsl:for-each select="1 to 4">#</xsl:for-each>
    1.49 +		<xsl:text> </xsl:text>
    1.50 +		<xsl:value-of select="text()"/>
    1.51 +		<xsl:text>&#10;</xsl:text>
    1.52 +		<xsl:text>&#10;</xsl:text>
    1.53 +	</xsl:template>
    1.54 +
    1.55 +	
    1.56 +	<xsl:template match="h:h5">
    1.57 +		<xsl:for-each select="1 to 5">#</xsl:for-each>
    1.58 +		<xsl:text> </xsl:text>
    1.59 +		<xsl:value-of select="text()"/>
    1.60 +		<xsl:text>&#10;</xsl:text>
    1.61 +		<xsl:text>&#10;</xsl:text>
    1.62 +	</xsl:template>
    1.63 +	
    1.64 +	<xsl:template match="h:h6">
    1.65 +		<xsl:for-each select="1 to 6">#</xsl:for-each>
    1.66 +		<xsl:text> </xsl:text>
    1.67 +		<xsl:value-of select="text()"/>
    1.68 +		<xsl:text>&#10;</xsl:text>
    1.69 +		<xsl:text>&#10;</xsl:text>
    1.70 +	</xsl:template>
    1.71 +
    1.72 +
    1.73 +	<xsl:template match="h:p">
    1.74 +		<xsl:apply-templates/>
    1.75 +		<xsl:text>&#10;</xsl:text>
    1.76 +		<xsl:text>&#10;</xsl:text>
    1.77 +	</xsl:template>
    1.78 +	
    1.79 +	<xsl:template match="h:a">
    1.80 +		<xsl:text>"</xsl:text>
    1.81 +		<xsl:value-of select="text()"/>
    1.82 +		<xsl:text>" &lt;</xsl:text>
    1.83 +		<xsl:choose>
    1.84 +			<xsl:when test="matches(@href, '^(http:|https:|ftp:)')">
    1.85 +				<xsl:value-of select="@href"/>
    1.86 +			</xsl:when>
    1.87 +			<xsl:when test="matches(@href, '^mailto:')">
    1.88 +				<xsl:value-of select="substring-after(@href, 'mailto:')"/>
    1.89 +			</xsl:when>
    1.90 +			<xsl:otherwise>
    1.91 +				<xsl:choose>
    1.92 +					<xsl:when test="ends-with($urlBase, '/') or starts-with(@href, '/')">
    1.93 +						<xsl:value-of select="concat($urlBase, @href)"/>
    1.94 +					</xsl:when>
    1.95 +					<xsl:otherwise>
    1.96 +						<xsl:value-of select="concat($urlBase, '/', @href)"/>
    1.97 +					</xsl:otherwise>
    1.98 +				</xsl:choose>
    1.99 +			</xsl:otherwise>
   1.100 +		</xsl:choose>	
   1.101 +		<xsl:text>&gt;</xsl:text>
   1.102 +		<xsl:if test="@title and not(matches(@title, '^\s*$'))">
   1.103 +			<xsl:text> (</xsl:text>
   1.104 +			<xsl:value-of select="@title"/>
   1.105 +			<xsl:text>)</xsl:text>
   1.106 +		</xsl:if>
   1.107 +	</xsl:template>
   1.108 +	
   1.109 +	<xsl:template match="h:img">
   1.110 +		<xsl:variable name="obrázek">
   1.111 +			<h:a href="{@src}" title="{@title}">Obrázek: <xsl:value-of select="@alt"/></h:a>
   1.112 +		</xsl:variable>
   1.113 +		<xsl:apply-templates select="$obrázek/node()"/>
   1.114 +	</xsl:template>
   1.115 +	
   1.116 +	<xsl:template match="h:strong|h:b">
   1.117 +		<xsl:text>**</xsl:text>
   1.118 +		<xsl:apply-templates/>
   1.119 +		<xsl:text>**</xsl:text>
   1.120 +	</xsl:template>
   1.121 +	
   1.122 +	<xsl:template match="h:em|h:i">
   1.123 +		<xsl:text>*</xsl:text>
   1.124 +		<xsl:apply-templates/>
   1.125 +		<xsl:text>*</xsl:text>
   1.126 +	</xsl:template>
   1.127 +	
   1.128 +	<xsl:template match="h:abbr[@title]">
   1.129 +		<xsl:apply-templates/>
   1.130 +		<xsl:text> (</xsl:text>
   1.131 +		<xsl:value-of select="@title"/>
   1.132 +		<xsl:text>)</xsl:text>
   1.133 +	</xsl:template>
   1.134 +	
   1.135 +	<xsl:template match="h:pre">
   1.136 +		<xsl:text>--------------------------------</xsl:text>
   1.137 +		<xsl:text>&#10;</xsl:text>
   1.138 +		<xsl:apply-templates/>
   1.139 +		<xsl:text>&#10;</xsl:text>
   1.140 +		<xsl:text>--------------------------------</xsl:text>
   1.141 +		<xsl:text>&#10;</xsl:text>
   1.142 +		<xsl:text>&#10;</xsl:text>
   1.143 +	</xsl:template>
   1.144 +	
   1.145 +	<xsl:template match="h:code">
   1.146 +		<xsl:text>`</xsl:text>
   1.147 +		<xsl:apply-templates/>
   1.148 +		<xsl:text>`</xsl:text>
   1.149 +	</xsl:template>
   1.150 +	
   1.151 +	<xsl:template match="h:hr">
   1.152 +		<xsl:text>----------------------------------------------------------------</xsl:text>
   1.153 +		<xsl:text>&#10;</xsl:text>
   1.154 +		<xsl:text>&#10;</xsl:text>
   1.155 +	</xsl:template>
   1.156 +	
   1.157 +	<xsl:template match="h:ul">
   1.158 +		<xsl:apply-templates/>
   1.159 +		<xsl:text>&#10;</xsl:text>
   1.160 +	</xsl:template>
   1.161 +	
   1.162 +	<xsl:template match="h:ul/h:li">
   1.163 +		<xsl:text> - </xsl:text>
   1.164 +		<xsl:apply-templates/>
   1.165 +		<xsl:text>&#10;</xsl:text>
   1.166 +	</xsl:template>
   1.167 +	
   1.168 +	<xsl:template match="h:ol">
   1.169 +		<xsl:for-each select="h:li">
   1.170 +			<xsl:value-of select="concat(' ', position(), ') ')"/>
   1.171 +			<xsl:apply-templates/>
   1.172 +			<xsl:text>&#10;</xsl:text>
   1.173 +		</xsl:for-each>		
   1.174 +		<xsl:text>&#10;</xsl:text>
   1.175 +	</xsl:template>
   1.176 +	
   1.177 +	
   1.178 +	<!--
   1.179 +	<xsl:template match="h:blockquote[matches(p/text(), '^(\"|„)')]">
   1.180 +		
   1.181 +	</xsl:template>
   1.182 +	-->
   1.183 +	
   1.184 +	<xsl:template match="text()[not(parent::h:pre)]">
   1.185 +		<xsl:if test="matches(., '^\s')">
   1.186 +			<xsl:text> </xsl:text>
   1.187 +		</xsl:if>
   1.188 +		<xsl:value-of select="normalize-space(.)"/>
   1.189 +		<xsl:if test="matches(., '\s$')">
   1.190 +			<xsl:text> </xsl:text>
   1.191 +		</xsl:if>
   1.192 +	</xsl:template>
   1.193 +
   1.194 +	
   1.195 +	<xsl:template match="h:div[@class='wwwLinks']">
   1.196 +		<xsl:text>-- </xsl:text>
   1.197 +		<xsl:text>&#10;</xsl:text>
   1.198 +		<xsl:apply-templates/>	
   1.199 +	</xsl:template>	
   1.200 +
   1.201 +
   1.202 +</xsl:stylesheet>
     2.1 --- a/src/org/sonews/storage/DrupalMessage.java	Mon Oct 17 13:55:28 2011 +0200
     2.2 +++ b/src/org/sonews/storage/DrupalMessage.java	Mon Oct 17 18:14:34 2011 +0200
     2.3 @@ -98,7 +98,9 @@
     2.4  
     2.5  			/** Plain text part */
     2.6  			MimeBodyPart textPart = new MimeBodyPart();
     2.7 -			textPart.setText(readPlainText(rs, xhtmlText));
     2.8 +			String plainText = readPlainText(rs, xhtmlText);
     2.9 +			textPart.setText(plainText);
    2.10 +			//addHeader("Lines", String.valueOf(plainText.split("\n").length));
    2.11  
    2.12  			/**
    2.13  			 * Thunderbirdu záleží, v jakém pořadí části jsou 
    2.14 @@ -114,10 +116,22 @@
    2.15  	}
    2.16  
    2.17  	private String readPlainText(ResultSet rs, String xhtmlText) {
    2.18 -		/**
    2.19 -		 * TODO: převést na prostý text
    2.20 -		 */
    2.21 -		return "TODO: obyčejný text\n(zatím čtěte XHTML verzi)";
    2.22 +		try {
    2.23 +			TransformerFactory tf = TransformerFactory.newInstance();
    2.24 +			Transformer textTransformer = tf.newTransformer(new StreamSource(Resource.getAsStream("helpers/mimeTextPart.xsl")));
    2.25 +
    2.26 +			StringReader input = new StringReader(xhtmlText);
    2.27 +			StringWriter output = new StringWriter(xhtmlText.length());
    2.28 +			textTransformer.transform(new StreamSource(input), new StreamResult(output));
    2.29 +
    2.30 +			return output.toString();
    2.31 +		} catch (Exception e) {
    2.32 +			/**
    2.33 +			 * TODO: lepší ošetření chyby
    2.34 +			 */
    2.35 +			log.log(Level.WARNING, "Error while transforming article to plain text", e);
    2.36 +			return makeSimpleXHTML("Při transformaci příspěvku bohužel došlo k chybě.");
    2.37 +		}
    2.38  	}
    2.39  
    2.40  	private String readXhtmlText(ResultSet rs) {
    2.41 @@ -177,7 +191,13 @@
    2.42  	 * TODO: refaktorovat, přesunout
    2.43  	 */
    2.44  	private static String tidyXhtml(String inputText) throws IOException {
    2.45 -		// https://sourceforge.net/tracker/index.php?func=detail&aid=3424437&group_id=27659&atid=390966
    2.46 +		/*
    2.47 +		 * Viz https://sourceforge.net/tracker/index.php?func=detail&aid=3424437&group_id=27659&atid=390966
    2.48 +		 *
    2.49 +		 * TODO:
    2.50 +		 *		- použít delší zástupný řetězec, ne jen jeden znak
    2.51 +		 *		- umísťovat ho jen tam, kde už nějaký text je (ne mezi >\s*<)
    2.52 +		 */
    2.53  		inputText = inputText.replaceAll("\\n", "◆\n");
    2.54  
    2.55  		Runtime r = Runtime.getRuntime();