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

Wiki links with anchor reference, MultiMarkdown style footnotes and fix for inline code mistaken for fence startMul #201

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
49 changes: 48 additions & 1 deletion README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,54 @@ Currently _pegdown_ supports the following extensions over standard Markdown:
* EXTANCHORLINKS: Generate anchor links for headers using complete contents of the header.
* Spaces and non-alphanumerics replaced by `-`, multiple dashes trimmed to one.
* Anchor link is added as first element inside the header with empty content: `<h1><a name="header"></a>header</h1>`

* EXTANCHORLINKS_WRAP: used in conjunction with above to create an anchor that wraps header content: `<h1><a name="header">header</a></h1>`
* FOOTNOTES: Support MultiMarkdown style footnotes: `[^n] for footnote reference` and `[^n]: Footnote text` for footnotes. Where `n` is one or more digit, letter, `-`, `_` or `.`. Footnotes will be put at the bottom of the page, sequentially numbered in order of appearance of the footnote reference. Footnotes that are not referenced will NOT be included in the HTML output.

```markdown
This paragraph has a footnote[^1] and another footnote[^two].

This one has more but out of sequence[^4] and[^eight].

[^two]: Footnote 2 with a bit more text
and another continuation line

[^1]: Footnote 1

[^3]: Unused footnote, it will not be added to the end of the page.

[^4]: Out of sequence footnote

[^eight]: Have one that is used.
```

will generate:

```html
<p>This paragraph has a footnote<sup id="fnref-1"><a href="#fn-1" class="footnote-ref">1</a></sup> and another footnote<sup id="fnref-2"><a href="#fn-2" class="footnote-ref">2</a></sup>.</p>
<p>This one has more but out of sequence<sup id="fnref-3"><a href="#fn-3" class="footnote-ref">3</a></sup> and<sup id="fnref-4"><a href="#fn-4" class="footnote-ref">4</a></sup>. </p><div class="footnotes">
<hr/>
<ol>
<li id="fn-1"><p>Footnote 1<a href="#fnref-1" class="footnote-backref">&#8617;</a></p></li>
<li id="fn-2"><p>Footnote 2 with a bit more text and another continuation line<a href="#fnref-2" class="footnote-backref">&#8617;</a></p></li>
<li id="fn-3"><p>Out of sequence footnote<a href="#fnref-3" class="footnote-backref">&#8617;</a></p></li>
<li id="fn-4"><p>Have one that is used.<a href="#fnref-4" class="footnote-backref">&#8617;</a></p></li>
</ol>
</div>
```
to look like this:

<p>This paragraph has a footnote<sup id="fnref-1"><a href="#fn-1" class="footnote-ref">1</a></sup> and another footnote<sup id="fnref-2"><a href="#fn-2" class="footnote-ref">2</a></sup>.</p>
<p>This one has more but out of sequence<sup id="fnref-3"><a href="#fn-3" class="footnote-ref">3</a></sup> and<sup id="fnref-4"><a href="#fn-4" class="footnote-ref">4</a></sup>. </p><div class="footnotes">
<hr/>
<ol>
<li id="fn-1"><p>Footnote 1<a href="#fnref-1" class="footnote-backref">&#8617;</a></p></li>
<li id="fn-2"><p>Footnote 2 with a bit more text and another continuation line<a href="#fnref-2" class="footnote-backref">&#8617;</a></p></li>
<li id="fn-3"><p>Out of sequence footnote<a href="#fnref-3" class="footnote-backref">&#8617;</a></p></li>
<li id="fn-4"><p>Have one that is used.<a href="#fnref-4" class="footnote-backref">&#8617;</a></p></li>
</ol>
</div>


Note: _pegdown_ differs from the original Markdown in that it ignores in-word emphasis as in

> my_cool_file.txt
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name := "pegdown"

version := "1.6.0"
version := "1.6.5"

homepage := Some(new URL("http://pegdown.org"))

