Drupal: textová část zpráv (text/plain), základní funkční verze (XSLT+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> </xsl:text>
1.25 + <xsl:for-each select="1 to string-length(.)">#</xsl:for-each>
1.26 + <xsl:text> </xsl:text>
1.27 + <xsl:text> </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> </xsl:text>
1.33 + <xsl:for-each select="1 to string-length(.)">-</xsl:for-each>
1.34 + <xsl:text> </xsl:text>
1.35 + <xsl:text> </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> </xsl:text>
1.43 + <xsl:text> </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> </xsl:text>
1.52 + <xsl:text> </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> </xsl:text>
1.61 + <xsl:text> </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> </xsl:text>
1.69 + <xsl:text> </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> </xsl:text>
1.76 + <xsl:text> </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>" <</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>></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> </xsl:text>
1.138 + <xsl:apply-templates/>
1.139 + <xsl:text> </xsl:text>
1.140 + <xsl:text>--------------------------------</xsl:text>
1.141 + <xsl:text> </xsl:text>
1.142 + <xsl:text> </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> </xsl:text>
1.154 + <xsl:text> </xsl:text>
1.155 + </xsl:template>
1.156 +
1.157 + <xsl:template match="h:ul">
1.158 + <xsl:apply-templates/>
1.159 + <xsl:text> </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> </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> </xsl:text>
1.173 + </xsl:for-each>
1.174 + <xsl:text> </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> </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();