GithubHelp home page GithubHelp logo

sirthias / pegdown Goto Github PK

View Code? Open in Web Editor NEW
1.3K 1.3K 218.0 11.44 MB

A pure-Java Markdown processor based on a parboiled PEG parser supporting a number of extensions

Home Page: http://pegdown.org

License: Apache License 2.0

Scala 6.67% Java 46.98% HTML 46.04% GCC Machine Description 0.32%

pegdown's People

Contributors

abatkin avatar annmalachi avatar big-guy avatar brettporter avatar deraen avatar elmervc avatar esamson avatar gitblit avatar gpicron avatar jbunting avatar jirutka avatar jroper avatar kungfoo avatar kyegupov avatar ltheussl avatar martinklepsch avatar nicoulaj avatar pepoirot avatar rroopreddy avatar sirthias avatar sonson avatar valery1707 avatar vsch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pegdown's Issues

Incorrect HTML Output

I recently started using Pegdown in a project I'm working on and have been very impressed. One thing I have noticed however is that it seems to produce incorrect HTML for Markdown images. For example, the following Markdown:

![Cascading Style Sheets](http://jigsaw.w3.org/css-validator/images/vcss)

Becomes:

<img src="http://jigsaw.w3.org/css-validator/images/vcss">Cascading Style Sheets</img>

When, according to http://daringfireball.net/projects/markdown/syntax it should be setting the alt attribute, as such:

<img src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Cascading Style Sheets" />

I noticed that the test clase test-cases/docs-maruku/images.html shows this working correctly, so perhaps a recent change as broken it?

To tried to get around this by just omitting the alt text in the markdown, however the parser then seems to not recognize it as an image. For example:

![](http://jigsaw.w3.org/css-validator/images/vcss)

Using other markdown parsers, this seems to be legal syntax.

Automatic links, as described by John Gruber's link above, seem to also have a slight issue. When given something as such:

<http://example.com/>

The result is:

<a href="http://example.com>">http://example.com></a>

The image problem seems to occur with or without extensions, while the automatic linking syntax problem seems to occur only when I have the extensions on (perhaps a conflict with GitHub style automatic linking?)

This implementation of Markdown is one of the best I've seen, thank you for sharing all your hard work!

NOTE: All instances of & lt; and & gt; above should actually be < and >. Not sure why Github Markdown is doing that.

Strong inside emphasis renders incorrectly

It appears that putting a strong (bold) inside an emphasis (italic) using the same character renders incorrectly.

Example:

*This is a **test***

Expected Output:

<p><em>This is a <strong>test</strong></em></p>

_This is a _test**

Actual Output:

<p><em>This is a </em><em>test</em>**</p>

This is a test**

The bold tag doesn't need to be at the end: *This **is a ** test* is also rendered incorrectly.

The inverse isn't a problem (ie: **This is a *test*** renders fine).

It looks like a single asterisk is getting priority over a double asterisk. I haven't had time to dig into the source to see what's going on yet.

Improve parser extensibility

The Parser class has some inner classes the prevent it being subtyped. Parboiled generates some methods that can't be seen from a subtype.

See the fork stickycode/pegdown for a solution....

I'm implementing includes for source code samples and might look at folding it back into the core if it makes sense but it would probably be too many dependencies so thought it best as an external extension.

Disabling HTML

The ability to disable HTML via an option would be very useful for cases where people would like to use only markdown syntax. For example, markdown could be allowed in a blog's comments but not HTML so that commenters could safely include things such as code blocks and emphasis (this is the case I would like to use it in). PHP Markdown provides this through the use of the no_markup option.

This could theoretically be implemented either before or after using the markdown parser, but I think it would be much more beneficial and efficient to have this included in the parser itself.

Feature proposal: definition list

Definition lists are an useful semantical markup means for many documents. While the original markdown does not include a syntax for this there are other implementations doing so.

So, what about making a pegdown extension for parsing a definition list markup?

The blog entry http://www.justatheory.com/computers/markup/modest-markdown-proposal.html is pretty good in explaining the appropriate syntax from markdown extra and furthermore proposes a slight improvement for it.

Some characters/sequences break links

Here are some examples of links that should work but don't:

[ex@mple](http://example)
[example://](http://example)

This must have something to do with autolinks detection, I guess ?

Disappearing backslash

When transforming some text to Markdown I observed that backslashes were disappearing:

  def processor = new PegDownProcessor(ALL & ~QUOTES & ~SMARTS)
  processor.markdownToText("hello\\ world")

  => <p>hello world</p> // instead of <p>hello\ world</p>

I had the same issue earlier with specs2 when using "regex".r.replaceAllIn(someString, groupMatches) so maybe that's something you're using internally somewhere?

Will pegdown support code blocks wrapped in ``` and ```?

In standard markdown, code blocks must be indented with 4 spaces or a tab, but it's not convenient if we copy some code from somewhere else, that we usually have to correct the format line by line manually, sometimes it's a hard work.

I wonder if pegdown support code blocks wrapped in ``` and ```, such as:

```
class A
class B
```

This will make things easier.

Extremely slow when bold AND italics inside links

Pegdown is usually really fast, but something goes wrong when there's a bunch of links with bold _and_ italics inside the label.

For example, this basically never completes on my machine. Yes, it's odd, but I'm trying to write something to convert backward from HTML to Markdown with Pegdown extras (mostly for fun), and I was using a Wikipedia page. This is just a snippet:

 1. ^ [***a***][link143][***b***][link144][***c***][link145][***d***][link146][***e***][link147][***f***][link148][***g***][link149][***h***][link150][***i***][link151][***j***][link152][***k***][link153][***l***][link154][***m***][link155][***n***][link156][***o***][link157][***p***][link158][***q***][link159] Scheina, "Argentina," 401.

[link143]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-0
[link144]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-1
[link145]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-2
[link146]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-3
[link147]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-4
[link148]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-5
[link149]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-6
[link150]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-7
[link151]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-8
[link152]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-9
[link153]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-10
[link154]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-11
[link155]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-12
[link156]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-13
[link157]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-14
[link158]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-15
[link159]: http://en.wikipedia.org/wiki/ARA_Moreno#cite_ref-Conways_0-16

Now, if you replace all the *** with **, *, or nothing, it runs just fine. None of the other parsers I've been playing with seem to have this issue. (TextMate, Mac OS X quicklook, and a program called Readown.)

Reducing the number of links helps, too, but it still runs rather slow.

Code block followed immediately by a definition isn't rendered correctly

This is another low-priority oddball. When a fenced codeblock is immediately followed by a "<dd>", the codeblock is not processed.

Example:

~~~
this is code
~~~

:   this is a definition

If the definition has a term preceding it, it renders as expected:

~~~
this is code
~~~

Term
:   this is a definition

Now for the really weird stuff. If I add two linebreaks, the code renders correctly, but the definition now doesn't:

~~~
this is code
~~~


:   this is a definition

The same thing happens if we change the fenced code block to a normal code block, but leave the single space:

    this is code

:   this is a definition

The order matters. A fenced code block coming after a single "dd" always works.

Special character encoding fails with 0.9.x

I have just recently begun to use pegdown in a project and so far I am finding it to be a nice library. One thing I have noticed though, even with 0.9.x series, I am unable to escape special characters correctly when they are not placed within a markdown tag that generates a link.

For example if I do this:
example

The & does correctly become &.

If on the other hand I do something like what is found in the Special Chars.text, the special characters are not correctly replaced with the escaped counterparts.

I have attempted to use different combinations of the Extensions ranging from none to all and combination of the extensions seem to change how the special characters are handled.

Thank you for sharing this easy to use implementation of markdown.

Parsing of underscores slow

Pegdown needs too long (hours) for parsing the simple string A<hr>B_C_D_E_F_G_H_I_J_K_L_M_N.

  • You could also replace <hr> with any other html tag to get a too slow result.
  • If I remove the underscores, everything is fast.
  • If I remove the beginning A-text, everything is fast.
  • If I remove the tag <hr> everything is fast.
  • If I add an empty line between A and <hr> everything is fast.

Sometimes PegDownProcessor.markdownToHtml(...) does nothing

I have this simple utility class with ThreadLocal static field:

public class MarkDownProcessor {
    private static final ThreadLocal<PegDownProcessor> PROCESSOR = 
        new ThreadLocal<PegDownProcessor>() {
            protected PegDownProcessor initialValue() {
                return new PegDownProcessor(Extensions.WIKILINKS + Extensions.AUTOLINKS);
            }
        };

    public static PegDownProcessor get() {
        return PROCESSOR.get();
    }
}

When I want to render markdown text to page, I can use this:

MarkDownProcessor.get().markdownToHtml(....);

But from time to time first call to markdownToHtml() renders same output as I passed into. Next call is OK. Maybe, it is a timing stuff. Can I use ThreadLocal for managing instances of PegDownProcessor or it is a bug?

Parser can't be subclassed outside of org.pegdown package

(This has been discussed in #28, but the solution from commit 07dda00 is incomplete.)

Subclassing Parser does only work if the subclass resides in the same package as Parser, that is, org.pegdown. The MyParser subclass introduced in commit 07dda00 is inside that package. Relocating it to any other package results in an IllegalAccessError.

Bug with TABLES Extension

PegDownProcessor with enabled extension TABLES crashes with org.parboiled.errors.ParserRuntimeException for text:
"$c_3 \cdots k_3 + c_4 \cdots k_4 + c_5 \cdots k_5 = s |c_3 \cdots k_3 --- c_4 \cdots k_4| + |c_4 \cdots k_4 โ€“ c_5 \cdots k_5|$" (quotes added for clarity). PegDownProcessor version is 1.1.0.

Extremely slow parsing for certain pathological input

This appears to trigger exponential parsing time:

Blaa

**SELECT @default_late_fees =
     CASE @default_days_out % @default_product_price_days_out
               <br>WHEN 0 <br>THEN (@default_days_out / @default_product_price_days_out) * @default_amount 
               <br>ELSE (FLOOR(@default_days_out / @default_product_price_days_out) + 1) * @default_amount 
          <br> END**

Thanks,
<br>S

Doesn't support CSS header

Maruku supports CSS header declarations like this:

CSS: style.css

# Normal Markdown starts here

Etc. Etc.

Which will insert the appropriate <link /> tag into the rendered HTML.

This is super handy and would love to see it in pegdown.

HTML tags with attributes whose names contain underscores are not recognized as tags

Whenever an attribute name of an HTML tag contains underscores, the tag is not recognized as a tag. Instead, the characters are escaped.

For example, given input:

Some text

<div attr_with_underscore="the value">
then a div
</div>

Then some other text

We expect the block-level tag to be recognized and left as it is:

<p>Some text</p>

<div attr_with_underscore="the value">
then a div
</div>

<p>Then some other text</p>

But, instead, the opening tag gets escaped:

<p>Some text</p>

<p>&lt;div attr_with_underscore=&ldquo;the value&rdquo;&gt;
then a div
</div></p>

<p>Then some other text</p>

Regression on code blocks

Hi Matthias,

I have a regression in specs2 with the latest 1.0.0.

A code block like this:

  • this is an item

     // showing some code here
     val x = y + 1
    
  • this is another item

used to be rendered with just one

 tag for the code block.

Now I have several

 tags for each line of the block. For example, in my user guide, I used to have:

  • using logical operators

    def beBetween(i: Int, j: Int) = be_>=(i) and be_<=(j)
    

    // create a Seq Matcher from a Matcher
    def allBeGreaterThan2: Matcher[Seq[Int]] = be_>=(2).forall // fail after the first failure
    def allBeGreaterThan3: Matcher[Seq[Int]] = be_>=(2).foreach // like forall but execute all matchers and collect the results
    def haveOneGreaterThan2: Matcher[Seq[Int]] = be_>=(2).atLeastOnce

    Now I have:

    • using logical operators

      def beBetween(i: Int, j: Int) = be_>=(i) and be_<=(j)
      

      // create a Seq Matcher from a Matcher

      def allBeGreaterThan2: Matcher[Seq[Int]]   = be_>=(2).forall     // fail after the first failure
      
  • Multi-Markdown parser option

    Can I suggest having the PegDown parser as a Multi-Markdown alternative to org.fusesource.scalamd.

    PegDown seems to run faster than scalamd but, more critically for me, provides multi-markdown extensions such as tables and definition lists as well as smart quotes, em-dashes, etc.

    I have successfully added it to a local copy with the following Filter:

    import org.fusesource.scalate.{TemplateEngineAddOn, RenderContext, TemplateEngine}
    import org.fusesource.scalate.filter.Filter
    import org.pegdown.{Extensions, PegDownProcessor}
    
    object MultiMarkdownFilter extends Filter with TemplateEngineAddOn {
    
      private val pegDownProcessor = new PegDownProcessor(
        Extensions.ABBREVIATIONS |
          Extensions.AUTOLINKS |
          Extensions.DEFINITIONS |
          Extensions.FENCED_CODE_BLOCKS |
          Extensions.QUOTES |
          Extensions.SMARTS |
          Extensions.TABLES |
          Extensions.WIKILINKS
      )
    
      def filter(context: RenderContext, content: String) = {
        synchronized {
          // This code block is synchronized as the PegDownProcessor is not thread safe.
          pegDownProcessor.markdownToHtml(content).stripLineEnd
        }
      }
    
      /**
       * Add the markdown filter to the template engine.
       */
      def apply(te: TemplateEngine) = {
        te.filters += "multimarkdown" -> MultiMarkdownFilter
        te.pipelines += "mmd" -> List(MultiMarkdownFilter)
        te.pipelines += "multimarkdown" -> List(MultiMarkdownFilter)
      }
    }
    
    

    and a dependency on: "org.pegdown" % "pegdown" % "1.1.0".

    Add support for custom extensions

    I've just started using pegdown and was hoping to have some way of subclassing the parser used to add my own extensions on top of the provided markdown however it seems all the methods to return/construct a parser instance are private.

    Incorrect links in the README

    Just a small, not-important issue about the README.markdown:

    Some links in the "Introduction"-section are wrong:

    Typo in line "See http://sirthias.github.com/pegdown/api for the pegdown API documation."

    pathologically slow parsing of HTML tables

    the HTML for this little table:

    Your action Partner's action Your jail time Partner's jail time
    silent silent 1 1
    silent confess 5 0
    confess silent 0 5

    takes Pegdown 0.8.5.4 30 seconds to process on my Mac.

    I'm invoking pegdown like this:
    new PegDownProcessor(Extensions.SMARTYPANTS | Extensions.AUTOLINKS)
    .markdownToHtml(str)

    Tests fail because of case sensitivity in file names

    Tests fail because of case sensitivity in file names. Maybe no-one tried it on a case sensitive OS before? It's easy to fix if you just merge all the files in test-cases/PhpMarkdown and test-cases/phpmarkdown.

    WikiLinkNode not parsed

    This is the sample implementation:

    return new PegDownProcessor().markdownToHtml("This is an [[internal]] link", new CustomLinkRenderer());

    This is the custom LinkRenderer:

    public class CustomLinkRenderer extends LinkRenderer {
    
        @Override
        public Rendering render(WikiLinkNode arg0) {
            System.out.println("Found a WikiLinkNode!");
            return new Rendering("http://test.com/", arg0.getText());
        }
    
    }

    And nothing gets printed to the standard output. I've tried to debug this, and it never parses [[internal]] as a WikiLinkNode.

    Selective "nofollow" handling for internal links

    It would be awesome if you can add "nofollow" attribute based on some regex.

    What if 50% of the links posted on your site are internal links? A la StackOverFlow... With the current config, either all links get nofollow or none do.

    Is there a way to customize this behaviour so that nofollow is only added based on a regex that matches your site or a custom value?

    Why is everything wrapped in pre/code???

    If I pass the default pegdown processor the text:

    start \n

    This is some text \n
    And this is some more... \n
    

    it gives me back:

    <h1>start</h1>
    <pre><code>This is some text
    And this is some more...
    </code></pre>

    Why is it wrapping the text in pre and code? How can I make it stop??

    support <div mardown=1> ....?

    I did my best to fork and try to get this working but I got really lost in the peg. I spent quit a bit of time wrapping my head around the code. I got as far as understanding that we want to do something similar to how blockquotes work. but the push/pop combined with the location and how nodeSequence got me really wrapped into knots.

    Any chance this is an easy fix or change for you? I will be watching the diff closely if so and hoepfully it will help me see the error of my ways

    Expected space not produced after </strong> or </em>

    These two lines of markdown:

    __ strong words__ weak words

    emphasized words regular words

    are rendered like this:

    <p><strong>strong words</strong>weak words</p><p><em>emphasized words</em>regular words</p>
    

    I am expecting spaces before the word "weak" and the word: "regular". Without the spaces, the strong/emphasized text is not separated from the regular text.

    Issues with code blocks in sublists

    I am having a problem with code blocks which are embedded inside of a list within a list. when the code block is made, it gets aligned with the overarching list instead of the inner list. I copy and paste the code into a GitHub Flavored Parser, and it works fine. here is the code:


    Fenced code blocks inside ordered and unordered lists

    1. This is a numbered list.

    2. I'm going to include a fenced code block as part of this bullet:

      Code
      More Code
      
    3. We can put fenced code blocks inside nested bullets, too.

      1. Like this:

        printf("Hello, World!");
        
      2. The key is to indent your fenced block by (4 * bullet_indent_level) spaces.

      3. Also need to put a separating newline above and below the fenced block.


    the error occurs at the code block under the Like this item. When parsed in pegdown, the code gets aligned with the 3 instead of the 1. also, the code breaks the current list.
    here is the html pegdown produces.


    Fenced code blocks inside ordered and unordered lists

    1. This is a numbered list.
    2. I'm going to include a fenced code block as part of this bullet:

      Code More Code

    3. We can put fenced code blocks inside nested bullets, too.

      1. Like this:
      ```
      printf("Hello, World!");
      ```
      
      1. The key is to indent your fenced block by (4 * bullet_indent_level) spaces.
      2. Also need to put a separating newline above and below the fenced block.

    the test code was retrieved from here
    thanks to clintel
    my first bug report, so sorry if I messed something up.

    Exception caused by Partial Table input

    Here's a simple example of input that can cause an exception when Tables are enabled:

    | H1 | h2|
    |--
    

    Also:

    | H1 | h2|
    |--|
    

    But this works:

    | H1 | h2|
    |--|--
    

    The exact error message is:

    java.lang.IndexOutOfBoundsException: index (1) must be less than size (1)
        at org.parboiled.common.Preconditions.checkElementIndex(Preconditions.java:274)
        at org.parboiled.common.Preconditions.checkElementIndex(Preconditions.java:254)
        at org.parboiled.common.ImmutableList$SingleElementList.get(ImmutableList.java:61)
        at org.pegdown.ToHtmlSerializer.visit(ToHtmlSerializer.java:234)
        at org.pegdown.ast.TableCellNode.accept(TableCellNode.java:35)
        at org.pegdown.ToHtmlSerializer.visitChildren(ToHtmlSerializer.java:322)
        at org.pegdown.ToHtmlSerializer.printIndentedTag(ToHtmlSerializer.java:340)
        at org.pegdown.ToHtmlSerializer.visit(ToHtmlSerializer.java:278)
        at org.pegdown.ast.TableRowNode.accept(TableRowNode.java:25)
        at org.pegdown.ToHtmlSerializer.visitChildren(ToHtmlSerializer.java:322)
        at org.pegdown.ToHtmlSerializer.printIndentedTag(ToHtmlSerializer.java:340)
        at org.pegdown.ToHtmlSerializer.visit(ToHtmlSerializer.java:266)
        at org.pegdown.ast.TableHeaderNode.accept(TableHeaderNode.java:25)
        at org.pegdown.ToHtmlSerializer.visitChildren(ToHtmlSerializer.java:322)
        at org.pegdown.ToHtmlSerializer.printIndentedTag(ToHtmlSerializer.java:340)
        at org.pegdown.ToHtmlSerializer.visit(ToHtmlSerializer.java:272)
        at org.pegdown.ast.TableNode.accept(TableNode.java:43)
        at org.pegdown.ToHtmlSerializer.visitChildren(ToHtmlSerializer.java:322)
        at org.pegdown.ToHtmlSerializer.visit(ToHtmlSerializer.java:66)
        at org.pegdown.ast.RootNode.accept(RootNode.java:51)
        at org.pegdown.ToHtmlSerializer.toHtml(ToHtmlSerializer.java:47)
        at org.pegdown.PegDownProcessor.markdownToHtml(PegDownProcessor.java:100)
        at org.pegdown.PegDownProcessor.markdownToHtml(PegDownProcessor.java:88)
        at org.pegdown.PegDownProcessor.markdownToHtml(PegDownProcessor.java:67)
        ...
    

    Links with nofollow

    Hi,

    Is there any way to get the links with the rel="nofollow" property? I think it would be useful

    Thanks for this awesome lib!

    Github Flavored Markdown Fenced Code Blocks

    It would be exceptionally great if the plugin supported Github Flavored Markdown's Fenced Code Blocks as well as the PHP Markdown Extra's approach.

    Github Flavored Markdown allows:

    ```scala
    class Example(name: String) {
      val field: Option[Int] = None
    }
    ```
    

    To render as:

    class Example(name: String) {
      val field: Option[Int] = None
    }

    It would be awesome if pegdown could treat blocks like this the same as:

    ~~~
    class Example(name: String) {
      val field: Option[Int] = None
    }
    ~~~
    

    and render as:

    class Example(name: String) {
      val field: Option[Int] = None
    }
    

    Syntax highlighting is a bigger deal and IMHO better delegated to SyntaxHighlighter on the client-side.

    Pegdown is great and thank you for building it :)

    Missing emphasis when paragraph has multiple lines

    emphasis does not seem to work when a paragraph is split across multiple lines...

    *A multi line paragraph broken
    with some line feeds onto several
    lines.*
    

    should produce

    <p><em>A multi line paragraph broken
    with some line feeds onto several
    lines.</em></p>
    

    actually produces

    <p>*A multi line paragraph broken
    with some line feeds onto several
    lines.*</p>
    

    Make it easier to extend ToHtmlSerializer

    Similar to #21 - toHtmlSerialzer is difficult to subclass and tweak behaviour.

    I would like to modify the link URLs before they are written (in my case I want to resolve relative image URLs)

    I can do this by overriding toHtmlSerializer but I have to override all of the link methods, some are complicated and I end up having to repeat the base class code (public void visit(final RefLinkNode node) in particular).

    Maybe some of the code in this class could be broken down with more overridable template method hooks so subclasses can change the functionality more easily?

    public void visit(ExpLinkNode node) {
        if (node.getImage()) {
            printer.print("<img src=\"").printEncoded(modifyUrl(node.getUrl()), this).print("\"  alt=\"").startEncoding(this);
            ...
    
    String modifyUrl(String url) {
        // override to modify the url
        return url;
    }
    

    Also some variables like printer as private which make overriding and tweaking the behaviour difficult.

    Unable to run on Google AppEngine

    This component cannot be used on GAE due to reflection restrictions (http://code.google.com/appengine/docs/java/runtime.html - see chapter Reflection).

    Stack trace is below:
    Caused by: java.lang.SecurityException: java.lang.IllegalAccessException: Reflection is not allowed on protected final java.lang.Class java.lang.ClassLoader.findLoadedClass(java.lang.String)
    at com.google.appengine.runtime.Request.process-0cd4e3037a565acb(Request.java)
    at java.lang.reflect.Method.setAccessible(Method.java:134)
    at org.parboiled.transform.AsmUtils.findLoadedClass(AsmUtils.java:173)

    Problems on appengine

    when trying to run it on appengine, I get stacktrace below.

    Did I do some stupid mistake, or did I hit some hard limits / restricitons for appengine ? And if so, are there any workarounds ?

    java.lang.NoClassDefFoundError: org/objectweb/asm/ClassVisitor at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:169) at com.google.appengine.tools.development.agent.runtime.RuntimeHelper.checkRestricted(RuntimeHelper.java:63) at com.google.appengine.tools.development.agent.runtime.Runtime.checkRestricted(Runtime.java:63) at org.parboiled.Parboiled.createParser(Parboiled.java:54) at org.pegdown.PegDownProcessor.(PegDownProcessor.java:48) at org.pegdown.PegDownProcessor.(PegDownProcessor.java:39) at unpaperfy.controller.MdController.run(MdController.java:118) at org.slim3.controller.Controller.runBare(Controller.java:111) at org.slim3.controller.FrontController.processController(FrontController.java:491) at org.slim3.controller.FrontController.doFilter(FrontController.java:277) at org.slim3.controller.FrontController.doFilter(FrontController.java:229) at org.slim3.controller.FrontController.doFilter(FrontController.java:199) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:78) at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:327) at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:126) at org.slim3.controller.HotRequestDispatcherWrapper.forward(HotRequestDispatcherWrapper.java:67) at org.slim3.controller.FrontController.doForward(FrontController.java:638) at org.slim3.controller.FrontController.doFilter(FrontController.java:235) at org.slim3.controller.FrontController.doFilter(FrontController.java:199) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at org.slim3.datastore.DatastoreFilter.doFilter(DatastoreFilter.java:55) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at org.slim3.controller.HotReloadingFilter.doHotReloading(HotReloadingFilter.java:223) at org.slim3.controller.HotReloadingFilter.doFilter(HotReloadingFilter.java:187) at org.slim3.controller.HotReloadingFilter.doFilter(HotReloadingFilter.java:157) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:35) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:60) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:78) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:369) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at org.mortbay.jetty.Server.handle(Server.java:326) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409) at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582) Caused by: java.lang.ClassNotFoundException: org.objectweb.asm.ClassVisitor at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:176) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) ... 62 more

    Recommend Projects

    • React photo React

      A declarative, efficient, and flexible JavaScript library for building user interfaces.

    • Vue.js photo Vue.js

      ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

    • Typescript photo Typescript

      TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    • TensorFlow photo TensorFlow

      An Open Source Machine Learning Framework for Everyone

    • Django photo Django

      The Web framework for perfectionists with deadlines.

    • D3 photo D3

      Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

    Recommend Topics

    • javascript

      JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

    • web

      Some thing interesting about web. New door for the world.

    • server

      A server is a program made to process requests and deliver data to clients.

    • Machine learning

      Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

    • Game

      Some thing interesting about game, make everyone happy.

    Recommend Org

    • Facebook photo Facebook

      We are working to build community through open source technology. NB: members must have two-factor auth.

    • Microsoft photo Microsoft

      Open source projects and samples from Microsoft.

    • Google photo Google

      Google โค๏ธ Open Source for everyone.

    • D3 photo D3

      Data-Driven Documents codes.