Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace remark with flexmark-java #1607

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/pr-verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up JDK 8
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '8'
java-version: '11'
distribution: 'temurin'
cache: 'maven'
- name: Run Tests
Expand Down
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
"editor.tabSize": 4,
"editor.insertSpaces": false,
"java.compile.nullAnalysis.mode": "automatic",
"java.configuration.updateBuildConfiguration": "interactive",
}
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ and can be used with any editor that supports the protocol, to offer good suppor
* [Eclipse LSP4J](https://github.com/eclipse/lsp4j), the Java binding for the Language Server Protocol.
* Xerces to manage XML Schema validation, completion and hover

**LemMinX** requires a Java 11+ JVM to run.

Features
--------------

Expand Down
24 changes: 20 additions & 4 deletions org.eclipse.lemminx/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -231,14 +231,30 @@
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>com.kotcrab.remark</groupId>
<artifactId>remark</artifactId>
<version>1.0.0</version>
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark-html2md-converter</artifactId>
<version>0.64.8</version>
<!-- for versions >= 0.64.0, Java 11 is required -->
<exclusions>
<exclusion>
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark-jira-converter</artifactId>
</exclusion>
<exclusion>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.10.0</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.14.2</version>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>xml-resolver</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ private Node nodeByOffset(final int offset) throws BadLocationException {
if (node == null) {
fail(offset);
}

if (remaining < node.offset) {
node = node.left;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ public class ConfigurationItemEdit extends ConfigurationItem {
private Object value;
private ConfigurationItemEditType editType;
private ConfigurationItemValueKind valueKind;

public ConfigurationItemEdit () {
// Need explicit no-arg constructor for deserialization
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,9 @@ private static String removeFileScheme(String fileURI, boolean removeLastSlash)
* @return the given file Uri to a File.
*/
public static File toFile(String fileUri) {
String convertedUri = fileUri.replace("file:///", "file:/"); //$NON-NLS-1$//$NON-NLS-2$
convertedUri = convertedUri.replace("file://", "file:/"); //$NON-NLS-1$//$NON-NLS-2$
return new File(URI.create(convertedUri));
//String convertedUri = fileUri.replace("file:///", "file:/"); //$NON-NLS-1$//$NON-NLS-2$
//convertedUri = convertedUri.replace("file://", "file:/"); //$NON-NLS-1$//$NON-NLS-2$
return new File(URI.create(fileUri));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,15 @@
*******************************************************************************/
package org.eclipse.lemminx.utils;

import static org.apache.commons.lang3.StringEscapeUtils.unescapeJava;
import static org.apache.commons.lang3.StringEscapeUtils.unescapeXml;
import static org.apache.commons.text.StringEscapeUtils.unescapeJava;
import static org.apache.commons.text.StringEscapeUtils.unescapeXml;

import java.lang.reflect.Field;
import java.util.logging.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.overzealous.remark.Options;
import com.overzealous.remark.Options.FencedCodeBlocks;
import com.overzealous.remark.Options.Tables;
import com.overzealous.remark.Remark;

import org.jsoup.safety.Cleaner;
import org.jsoup.safety.Safelist;
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter;

/**
* Converts HTML content into Markdown equivalent.
Expand All @@ -33,46 +29,60 @@
*/
public class MarkdownConverter {

private static final Logger LOGGER = Logger.getLogger(MarkdownConverter.class.getName());

private static Remark remark;
private static final FlexmarkHtmlConverter CONVERTER = FlexmarkHtmlConverter.builder().build();

private MarkdownConverter(){
//no public instanciation
private MarkdownConverter() {
// no public instanciation
}

static {
Options options = new Options();
options.tables = Tables.CONVERT_TO_CODE_BLOCK;
options.hardwraps = true;
options.inlineLinks = true;
options.autoLinks = true;
options.reverseHtmlSmartPunctuation = true;
options.fencedCodeBlocks = FencedCodeBlocks.ENABLED_BACKTICK;
remark = new Remark(options);
//Stop remark from stripping file protocol in an href
try {
Field cleanerField = Remark.class.getDeclaredField("cleaner");
cleanerField.setAccessible(true);

Cleaner c = (Cleaner) cleanerField.get(remark);

Field safelistField = Cleaner.class.getDeclaredField("safelist");
safelistField.setAccessible(true);

Safelist s = (Safelist) safelistField.get(c);
public static String convert(String html) {
if (!StringUtils.isTagOutsideOfBackticks(html)) {
return unescapeXml(html); // is not html so it can be returned as-is (aside from unescaping)
}

s.addProtocols("a", "href", "file");
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
LOGGER.severe("Unable to modify jsoup to include file protocols "+ e.getMessage());
Document document = Jsoup.parse(html);
//Add missing table headers if necessary, else most Markdown renderers will crap out
document.select("table").forEach(MarkdownConverter::addMissingTableHeaders);

String markdown = CONVERTER.convert(document);
if (markdown.endsWith("\n")) {// FlexmarkHtmlConverter keeps adding an extra line
markdown = markdown.substring(0, markdown.length() - 1);
}
return unescapeJava(markdown);
}

public static String convert(String html) {
if(!StringUtils.isTagOutsideOfBackticks(html)) {
return unescapeXml(html); // is not html so it can be returned as is (aside from unescaping)
/**
* Adds a new row header if the given table doesn't have any.
* @param table the HTML table to check for a header
*/
private static void addMissingTableHeaders(Element table) {
int numCols = 0;
for (Element child : table.children()) {
if ("thead".equals(child.nodeName())) {
// Table already has a header, nothing else to do
return;
}
if ("tbody".equals(child.nodeName())) {
Elements rows = child.getElementsByTag("tr");
if (!rows.isEmpty()) {
for (Element row : rows) {
int colSize = row.getElementsByTag("td").size();
//Keep the biggest column size
if (colSize > numCols) {
numCols = colSize;
}
}
}
}
}
if (numCols > 0) {
//Create a new header row based on the number of columns already found
Element newHeader = new Element("tr");
for (int i = 0; i < numCols; i++) {
newHeader.appendChild(new Element("th"));
}
//Insert header row in 1st position in the table
table.insertChildren(0, newHeader);
}
return unescapeJava(remark.convert(html));
}

}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
[
{
"name": "com.overzealous.remark.Remark",
"fields": [{
"name": "cleaner"
}]
"name": "java.lang.Object",
"allDeclaredMethods": true
},
{
"name": "java.lang.Object",
"name": "java.lang.Enum",
"allDeclaredMethods": true
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1327,8 +1327,8 @@ public static void assertDocumentLinks(List<DocumentLink> actual, DocumentLink..
assertEquals(expected.length, actual.size());
for (int i = 0; i < expected.length; i++) {
assertEquals(expected[i].getRange(), actual.get(i).getRange(), " Range test '" + i + "' link");
assertEquals(Paths.get(expected[i].getTarget()).toUri().toString().replace("file:///", "file:/"),
actual.get(i).getTarget().replace("file:///", "file:/"), " Target test '" + i + "' link");
assertEquals(Paths.get(expected[i].getTarget()).toUri().toString(),
actual.get(i).getTarget(), " Target test '" + i + "' link");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public void webXML() throws Exception {
"'" + cachedFilePath + "' file should be downloaded in the cache.");

// Process hover with the DTD (http dtd)
String dtdFileCacheURI = cachedFilePath.toUri().toString().replace("file:///", "file:/");
String dtdFileCacheURI = cachedFilePath.toUri().toString();
String xml = "<!DOCTYPE web-app PUBLIC\n" + //
" \"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN\"\n" + //
" \"" + httpDTDUri + "\" >\n" + //
Expand Down Expand Up @@ -122,7 +122,6 @@ private static void assertHoverWithCache(String value, String expectedHoverLabel
}

private static String getDTDFileURI(String dtdURI) throws MalformedURIException {
return XMLEntityManager.expandSystemId("dtd/" + dtdURI, "src/test/resources/test.xml", true).replace("///",
"/");
return XMLEntityManager.expandSystemId("dtd/" + dtdURI, "src/test/resources/test.xml", true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ private static void assertHover(String value, String fileURI, ContentModelSettin
}

private static String getXMLSchemaFileURI(String schemaURI) throws MalformedURIException {
return XMLEntityManager.expandSystemId("xsd/" + schemaURI, "src/test/resources/test.xml", true).replace("///",
"/");
return XMLEntityManager.expandSystemId("xsd/" + schemaURI, "src/test/resources/test.xml", true);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,7 @@ private SharedSettings createSharedSettings(SchemaDocumentationType docSource, b
}

private static String getXMLSchemaFileURI(String schemaURI) throws MalformedURIException {
return XMLEntityManager.expandSystemId("xsd/" + schemaURI, "src/test/resources/test.xml", true).replace("///",
"/");
return XMLEntityManager.expandSystemId("xsd/" + schemaURI, "src/test/resources/test.xml", true);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ private SharedSettings createSharedSettings(SchemaDocumentationType docSource, b
}

private static String getXMLSchemaFileURI(String schemaURI) throws MalformedURIException {
return XMLEntityManager.expandSystemId("xsd/" + schemaURI, "src/test/resources/test.xml", true).replace("///",
"/");
return XMLEntityManager.expandSystemId("xsd/" + schemaURI, "src/test/resources/test.xml", true);
}

private void assertHover(String xml, String expected, Range range) throws BadLocationException, MalformedURIException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,6 @@ private static void assertHover(String value, String expectedHoverLabel, Range e
}

private static String getXMLSchemaFileURI(String schemaURI) throws MalformedURIException {
return XMLEntityManager.expandSystemId("xsd/" + schemaURI, "src/test/resources/test.xml", true).replace("///",
"/");
return XMLEntityManager.expandSystemId("xsd/" + schemaURI, "src/test/resources/test.xml", true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ public class MarkdownConverterTest {
@Test
public void testHTMLConversion() {
assertEquals("This is `my code`", convert("This is <code>my code</code>"));
assertEquals("This is" + System.lineSeparator() + "**bold**", convert("This is<br><b>bold</b>"));
assertEquals("This is " + System.lineSeparator() + "**bold**", convert("This is<br><b>bold</b>"));
assertEquals("The `<project>` element is the root of the descriptor.", convert("The <code>&lt;project&gt;</code> element is the root of the descriptor."));
assertEquals("# Hey Man #", convert("<h1>Hey Man</h1>"));
assertEquals("Hey Man"+ System.lineSeparator()+"=======", convert("<h1>Hey Man</h1>"));
assertEquals("[Placeholder](https://www.xml.com)", convert("<a href=\"https://www.xml.com\">Placeholder</a>"));

String htmlList =
Expand All @@ -36,9 +36,9 @@ public void testHTMLConversion() {
" <li>Milk</li>" + System.lineSeparator() +
"</ul>";
String expectedList =
" * Coffee" + System.lineSeparator() +
" * Tea" + System.lineSeparator() +
" * Milk";
"* Coffee" + System.lineSeparator() +
"* Tea" + System.lineSeparator() +
"* Milk";
assertEquals(expectedList, convert(htmlList));
assertEquals("ONLY_THIS_TEXT", convert("<p>ONLY_THIS_TEXT</p>"));

Expand All @@ -54,10 +54,13 @@ public void testHTMLConversion() {
"line" + System.lineSeparator() +
"<code>HTML</code>" + System.lineSeparator() +
"stuff";
String multilineHTML2Expected =
String multilineHTML2Expected =
"multi" + System.lineSeparator() +
"" + System.lineSeparator() +
"line `HTML` stuff";
"" + System.lineSeparator() +
"line"+ System.lineSeparator() +
"`HTML`"+ System.lineSeparator() +
"stuff";
assertEquals(multilineHTML2Expected, convert(multilineHTML2));
}

Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
Expand Down
Loading