Skip to content

Commit 8dd0330

Browse files
committed
update samples
1 parent de911ee commit 8dd0330

3 files changed

Lines changed: 130 additions & 96 deletions

File tree

VERSION-TODO.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- [Release 0.60.0](#release-0600)
88
- [API Refactoring](#api-refactoring)
99
- [Next 0.61.xx](#next-061xx)
10+
- [0.61.18](#06118)
1011
- [0.61.16](#06116)
1112
- [0.61.14](#06114)
1213
- [0.61.12](#06112)
@@ -204,7 +205,7 @@ Please give feedback on the upcoming changes if you have concerns about breaking
204205
extension add order
205206
* [ ] Fix: Change spec example to variable number of sections
206207
* [ ] Add: yaml front matter configurator for modules. See: [Yaml Front Matter
207-
Configuration](../../wiki/Yaml-Front-Matter-Configuration)
208+
Configuration](../../wiki/Yaml-Front-Matter-Configuration)
208209
* [ ] Fix: table formatting caret position tracking affects alignment even when not inserting,
209210
just formatting. Need to keep track of whether format after typing or just format. Then
210211
caret position should only track but not force spaces behind it to be preserved. See
@@ -220,6 +221,14 @@ Please give feedback on the upcoming changes if you have concerns about breaking
220221
* [ ] Fix: Html converter to not add spaces between end of inline marker and next punctuation:
221222
`.,:;`
222223

224+
## 0.61.18
225+
226+
* Break: remove from `TocOptions` confusing and error prone `rawTitle` and `rawTitleLevel`. Now
227+
mutable toc options have to set `title` and `titleLevel` then call
228+
`TocOptions.AsMutable.normalizeTitle()`
229+
* Fix: add more debug trace information to markdown wrap tracked offset mismatch.
230+
231+
223232
## 0.61.16
224233

225234
* Fix: add range limit to `Escaping.replaceAll(Pattern, BasedSequence, List<Range>, Replacer,
@@ -239,9 +248,9 @@ Please give feedback on the upcoming changes if you have concerns about breaking
239248
* Add: `JekyllTagExtension.EMBED_INCLUDED_CONTENT`, default `false`. Set to `true` to embed
240249
included markdown content.
241250
* Fix: tracked paragraph wrapping when inserting space before EOL on a line when the word before
242-
caret will be wrapped to the next line. ie. the EOL will be removed.
251+
caret will be wrapped to the next line. ie. the EOL will be removed.
243252
* Deprecate: `JekyllTagExtension.ENABLE_RENDERING`, not used nor needed.
244-
* Fix: [#398, Autolinks get cut off if they contain \`&amp;\` (escaped query params)]
253+
* Fix: [#398, Autolinks get cut off if they contain \`&amp;\` (escaped query params)]
245254

246255
## 0.61.10
247256

@@ -2406,6 +2415,7 @@ Please give feedback on the upcoming changes if you have concerns about breaking
24062415
[#391, PR: Fix: CRLF line separator in fenced code blocks produce redundant CR.]: https://github.com/vsch/flexmark-java/pull/391
24072416
[#396, DocumentParser stops reading too early resulting in the document being cut off]: https://github.com/vsch/flexmark-java/issues/396
24082417
[#397, PR: Add base64 image support with docx rendering]: https://github.com/vsch/flexmark-java/pull/397
2418+
[#398, Autolinks get cut off if they contain \`&amp;\` (escaped query params)]: https://github.com/vsch/flexmark-java/issues/398
24092419
[@Xaelis]: https://github.com/Xaelis
24102420
[Awesome Console]: https://plugins.jetbrains.com/plugin/7677-awesome-console "Awesome Console"
24112421
[HtmlToMarkdownCustomizedSample.java]: https://github.com/vsch/flexmark-java/blob/master/flexmark-java-samples/src/com/vladsch/flexmark/java/samples/HtmlToMarkdownCustomizedSample.java
@@ -2418,6 +2428,4 @@ Please give feedback on the upcoming changes if you have concerns about breaking
24182428
[migrate flexmark-java 0_40_x to 0_42_0]: https://github.com/vsch/flexmark-java/blob/master/assets/migrations/migrate%20flexmark-java%200_40_x%20to%200_42_0.xml
24192429
<!-- @IGNORE PREVIOUS: link -->
24202430
[migrate flexmark-java 0_42_x to 0_50_0.xml]: https://github.com/vsch/flexmark-java/blob/master/assets/migrations/migrate%20flexmark-java%200_42_x%20to%200_50_0.xml
2421-
[#398, Autolinks get cut off if they contain \`&amp;\` (escaped query params)]: https://github.com/vsch/flexmark-java/issues/398
2422-
24232431

flexmark-java-samples/src/com/vladsch/flexmark/java/samples/CustomLinkResolverSample.java

Lines changed: 75 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import com.vladsch.flexmark.ast.Image;
44
import com.vladsch.flexmark.ast.Link;
55
import com.vladsch.flexmark.ast.Reference;
6+
import com.vladsch.flexmark.docx.converter.DocxRenderer;
7+
import com.vladsch.flexmark.docx.converter.internal.DocxLinkResolver;
8+
import com.vladsch.flexmark.ext.jekyll.tag.JekyllTagBlock;
69
import com.vladsch.flexmark.html.HtmlRenderer;
710
import com.vladsch.flexmark.html.HtmlRenderer.Builder;
811
import com.vladsch.flexmark.html.HtmlRenderer.HtmlRendererExtension;
@@ -33,36 +36,36 @@ public class CustomLinkResolverSample {
3336
static final HtmlRenderer RENDERER = HtmlRenderer.builder(OPTIONS).build();
3437

3538
public static class DocxLinkResolver implements LinkResolver {
36-
protected static final String[] EMPTY_STRINGS = new String[0];
3739
final private String docRelativeURL;
3840
final private String docRootURL;
3941
final private String[] relativeParts;
42+
final private boolean prefixWwwLinks;
4043

4144
public DocxLinkResolver(LinkResolverBasicContext context) {
4245
// can use context for custom settings
43-
// context.getDocument();
44-
// context.getHtmlOptions();
45-
String docRelativeURL = DOC_RELATIVE_URL.get(context.getOptions());
46-
if (docRelativeURL != null) {
47-
docRelativeURL = Utils.removePrefix(docRelativeURL, '/');
48-
}
49-
50-
String docRootURL = DOC_ROOT_URL.get(context.getOptions());
51-
if (docRootURL != null) {
52-
docRootURL = Utils.removePrefix(docRootURL, '/');
53-
}
46+
String docRelativeURL = DocxRenderer.DOC_RELATIVE_URL.get(context.getOptions());
47+
String docRootURL = DocxRenderer.DOC_ROOT_URL.get(context.getOptions());
5448
this.docRelativeURL = docRelativeURL;
5549
this.docRootURL = docRootURL;
56-
relativeParts = docRelativeURL == null ? EMPTY_STRINGS : docRelativeURL.split("/");
50+
51+
docRelativeURL = Utils.removePrefix(docRelativeURL, '/');
52+
53+
relativeParts = docRelativeURL.split("/");
54+
prefixWwwLinks = DocxRenderer.PREFIX_WWW_LINKS.get(context.getOptions());
5755
}
5856

5957
@NotNull
6058
@Override
6159
public ResolvedLink resolveLink(@NotNull Node node, @NotNull LinkResolverBasicContext context, @NotNull ResolvedLink link) {
62-
if (node instanceof Image || node instanceof Link || node instanceof Reference) {
63-
// resolve wiki image link
60+
if (node instanceof Image || node instanceof Link || node instanceof Reference || node instanceof JekyllTagBlock) {
6461
String url = link.getUrl();
6562

63+
if (docRelativeURL.isEmpty() && docRootURL.isEmpty()) {
64+
// resolve url, return one of LinkStatus other than LinkStatus.UNKNOWN
65+
return link.withStatus(LinkStatus.VALID)
66+
.withUrl(url);
67+
}
68+
6669
if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("ftp://") || url.startsWith("sftp://")) {
6770
// resolve url, return one of LinkStatus other than LinkStatus.UNKNOWN
6871
return link.withStatus(LinkStatus.VALID)
@@ -71,63 +74,78 @@ public ResolvedLink resolveLink(@NotNull Node node, @NotNull LinkResolverBasicCo
7174
// assume it is good
7275
return link.withStatus(LinkStatus.VALID)
7376
.withUrl(url);
77+
} else if (url.startsWith(DocxRenderer.EMOJI_RESOURCE_PREFIX)) {
78+
// assume it is good
79+
return link.withStatus(LinkStatus.VALID)
80+
.withUrl(url);
7481
} else if (url.startsWith("/")) {
7582
if (docRootURL != null && !docRootURL.isEmpty()) {
7683
// this one is root url, prefix with root url, without the trailing /
7784
url = docRootURL + url;
78-
85+
if (!url.startsWith("file:")) url = "file://" + url;
7986
return link.withStatus(LinkStatus.VALID)
8087
.withUrl(url);
8188
}
82-
} else if (!url.matches("^(?:[a-z]+:|#|\\?)")) {
89+
} else if (prefixWwwLinks && url.startsWith("www.")) {
90+
// should be prefixed with http://, we will just add it
91+
return link.withStatus(LinkStatus.INVALID)
92+
.withUrl("http://" + url);
93+
} else if (!url.startsWith("data:") && !url.matches("^(?:[a-z]+:|#|\\?)")) {
8394
// relative, we will process it as a relative path to the docRelativeURL
8495
String pageRef = url;
8596
String suffix = "";
8697
int pos = url.indexOf('#');
87-
if (pos > 0) {
88-
// remove anchor
89-
suffix = url.substring(pos);
90-
pageRef = url.substring(0, pos);
91-
} else if (url.contains("?")) {
92-
// remove query
93-
suffix = url.substring(pos);
94-
pageRef = url.substring(0, pos);
95-
}
98+
if (pos == 0) {
99+
return link.withStatus(LinkStatus.VALID);
100+
} else {
101+
if (pos > 0) {
102+
// remove anchor
103+
suffix = url.substring(pos);
104+
pageRef = url.substring(0, pos);
105+
} else if (url.contains("?")) {
106+
// remove query
107+
pos = url.indexOf("?");
108+
suffix = url.substring(pos);
109+
pageRef = url.substring(0, pos);
110+
}
111+
112+
String[] pathParts = pageRef.split("/");
113+
int docParts = relativeParts.length;
114+
int iMax = pathParts.length;
115+
StringBuilder resolved = new StringBuilder();
116+
String sep = "";
117+
118+
for (int i = 0; i < iMax; i++) {
119+
String part = pathParts[i];
120+
if (part.equals(".")) {
121+
// skp
122+
} else if (part.equals("..")) {
123+
// remove one doc part
124+
if (docParts == 0) return link;
125+
docParts--;
126+
} else {
127+
resolved.append(sep);
128+
resolved.append(part);
129+
sep = "/";
130+
}
131+
}
96132

97-
String[] pathParts = pageRef.split("/");
98-
int docParts = relativeParts.length;
99-
int iMax = pathParts.length;
100-
StringBuilder resolved = new StringBuilder();
101-
String sep = "";
102-
103-
for (int i = 0; i < iMax; i++) {
104-
String part = pathParts[i];
105-
if (part.equals(".")) {
106-
// skp
107-
} else if (part.equals("..")) {
108-
// remove one doc part
109-
if (docParts == 0) return link;
110-
docParts--;
111-
} else {
112-
resolved.append(sep);
113-
resolved.append(part);
133+
// prefix with remaining docParts
134+
sep = docRelativeURL.startsWith("/") ? "/" : "";
135+
StringBuilder resolvedPath = new StringBuilder();
136+
iMax = docParts;
137+
for (int i = 0; i < iMax; i++) {
138+
resolvedPath.append(sep);
139+
resolvedPath.append(relativeParts[i]);
114140
sep = "/";
115141
}
116-
}
117142

118-
// prefix with remaining docParts
119-
sep = docRelativeURL.startsWith("/") ? "/" : "";
120-
StringBuilder resolvedURL = new StringBuilder();
121-
iMax = docParts;
122-
for (int i = 0; i < iMax; i++) {
123-
resolvedURL.append(sep);
124-
resolvedURL.append(relativeParts[i]);
125-
sep = "/";
143+
resolvedPath.append('/').append(resolved).append(suffix);
144+
String resolvedUri = resolvedPath.toString();
145+
if (!resolvedUri.startsWith("file:")) resolvedUri = "file://" + resolvedUri;
146+
return link.withStatus(LinkStatus.VALID)
147+
.withUrl(resolvedUri);
126148
}
127-
128-
resolvedURL.append('/').append(resolved).append(suffix);
129-
return link.withStatus(LinkStatus.VALID)
130-
.withUrl(resolvedURL.toString());
131149
}
132150
}
133151
return link;
@@ -158,7 +176,7 @@ public LinkResolver apply(@NotNull LinkResolverBasicContext context) {
158176
}
159177
}
160178
}
161-
179+
162180
static class CustomExtension implements HtmlRendererExtension {
163181
@Override
164182
public void rendererOptions(@NotNull MutableDataHolder options) {

flexmark-java-samples/src/com/vladsch/flexmark/java/samples/JekyllIncludeFileSample.java

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@
1010
import com.vladsch.flexmark.util.data.MutableDataHolder;
1111
import com.vladsch.flexmark.util.data.MutableDataSet;
1212

13-
import java.util.Arrays;
14-
import java.util.HashMap;
15-
import java.util.List;
16-
import java.util.Map;
13+
import java.util.*;
1714

1815
public class JekyllIncludeFileSample {
1916
static String commonMark(String markdown, Map<String, String> included) {
@@ -26,40 +23,51 @@ static String commonMark(String markdown, Map<String, String> included) {
2623
Parser parser = Parser.builder(options).build();
2724
HtmlRenderer renderer = HtmlRenderer.builder(options).build();
2825

29-
Node document = parser.parse(markdown);
26+
Document document = parser.parse(markdown);
3027

3128
// see if document has includes
32-
if (document instanceof Document) {
33-
Document doc = (Document) document;
34-
if (doc.contains(JekyllTagExtension.TAG_LIST)) {
35-
List<JekyllTag> tagList = JekyllTagExtension.TAG_LIST.get(doc);
36-
Map<String, String> includeHtmlMap = new HashMap<>();
37-
38-
for (JekyllTag tag : tagList) {
39-
String includeFile = tag.getParameters().toString();
40-
if (tag.getTag().equals("include") && !includeFile.isEmpty() && !includeHtmlMap.containsKey(includeFile)) {
41-
// see if it exists
42-
if (included.containsKey(includeFile)) {
43-
// have the file
44-
String text = included.get(includeFile);
45-
46-
if (includeFile.endsWith(".md")) {
47-
Document includeDoc = parser.parse(text);
48-
String includeHtml = renderer.render(includeDoc);
49-
includeHtmlMap.put(includeFile, includeHtml);
50-
51-
if (includeDoc instanceof Document) {
52-
// copy any definition of reference elements from included file to our document
53-
parser.transferReferences(doc, includeDoc, null);
54-
}
55-
} else {
56-
includeHtmlMap.put(includeFile, text);
57-
}
29+
Document doc = (Document) document;
30+
if (doc.contains(JekyllTagExtension.TAG_LIST)) {
31+
List<JekyllTag> tagList = JekyllTagExtension.TAG_LIST.get(doc);
32+
Map<String, String> includeHtmlMap = new HashMap<>();
33+
ArrayList<Document> includedDocs = new ArrayList<>();
34+
35+
for (JekyllTag tag : tagList) {
36+
String includeFile = tag.getParameters().toString();
37+
if (tag.getTag().equals("include") && !includeFile.isEmpty() && !includeHtmlMap.containsKey(includeFile)) {
38+
// see if it exists
39+
if (included.containsKey(includeFile)) {
40+
// have the file
41+
String text = included.get(includeFile);
42+
43+
if (includeFile.endsWith(".md")) {
44+
Document includeDoc = parser.parse(text);
45+
String includeHtml = renderer.render(includeDoc);
46+
47+
includeHtmlMap.put(includeFile, includeHtml);
48+
49+
// copy any definition of reference elements from included file to our document
50+
includedDocs.add(includeDoc);
51+
} else {
52+
includeHtmlMap.put(includeFile, text);
5853
}
5954
}
55+
}
6056

61-
if (!includeHtmlMap.isEmpty()) {
62-
doc.set(JekyllTagExtension.INCLUDED_HTML, includeHtmlMap);
57+
// Need to reparse document because embedding is done by a NodePostProcessor at the end of the parsing processing
58+
//
59+
// NOTE: an alternative is to append to JekyllTagBlock nodes which will render the embedded content using custom nodes and custom node renderer
60+
if (!includeHtmlMap.isEmpty()) {
61+
options.set(JekyllTagExtension.INCLUDED_HTML, includeHtmlMap);
62+
options.set(JekyllTagExtension.EMBED_INCLUDED_CONTENT, true);
63+
64+
parser = Parser.builder(options).build();
65+
renderer = HtmlRenderer.builder(options).build();
66+
67+
document = parser.parse(markdown);
68+
69+
for (Document includedDoc : includedDocs) {
70+
parser.transferReferences(document, includedDoc, null);
6371
}
6472
}
6573
}
@@ -78,7 +86,7 @@ public static void main(String[] args) {
7886
"[ref]: http://example.com\n" +
7987
"");
8088

81-
included.put("test.html", "<p>some text</p>\n" +
89+
included.put("test.html", "<p>test.html: some text</p>\n" +
8290
"");
8391

8492
String html = commonMark("http://github.com/vsch/flexmark-java\n" +

0 commit comments

Comments
 (0)