Expand Down
20 changes: 16 additions & 4 deletions src/main/java/org/pegdown/Extensions.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public interface Extensions {

/**
* All of the smartypants prettyfications. Equivalent to SMARTS + QUOTES.
*
*
* @see <a href="http://daringfireball.net/projects/smartypants/">Smartypants</a>
*/
static final int SMARTYPANTS = SMARTS + QUOTES;
Expand Down Expand Up @@ -71,7 +71,7 @@ public interface Extensions {
* @see <a href="http://fletcherpenney.net/multimarkdown/users_guide/">MultiMarkdown</a>
*/
static final int TABLES = 0x20;

/**
* PHP Markdown Extra style definition lists.
* Additionally supports the small extension proposed in the article referenced below.
Expand Down Expand Up @@ -153,11 +153,23 @@ public interface Extensions {
*/
static final int EXTANCHORLINKS = 0x00400000;

/**
* EXTANCHORLINKS should wrap header content instead of creating an empty anchor.
* Anchor link wrapps the header content: `<h1><a name="header-a">header a</a></h1>`
*/
static final int EXTANCHORLINKS_WRAP = 0x00800000;

/**
* Enables footnote processing [^1]: Text Paragraph with continuations
* and footnote reference [^1]
*/
static final int FOOTNOTES = 0x01000000;

/**
* All Optionals other than Suppress and FORCELISTITEMPARA which is a backwards compatibility extension
*
*/

static final int ALL_OPTIONALS = (ATXHEADERSPACE | RELAXEDHRULES | TASKLISTITEMS | EXTANCHORLINKS);
static final int ALL_WITH_OPTIONALS = ALL | (ATXHEADERSPACE | RELAXEDHRULES | TASKLISTITEMS);
static final int ALL_OPTIONALS = (ATXHEADERSPACE | RELAXEDHRULES | TASKLISTITEMS | EXTANCHORLINKS | FOOTNOTES);
static final int ALL_WITH_OPTIONALS = ALL | (ATXHEADERSPACE | RELAXEDHRULES | TASKLISTITEMS | FOOTNOTES);
}
30 changes: 26 additions & 4 deletions src/main/java/org/pegdown/LinkRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
import org.parboiled.common.StringUtils;
import org.pegdown.ast.*;

import static org.pegdown.FastEncoder.*;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import static org.pegdown.FastEncoder.encode;
import static org.pegdown.FastEncoder.obfuscate;

/**
* A LinkRenderer is responsible for turning an AST node representing a link into a {@link LinkRenderer.Rendering}
* instance, which hold the actual properties of the link as it is going to be rendered.
Expand Down Expand Up @@ -50,6 +51,20 @@ public Rendering withAttribute(String name, String value) {
}

public Rendering withAttribute(Attribute attr) {
int iMax = attributes.size();

// vsch: a little wasteful, a Map would be better, but we don't have too many attributes and
// this will not break code for those that have implemented their own derived ToHtmlSerializers.
for (int i = 0; i < iMax; i++) {
Attribute attribute = attributes.get(i);
if (attribute.name.equals(attr.name)) {
// vsch: need to handle setting multiple classes, works for values too
// concatenate them with space between values, as for class
attr = new Attribute(attr.name, attribute.value + " " + attr.value);
attributes.remove(i);
break;
}
}
attributes.add(attr);
return this;
}
Expand Down Expand Up @@ -97,10 +112,17 @@ public Rendering render(WikiLinkNode node) {
int pos;
if ((pos = text.indexOf("|")) >= 0) {
url = text.substring(0, pos);
text = text.substring(pos+1);
text = text.substring(pos + 1);
}

// vsch: #200 WikiLinks can have anchor # refs
String suffix = "";
if ((pos = url.lastIndexOf("#")) >= 0) {
suffix = url.substring(pos);
url = url.substring(0, pos);
}

url = "./" + URLEncoder.encode(url.replace(' ', '-'), "UTF-8") + ".html";
url = "./" + URLEncoder.encode(url.replace(' ', '-'), "UTF-8") + ".html" + suffix;
return new Rendering(url, text);
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException();
Expand Down
Loading