mirror of
https://github.com/moparisthebest/k-9
synced 2025-02-25 15:11:52 -05:00
Merge pull request #309 from jca02266/preserve-spaces
Fixed issue 5630: Quotes are missing a space between > and the quoted text
This commit is contained in:
commit
f87ff20556
@ -211,63 +211,54 @@ public class HtmlConverter {
|
|||||||
}
|
}
|
||||||
StringReader reader = new StringReader(text);
|
StringReader reader = new StringReader(text);
|
||||||
StringBuilder buff = new StringBuilder(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH);
|
StringBuilder buff = new StringBuilder(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH);
|
||||||
boolean isStartOfLine = false; // Are we currently at the start of a line?
|
boolean isStartOfLine = true; // Are we currently at the start of a line?
|
||||||
|
int spaces = 0;
|
||||||
int quoteDepth = 0; // Number of DIVs deep we are.
|
int quoteDepth = 0; // Number of DIVs deep we are.
|
||||||
int quotesThisLine = 0; // How deep we should be quoting for this line.
|
int quotesThisLine = 0; // How deep we should be quoting for this line.
|
||||||
try {
|
try {
|
||||||
int c;
|
int c;
|
||||||
while ((c = reader.read()) != -1) {
|
while ((c = reader.read()) != -1) {
|
||||||
switch (c) {
|
if (isStartOfLine) {
|
||||||
case '\n':
|
switch (c) {
|
||||||
// pine treats <br> as two newlines, but <br/> as one newline. Use <br/> so our messages aren't
|
case ' ':
|
||||||
// doublespaced.
|
spaces++;
|
||||||
buff.append(HTML_NEWLINE);
|
break;
|
||||||
isStartOfLine = true;
|
case '>':
|
||||||
quotesThisLine = 0;
|
|
||||||
break;
|
|
||||||
case '&':
|
|
||||||
buff.append("&");
|
|
||||||
break;
|
|
||||||
case '<':
|
|
||||||
buff.append("<");
|
|
||||||
break;
|
|
||||||
case '>':
|
|
||||||
if (isStartOfLine) {
|
|
||||||
quotesThisLine++;
|
quotesThisLine++;
|
||||||
} else {
|
spaces = 0;
|
||||||
// We use a token here which can't occur in htmlified text because > is valid
|
break;
|
||||||
// within links (where > is not), and linkifying links will include it if we
|
case '\n':
|
||||||
// do it here. We'll make another pass and change this back to > after
|
appendbq(buff, quotesThisLine, quoteDepth);
|
||||||
// the linkification is done.
|
quoteDepth = quotesThisLine;
|
||||||
buff.append("<gt>");
|
|
||||||
}
|
appendsp(buff, spaces);
|
||||||
break;
|
spaces = 0;
|
||||||
case '\r':
|
|
||||||
break;
|
appendchar(buff, c);
|
||||||
case ' ':
|
isStartOfLine = true;
|
||||||
if (isStartOfLine) {
|
quotesThisLine = 0;
|
||||||
// If we're still in the start of the line and we have spaces, don't output them, since they
|
break;
|
||||||
// may be collapsed by our div-converting magic.
|
default:
|
||||||
|
isStartOfLine = false;
|
||||||
|
|
||||||
|
appendbq(buff, quotesThisLine, quoteDepth);
|
||||||
|
quoteDepth = quotesThisLine;
|
||||||
|
|
||||||
|
appendsp(buff, spaces);
|
||||||
|
spaces = 0;
|
||||||
|
|
||||||
|
appendchar(buff, c);
|
||||||
|
isStartOfLine = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
}
|
||||||
if (isStartOfLine) {
|
else {
|
||||||
// Not a quote character and not a space. Content is starting now.
|
appendchar(buff, c);
|
||||||
isStartOfLine = false;
|
if (c == '\n') {
|
||||||
// Add/remove blockquotes by comparing this line's quotes to the previous line's quotes.
|
isStartOfLine = true;
|
||||||
if (quotesThisLine > quoteDepth) {
|
quotesThisLine = 0;
|
||||||
for (int i = quoteDepth; i < quotesThisLine; i++) {
|
|
||||||
buff.append(HTML_BLOCKQUOTE_START.replace(HTML_BLOCKQUOTE_COLOR_TOKEN, getQuoteColor(i + 1)));
|
|
||||||
}
|
|
||||||
} else if (quotesThisLine < quoteDepth) {
|
|
||||||
for (int i = quoteDepth; i > quotesThisLine; i--) {
|
|
||||||
buff.append(HTML_BLOCKQUOTE_END);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
quoteDepth = quotesThisLine;
|
|
||||||
}
|
}
|
||||||
buff.append((char)c);
|
}
|
||||||
}//switch
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
//Should never happen
|
//Should never happen
|
||||||
@ -311,6 +302,54 @@ public class HtmlConverter {
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void appendchar(StringBuilder buff, int c) {
|
||||||
|
switch (c) {
|
||||||
|
case '&':
|
||||||
|
buff.append("&");
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
buff.append("<");
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
// We use a token here which can't occur in htmlified text because > is valid
|
||||||
|
// within links (where > is not), and linkifying links will include it if we
|
||||||
|
// do it here. We'll make another pass and change this back to > after
|
||||||
|
// the linkification is done.
|
||||||
|
buff.append("<gt>");
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
// pine treats <br> as two newlines, but <br/> as one newline. Use <br/> so our messages aren't
|
||||||
|
// doublespaced.
|
||||||
|
buff.append(HTML_NEWLINE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buff.append((char)c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void appendsp(StringBuilder buff, int spaces) {
|
||||||
|
while (spaces > 0) {
|
||||||
|
buff.append(' ');
|
||||||
|
spaces--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void appendbq(StringBuilder buff, int quotesThisLine, int quoteDepth) {
|
||||||
|
// Add/remove blockquotes by comparing this line's quotes to the previous line's quotes.
|
||||||
|
if (quotesThisLine > quoteDepth) {
|
||||||
|
for (int i = quoteDepth; i < quotesThisLine; i++) {
|
||||||
|
buff.append(HTML_BLOCKQUOTE_START.replace(HTML_BLOCKQUOTE_COLOR_TOKEN, getQuoteColor(i + 1)));
|
||||||
|
}
|
||||||
|
} else if (quotesThisLine < quoteDepth) {
|
||||||
|
for (int i = quoteDepth; i > quotesThisLine; i--) {
|
||||||
|
buff.append(HTML_BLOCKQUOTE_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected static final String QUOTE_COLOR_DEFAULT = "#ccc";
|
protected static final String QUOTE_COLOR_DEFAULT = "#ccc";
|
||||||
protected static final String QUOTE_COLOR_LEVEL_1 = "#729fcf";
|
protected static final String QUOTE_COLOR_LEVEL_1 = "#729fcf";
|
||||||
protected static final String QUOTE_COLOR_LEVEL_2 = "#ad7fa8";
|
protected static final String QUOTE_COLOR_LEVEL_2 = "#ad7fa8";
|
||||||
|
@ -25,7 +25,27 @@ public class HtmlConverterTest extends TestCase {
|
|||||||
">> Guess!";
|
">> Guess!";
|
||||||
String result = HtmlConverter.textToHtml(message);
|
String result = HtmlConverter.textToHtml(message);
|
||||||
writeToFile(result);
|
writeToFile(result);
|
||||||
assertEquals("<pre class=\"k9mail\">Panama!<br /><br />Bob Barker <bob@aol.com> wrote:<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">a canal<br /><br />Dorothy Jo Gideon <dorothy@aol.com> espoused:<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">A man, a plan...<br /></blockquote>Too easy!</blockquote><br />Nice job :)<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\"><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">Guess!</blockquote></blockquote></pre>", result);
|
assertEquals("<pre class=\"k9mail\">"
|
||||||
|
+ "Panama!<br />"
|
||||||
|
+ "<br />"
|
||||||
|
+ "Bob Barker <bob@aol.com> wrote:<br />"
|
||||||
|
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">"
|
||||||
|
+ " a canal<br />"
|
||||||
|
+ "<br />"
|
||||||
|
+ " Dorothy Jo Gideon <dorothy@aol.com> espoused:<br />"
|
||||||
|
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">"
|
||||||
|
+ "A man, a plan...<br />"
|
||||||
|
+ "</blockquote>"
|
||||||
|
+ " Too easy!<br />"
|
||||||
|
+ "</blockquote>"
|
||||||
|
+ "<br />"
|
||||||
|
+ "Nice job :)<br />"
|
||||||
|
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">"
|
||||||
|
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">"
|
||||||
|
+ " Guess!"
|
||||||
|
+ "</blockquote>"
|
||||||
|
+ "</blockquote>"
|
||||||
|
+ "</pre>", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testTextQuoteToHtmlBlockquoteIndented() {
|
public void testTextQuoteToHtmlBlockquoteIndented() {
|
||||||
@ -39,7 +59,18 @@ public class HtmlConverterTest extends TestCase {
|
|||||||
"> :)";
|
"> :)";
|
||||||
String result = HtmlConverter.textToHtml(message);
|
String result = HtmlConverter.textToHtml(message);
|
||||||
writeToFile(result);
|
writeToFile(result);
|
||||||
assertEquals("<pre class=\"k9mail\">*facepalm*<br /><br />Bob Barker <bob@aol.com> wrote:<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">A wise man once said...<br /><br />LOL F1RST!!!!!<br /><br />:)</blockquote></pre>", result);
|
assertEquals("<pre class=\"k9mail\">"
|
||||||
|
+ "*facepalm*<br />"
|
||||||
|
+ "<br />"
|
||||||
|
+ "Bob Barker <bob@aol.com> wrote:<br />"
|
||||||
|
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">"
|
||||||
|
+ " A wise man once said...<br />"
|
||||||
|
+ "<br />"
|
||||||
|
+ " LOL F1RST!!!!!<br />"
|
||||||
|
+ "<br />"
|
||||||
|
+ " :)"
|
||||||
|
+ "</blockquote></pre>", result);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testQuoteDepthColor() {
|
public void testQuoteDepthColor() {
|
||||||
@ -62,7 +93,27 @@ public class HtmlConverterTest extends TestCase {
|
|||||||
">>>>>> six";
|
">>>>>> six";
|
||||||
String result = HtmlConverter.textToHtml(message);
|
String result = HtmlConverter.textToHtml(message);
|
||||||
writeToFile(result);
|
writeToFile(result);
|
||||||
assertEquals("<pre class=\"k9mail\">zero<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">one<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">two<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #8ae234; padding-left: 1ex;\">three<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #fcaf3e; padding-left: 1ex;\">four<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #e9b96e; padding-left: 1ex;\">five<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ccc; padding-left: 1ex;\">six</blockquote></blockquote></blockquote></blockquote></blockquote></blockquote></pre>", result);
|
assertEquals("<pre class=\"k9mail\">"
|
||||||
|
+ "zero<br />"
|
||||||
|
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">"
|
||||||
|
+ " one<br />"
|
||||||
|
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">"
|
||||||
|
+ " two<br />"
|
||||||
|
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #8ae234; padding-left: 1ex;\">"
|
||||||
|
+ " three<br />"
|
||||||
|
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #fcaf3e; padding-left: 1ex;\">"
|
||||||
|
+ " four<br />"
|
||||||
|
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #e9b96e; padding-left: 1ex;\">"
|
||||||
|
+ " five<br />"
|
||||||
|
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ccc; padding-left: 1ex;\">"
|
||||||
|
+ " six"
|
||||||
|
+ "</blockquote>"
|
||||||
|
+ "</blockquote>"
|
||||||
|
+ "</blockquote>"
|
||||||
|
+ "</blockquote>"
|
||||||
|
+ "</blockquote>"
|
||||||
|
+ "</blockquote>"
|
||||||
|
+ "</pre>", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeToFile(final String content) {
|
private void writeToFile(final String content) {
|
||||||
@ -83,4 +134,37 @@ public class HtmlConverterTest extends TestCase {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPreserveSpacesAtFirst() {
|
||||||
|
String message = "foo\n"
|
||||||
|
+ " bar\n"
|
||||||
|
+ " baz\n";
|
||||||
|
String result = HtmlConverter.textToHtml(message);
|
||||||
|
writeToFile(result);
|
||||||
|
assertEquals("<pre class=\"k9mail\">"
|
||||||
|
+ "foo<br />"
|
||||||
|
+ " bar<br />"
|
||||||
|
+ " baz<br />"
|
||||||
|
+ "</pre>", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPreserveSpacesAtFirstForSpecialCharacters() {
|
||||||
|
String message =
|
||||||
|
" \n"
|
||||||
|
+ " &\n"
|
||||||
|
+ " \r\n"
|
||||||
|
+ " <\n"
|
||||||
|
+ " > \n";
|
||||||
|
String result = HtmlConverter.textToHtml(message);
|
||||||
|
writeToFile(result);
|
||||||
|
assertEquals("<pre class=\"k9mail\">"
|
||||||
|
+ " <br />"
|
||||||
|
+ " &<br />"
|
||||||
|
+ " <br />"
|
||||||
|
+ " <<br />"
|
||||||
|
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">"
|
||||||
|
+ " <br />"
|
||||||
|
+ "</blockquote>"
|
||||||
|
+ "</pre>", result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user