Skip to content

Commit

Permalink
Improve full support for max line width
Browse files Browse the repository at this point in the history
Signed-off-by: Jessica He <jhe@redhat.com>
  • Loading branch information
JessicaJHee authored and datho7561 committed Nov 16, 2022
1 parent d505e7e commit f6c8d9a
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ private int formatStartTagElement(DOMElement element, XMLFormattingConstraints p
int parentStartCloseOffset = element.getParentElement().getStartTagCloseOffset() + 1;
if ((parentStartCloseOffset != startTagOpenOffset
&& StringUtils.isWhitespace(formatterDocument.getText(), parentStartCloseOffset,
startTagOpenOffset))
|| ((parentConstraints.getAvailableLineWidth() - width) < 0 && isMaxLineWidthSupported())) {
startTagOpenOffset))) {
replaceLeftSpacesWithIndentationPreservedNewLines(parentStartCloseOffset, startTagOpenOffset,
indentLevel, edits);
parentConstraints.setAvailableLineWidth(getMaxLineWidth());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ public void formatText(DOMText textNode, XMLFormattingConstraints parentConstrai
int lineSeparatorOffset = -1;
boolean containsNewLine = false;

for (int i = textNode.getStart(); i < textNode.getEnd(); i++) {
int textStart = textNode.getStart();
int textEnd = textNode.getEnd();

for (int i = textStart; i < textEnd; i++) {
char c = text.charAt(i);
if (Character.isWhitespace(c)) {
// Whitespaces...
Expand All @@ -66,14 +69,14 @@ public void formatText(DOMText textNode, XMLFormattingConstraints parentConstrai
// Text content...
spaceEnd = i;
int contentStart = i;
while (i + 1 < textNode.getEnd() && !Character.isWhitespace(text.charAt(i + 1))) {
while (i + 1 < textEnd && !Character.isWhitespace(text.charAt(i + 1))) {
i++;
}
int contentEnd = i + 1;
if (isMaxLineWidthSupported()) {
int maxLineWidth = getMaxLineWidth();
availableLineWidth -= contentEnd - contentStart;
if (textNode.getStart() != contentStart && availableLineWidth >= 0
if (textStart != contentStart && availableLineWidth >= 0
&& (isJoinContentLines() || !containsNewLine || isMixedContent)) {
// Decrement width for normalized space between text content (not done at
// beginning)
Expand Down Expand Up @@ -110,14 +113,25 @@ public void formatText(DOMText textNode, XMLFormattingConstraints parentConstrai
if (formatElementCategory != FormatElementCategory.IgnoreSpace && spaceEnd + 1 != text.length()) {
DOMElement parentElement = textNode.getParentElement();
// Don't format final spaces if text is at the end of the file
if ((!containsNewLine || isJoinContentLines() || isMixedContent) && (!isMaxLineWidthSupported() || availableLineWidth >= 0)) {
if ((!containsNewLine || isJoinContentLines() || isMixedContent)
&& (!isMaxLineWidthSupported() || availableLineWidth >= 0)) {
// Replace spaces with single space in the case of:
// 1. there is no new line
// 2. isJoinContentLines
replaceSpacesWithOneSpace(spaceStart, spaceEnd, edits);
if (isMaxLineWidthSupported() && spaceStart != -1) {
availableLineWidth--;
}
} else if (isMaxLineWidthSupported() && availableLineWidth < 0
&& !Character.isWhitespace(text.charAt(textStart))) {
// if there is no space between element tag and text but text exceeds max line
// width, move text to new line. (when text is only one term)
// ex: ...<example>|text </example>
int mixedContentIndentLevel = parentConstraints.getMixedContentIndentLevel() == 0 ? indentLevel
: parentConstraints.getMixedContentIndentLevel();
replaceLeftSpacesWithIndentationPreservedNewLines(textStart, textStart, mixedContentIndentLevel,
edits);
availableLineWidth = getMaxLineWidth() - (textEnd - textStart) - mixedContentIndentLevel * getTabSize();
} else {
if (formatElementCategory == FormatElementCategory.NormalizeSpace
|| parentElement.getLastChild() == textNode) {
Expand All @@ -126,6 +140,9 @@ public void formatText(DOMText textNode, XMLFormattingConstraints parentConstrai
}
replaceLeftSpacesWithIndentationPreservedNewLines(spaceStart, spaceEnd + 1, indentLevel,
edits);
if (isMaxLineWidthSupported()) {
availableLineWidth = getMaxLineWidth() - (textEnd - textStart) - indentLevel * getTabSize();
}
}
} else if (isTrimTrailingWhitespace()) {
removeLeftSpaces(spaceStart, lineSeparatorOffset, edits);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ public void closeTagMissing() throws BadLocationException {
String content = "<a>";
String expected = content;
assertFormat(content, expected);
assertFormat(expected, expected);
}

@Test
Expand All @@ -76,15 +75,13 @@ public void selfClosingTag() throws BadLocationException {
String content = "<a></a>";
String expected = content;
assertFormat(content, expected);
assertFormat(expected, expected);
}

@Test
public void singleEndTag() throws BadLocationException {
String content = "</a>";
String expected = content;
assertFormat(content, expected);
assertFormat(expected, expected);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -425,28 +425,29 @@ public void mixedTextDefaultLineWidth() throws BadLocationException {
"\r\n" + //
" Using\r\n" + //
" namespaces in your documents is very easy. Consider this simple article marked up in DocBook V4.5:</para>";
String expected = "<para>All DocBook V5.0 elements are in the namespace <uri>http://docbook.org/ns/docbook</uri>.\r\n"
+ //
" <acronym>XML <alt>Extensible Markup Language</alt></acronym> namespaces are\r\n" + //
" used to distinguish between different element sets. In the last few years,\r\n" + //
" almost all new XML grammars have used their own namespace. It is easy to\r\n" + //
" create compound documents that contain elements from different XML\r\n" + //
" vocabularies. DocBook V5.0 is <emphasis>following</emphasis> this <emphasis>design</emphasis>/\r\n" + //
" <emphasis>rule</emphasis>. Using namespaces in your documents is very easy.\r\n" + //
" Consider this simple article marked up in DocBook V4.5:</para>";
String expected = "<para>All DocBook V5.0 elements are in the namespace <uri>\r\n" + //
" http://docbook.org/ns/docbook</uri>. <acronym>XML <alt>Extensible Markup\r\n" + //
" Language</alt></acronym> namespaces are used to distinguish between different\r\n" + //
" element sets. In the last few years, almost all new XML grammars have used\r\n" + //
" their own namespace. It is easy to create compound documents that contain\r\n" + //
" elements from different XML vocabularies. DocBook V5.0 is <emphasis>following</emphasis>\r\n" + //
" this <emphasis>design</emphasis>/<emphasis>rule</emphasis>. Using namespaces\r\n" + //
" in your documents is very easy. Consider this simple article marked up in\r\n" + //
" DocBook V4.5:</para>";
assertFormat(content, expected, settings, //
te(0, 94, 0, 95, "\r\n "), //
te(0, 130, 1, 2, " "), //
te(1, 41, 1, 42, "\r\n "), //
te(1, 116, 1, 117, "\r\n "), //
te(0, 58, 0, 58, "\r\n "), //
te(1, 79, 1, 80, "\r\n "), //
te(1, 131, 2, 2, " "),
te(2, 59, 2, 60, "\r\n "), //
te(2, 24, 2, 25, "\r\n "), //
te(2, 98, 2, 99, "\r\n "), //
te(2, 126, 3, 2, " "), //
te(3, 31, 6, 2, " "), //
te(6, 32, 6, 33, "\r\n "), //
te(6, 37, 7, 2, " "),
te(7, 30, 7, 30, "\r\n "), //
te(7, 56, 9, 2, " "), //
te(9, 7, 10, 2, " "), //
te(10, 44, 10, 45, "\r\n "));
te(10, 12, 10, 13, "\r\n "), //
te(10, 86, 10, 87, "\r\n "));
assertFormat(expected, expected, settings);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@ public class XMLFormatterMixedContentWithTest extends AbstractCacheBasedTest {

@Test
public void mixedContent() throws BadLocationException {
SharedSettings settings = new SharedSettings();
settings.getFormattingSettings().setMaxLineWidth(20);
settings.getFormattingSettings().setJoinContentLines(true);
String content = "<a>abcd \r\n efgh</a>";
String expected = "<a>abcd efgh</a>";
assertFormat(content, expected, 20);
assertFormat(content, expected, settings, //
te(0, 7, 1, 3, " "));
assertFormat(expected, expected, settings);
}

@Test
Expand All @@ -41,7 +46,12 @@ public void ignoreSpace() throws BadLocationException {
" <c></c>" + System.lineSeparator() + //
" </b>" + System.lineSeparator() + //
"</a>";
assertFormat(content, expected, null);
assertFormat(content, expected, //
te(0, 3, 0, 3, System.lineSeparator() + " "), //
te(0, 6, 0, 6, System.lineSeparator() + " "), //
te(0, 13, 0, 13, System.lineSeparator() + " "), //
te(0, 17, 0, 17, System.lineSeparator()));
assertFormat(expected, expected);
}

@Test
Expand All @@ -50,7 +60,10 @@ public void withMixedContent() throws BadLocationException {
String expected = "<a>" + System.lineSeparator() + //
" <b>A<c></c></b>" + System.lineSeparator() + //
"</a>";
assertFormat(content, expected, null);
assertFormat(content, expected, //
te(0, 3, 0, 3, System.lineSeparator() + " "), //
te(0, 18, 0, 18, System.lineSeparator()));
assertFormat(expected, expected);
}

@Test
Expand All @@ -69,7 +82,7 @@ public void withMixedContentWhiteSpaceLeft() throws BadLocationException {
public void withMixedContentNoWhiteSpaceLeft() throws BadLocationException {
SharedSettings settings = new SharedSettings();
String content = "<a><b> content </b> test </a>";
String expected = "<a><b> content </b> test </a>";
String expected = content;
assertFormat(content, expected, settings);
}

Expand All @@ -88,9 +101,19 @@ public void withMixedContentWhiteSpaceRight() throws BadLocationException {
@Test
public void withMixedContentNoWhiteSpaceRight() throws BadLocationException {
SharedSettings settings = new SharedSettings();
String content = "<a> test <b> content </b></a>";
String expected = "<a> test <b> content </b></a>";
assertFormat(content, expected, settings);
settings.getFormattingSettings().setMaxLineWidth(20);
settings.getFormattingSettings().setJoinContentLines(true);
String content = "<a>abcd \r\n efgh</a>";
String expected = "<a>abcd efgh</a>";
assertFormat(content, expected, settings, //
te(0, 7, 1, 3, " "));
assertFormat(expected, expected, settings);
}

private static void assertFormat(String unformatted, String expected, TextEdit... expectedEdits)
throws BadLocationException {
SharedSettings settings = new SharedSettings();
assertFormat(unformatted, expected, settings, "test://test.html", true, expectedEdits);
}

private static void assertFormat(String unformatted, String expected, SharedSettings sharedSettings,
Expand All @@ -104,16 +127,4 @@ private static void assertFormat(String unformatted, String expected, SharedSett
sharedSettings.getFormattingSettings().setExperimental(true);
XMLAssert.assertFormat(null, unformatted, expected, sharedSettings, uri, considerRangeFormat, expectedEdits);
}

private static void assertFormat(String unformatted, String actual, Integer maxLineWidth)
throws BadLocationException {
SharedSettings sharedSettings = new SharedSettings();
if (maxLineWidth != null) {
sharedSettings.getFormattingSettings().setMaxLineWidth(maxLineWidth);
}
// Force to "experimental" formatter
sharedSettings.getFormattingSettings().setExperimental(true);
sharedSettings.getFormattingSettings().setJoinContentLines(true);
XMLAssert.assertFormat(unformatted, actual, sharedSettings, "test.xml", Boolean.FALSE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ public void preserveAttributeLineBreaks6() throws BadLocationException {
settings.getFormattingSettings().setPreserveAttributeLineBreaks(true);
String content = "<a attr=\"value\"\n" + //
"</a>";
assertFormat(content, content, settings);
String expected = content;
assertFormat(content, expected, settings);
}

@Test
Expand All @@ -175,7 +176,8 @@ public void preserveAttributeLineBreaks7() throws BadLocationException {
settings.getFormattingSettings().setPreserveAttributeLineBreaks(true);
String content = "<a attr=\"value\"\n" + //
"/>";
assertFormat(content, content, settings);
String expected = content;
assertFormat(content, expected, settings);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ public void testPreserveEmptyContentTag() throws BadLocationException {
String content = "<a>\n" + //
" " + //
"</a>";
String expected = "<a>\n" + //
" " + //
"</a>";
String expected = content;
assertFormat(content, expected, settings);
}

Expand All @@ -63,9 +61,7 @@ public void testPreserveTextContent() throws BadLocationException {
String content = "<a>\n" + //
" aaa " + //
"</a>";
String expected = "<a>\n" + //
" aaa " + //
"</a>";
String expected = content;
assertFormat(content, expected, settings);
}

Expand Down Expand Up @@ -110,8 +106,7 @@ public void testPreserveEmptyContentTagWithSiblingContent() throws BadLocationEx

String content = "<a>\n" + //
" zz <b> </b>tt </a>";
String expected = "<a>\n" + //
" zz <b> </b>tt </a>";
String expected = content;
assertFormat(content, expected, settings);
}

Expand All @@ -138,8 +133,7 @@ public void testPreserveEmptyContentTagWithSiblingWithComment() throws BadLocati

String content = "<a>\n" + //
" zz <b> </b>tt <!-- Comment --> </a>";
String expected = "<a>\n" + //
" zz <b> </b>tt <!-- Comment --> </a>";
String expected = content;
assertFormat(content, expected, settings);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ public void preserveSpacesWithXmlSpace2() throws BadLocationException {
public void preserveSpacesWithSettings() throws BadLocationException {
String content = "<a>b c</a>";
String expected = content;

SharedSettings settings = new SharedSettings();
settings.getFormattingSettings().setPreserveSpace(Arrays.asList("a"));
assertFormat(content, expected, settings);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,8 @@ public void testUseSingleQuotesLocalDTDUnclosedStart() throws BadLocationExcepti
settings.getPreferences().setQuoteStyle(QuoteStyle.singleQuotes);
settings.getFormattingSettings().setEnforceQuoteStyle(EnforceQuoteStyle.preferred);
String content = "<!DOCTYPE note SYSTEM note.dtd\">";
String expected = "<!DOCTYPE note SYSTEM note.dtd\">";
String expected = content;
assertFormat(content, expected, settings);
assertFormat(expected, expected, settings);
}

@Test
Expand All @@ -283,9 +282,8 @@ public void testUseSingleQuotesLocalDTDUnclosedEnd() throws BadLocationException
settings.getPreferences().setQuoteStyle(QuoteStyle.singleQuotes);
settings.getFormattingSettings().setEnforceQuoteStyle(EnforceQuoteStyle.preferred);
String content = "<!DOCTYPE note SYSTEM \"note.dtd>";
String expected = "<!DOCTYPE note SYSTEM \"note.dtd>";
String expected = content;
assertFormat(content, expected, settings);
assertFormat(expected, expected, settings);
}

@Test
Expand Down Expand Up @@ -530,7 +528,6 @@ public void dontEnforceSingleQuoteStyleProlog() throws BadLocationException {
String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
String expected = content;
assertFormat(content, expected, settings);
assertFormat(expected, expected, settings);
}

@Test
Expand All @@ -542,7 +539,6 @@ public void dontEnforceDoubleQuoteStyleProlog() throws BadLocationException {
String content = "<?xml version=\'1.0\' encoding=\'UTF-8\'?>";
String expected = content;
assertFormat(content, expected, settings);
assertFormat(expected, expected, settings);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public void testNestedAttributesNoSplit() throws BadLocationException {
@Test
public void testSplitAttributesProlog() throws BadLocationException {
String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
String expected = content;
SharedSettings settings = new SharedSettings();
settings.getFormattingSettings().setSplitAttributes(true);
assertFormat(content, expected, settings);
Expand All @@ -162,7 +162,7 @@ public void testSplitAttributesProlog() throws BadLocationException {
@Test
public void testSplitAttributesSingle() throws BadLocationException {
String content = "<a k1=\"v1\"></a>";
String expected = "<a k1=\"v1\"></a>";
String expected = content;
SharedSettings settings = new SharedSettings();
settings.getFormattingSettings().setSplitAttributes(true);
assertFormat(content, expected, settings);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ public void testXSDForEmptyMixedElement() throws Exception {
settings.getFormattingSettings().setGrammarAwareFormatting(true);
try {
assertFormat(content, expected, settings);
assertFormat(expected, expected, settings);
} catch (Exception ex) {
fail("Formatter failed to process text", ex);
}
Expand Down

0 comments on commit f6c8d9a

Please sign in to comment.