GithubHelp home page GithubHelp logo

showdownjs / showdown Goto Github PK

View Code? Open in Web Editor NEW
13.9K 198.0 1.6K 7.78 MB

A bidirectional Markdown to HTML to Markdown converter written in Javascript

Home Page: http://www.showdownjs.com/

License: MIT License

JavaScript 73.45% HTML 26.55%
showdown javascript markdown markdown-parser markdown-flavors gfm html converter html-converter

showdown's Introduction

Showdown

Build Status: Linux Build Status: Windows Browserstack Tests npm version Bower version Donate


Showdown is a JavaScript Markdown to HTML converter, based on the original works by John Gruber. Showdown can be used client side (in the browser) or server side (with Node.js).

Live DEMO

Check out a live demo here: http://demo.showdownjs.com/

As you know, ShowdownJS is a free library and it will remain free forever. However, maintaining and improving the library costs time and money.

If you like our work and find our library useful, please donate through PayPal! Your contribution will be greatly appreciated and help me continue to develop this awesome library.

License

ShowdownJS v 2.0 is released under the MIT license. Previous versions are released under BSD.

Who uses Showdown (or a fork)

Installation

Download tarball

You can download the latest release tarball directly from releases.

Bower

bower install showdown

npm (server-side)

npm install showdown

NuGet package

PM> Install-Package showdownjs

The NuGet Packages can be found here.

CDN

You can also use one of several CDNs available:

  • jsDelivr

      https://cdn.jsdelivr.net/npm/showdown@<version tag>/dist/showdown.min.js
    
  • cdnjs

      https://cdnjs.cloudflare.com/ajax/libs/showdown/<version tag>/showdown.min.js
    
  • unpkg

      https://unpkg.com/showdown/dist/showdown.min.js
    

Note: replace <version tag> with an actual full length version you're interested in e.g. 1.9.0

Browser Compatibility

Showdown has been tested successfully with:

  • Firefox 1.5 and 2.0
  • Chrome 12.0
  • Internet Explorer 6 and 7
  • Safari 2.0.4
  • Opera 8.54 and 9.10
  • Netscape 8.1.2
  • Konqueror 3.5.4

In theory, Showdown will work in any browser that supports ECMA 262 3rd Edition (JavaScript 1.5). The converter itself might even work in things that aren't web browsers, like Acrobat. No promises.

Node compatibility

Showdown is intended to work on any supported Node.js version (see the Node.js releases schedule. The code may work with previous versions of Node.js, but no accomidations are made to ensure it does.

Legacy version

If you're looking for showdown v<1.0.0, you can find it in the legacy branch.

Changelog

You can check the full changelog

Extended documentation

Check our wiki pages for examples and a more in-depth documentation.

Quick Example

Node

var showdown  = require('showdown'),
    converter = new showdown.Converter(),
    text      = '# hello, markdown!',
    html      = converter.makeHtml(text);

Browser

var converter = new showdown.Converter(),
    text      = '# hello, markdown!',
    html      = converter.makeHtml(text);

Output

Both examples should output...

    <h1 id="hellomarkdown">hello, markdown!</h1>

Options

You can change some of showdown's default behavior through options.

Setting options

Options can be set:

Globally

Setting a "global" option affects all instances of showdown

showdown.setOption('optionKey', 'value');

Locally

Setting a "local" option only affects the specified Converter object. Local options can be set:

  • through the constructor

    var converter = new showdown.Converter({optionKey: 'value'});
  • through the setOption() method

    var converter = new showdown.Converter();
    converter.setOption('optionKey', 'value');

Getting an option

Showdown provides 2 methods (both local and global) to retrieve previous set options.

getOption()

// Global
var myOption = showdown.getOption('optionKey');

//Local
var myOption = converter.getOption('optionKey');

getOptions()

// Global
var showdownGlobalOptions = showdown.getOptions();

//Local
var thisConverterSpecificOptions = converter.getOptions();

Retrieve the default options

You can get showdown's default options with:

var defaultOptions = showdown.getDefaultOptions();

Valid Options

  • omitExtraWLInCodeBlocks: (boolean) [default false] Omit the trailing newline in a code block. Ex:

    This:

    <code><pre>var foo = 'bar';
    </pre></code>

    Becomes this:

    <code><pre>var foo = 'bar';</pre></code>
  • noHeaderId: (boolean) [default false] Disable the automatic generation of header ids. Setting to true overrides prefixHeaderId

  • customizedHeaderId: (boolean) [default false] Use text in curly braces as header id. (since v1.7.0) Example:

    ## Sample header {real-id}     will use real-id as id
    
  • ghCompatibleHeaderId: (boolean) [default false] Generate header ids compatible with github style (spaces are replaced with dashes and a bunch of non alphanumeric chars are removed) (since v1.5.5)

  • prefixHeaderId: (string/boolean) [default false] Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic 'section' prefix.

  • rawPrefixHeaderId: (boolean) [default false] Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix). Has no effect if prefixHeaderId is set to false. (since v 1.7.3)

  • rawHeaderId: (boolean) [default false] Remove only spaces, ' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids (since v1.7.3)

  • headerLevelStart: (integer) [default 1] Set the header starting level. For instance, setting this to 3 means that

    # foo

    will be parsed as

    <h3>foo</h3>
  • parseImgDimensions: (boolean) [default false] Enable support for setting image dimensions from within markdown syntax. Examples:

    ![foo](foo.jpg =100x80)     simple, assumes units are in px
    ![bar](bar.jpg =100x*)      sets the height to "auto"
    ![baz](baz.jpg =80%x5em)  Image with width of 80% and height of 5em
    
  • simplifiedAutoLink: (boolean) [default false] Turning this option on will enable automatic linking to urls. This means that:

    some text www.google.com

    will be parsed as

    <p>some text <a href="www.google.com">www.google.com</a>
  • excludeTrailingPunctuationFromURLs: (boolean) [default false] This option excludes trailing punctuation from autolinking urls. Punctuation excluded: . ! ? ( ). Only applies if simplifiedAutoLink option is set to true.

  • literalMidWordUnderscores: (boolean) [default false] Turning this on will stop showdown from interpreting underscores in the middle of words as <em> and <strong> and instead treat them as literal underscores.

    Example:

    some text with__underscores__in middle

    will be parsed as

    <p>some text with__underscores__in middle</p>
  • literalMidWordAsterisks: (boolean) [default false] Turning this on will stop showdown from interpreting asterisks in the middle of words as <em> and <strong> and instead treat them as literal asterisks.

  • strikethrough: (boolean) [default false] Enable support for strikethrough syntax. ~~strikethrough~~ as <del>strikethrough</del>

  • tables: (boolean) [default false] Enable support for tables syntax. Example:

    | h1    |    h2   |      h3 |
    |:------|:-------:|--------:|
    | 100   | [a][1]  | ![b][2] |
    | *foo* | **bar** | ~~baz~~ |

    See the wiki for more info

  • tablesHeaderId: (boolean) [default false] If enabled adds an id property to table headers tags.

  • ghCodeBlocks: (boolean) [default true] Enable support for GFM code block style.

  • tasklists: (boolean) [default false] Enable support for GFM tasklists. Example:

     - [x] This task is done
     - [ ] This is still pending
  • smoothLivePreview: (boolean) [default false] Prevents weird effects in live previews due to incomplete input

  • smartIndentationFix: (boolean) [default false] Tries to smartly fix indentation problems related to es6 template strings in the midst of indented code.

  • disableForced4SpacesIndentedSublists: (boolean) [default false] Disables the requirement of indenting sublists by 4 spaces for them to be nested, effectively reverting to the old behavior where 2 or 3 spaces were enough. (since v1.5.0)

  • simpleLineBreaks: (boolean) [default false] Parses line breaks as <br>, without needing 2 spaces at the end of the line (since v1.5.1)

    a line  
    wrapped in two

    turns into:

    <p>a line<br>
    wrapped in two</p>
  • requireSpaceBeforeHeadingText: (boolean) [default false] Makes adding a space between # and the header text mandatory (since v1.5.3)

  • ghMentions: (boolean) [default false] Enables github @mentions, which link to the username mentioned (since v1.6.0)

  • ghMentionsLink: (string) [default https://github.com/{u}] Changes the link generated by @mentions. Showdown will replace {u} with the username. Only applies if ghMentions option is enabled. Example: @tivie with ghMentionsOption set to //mysite.com/{u}/profile will result in <a href="//mysite.com/tivie/profile">@tivie</a>

  • encodeEmails: (boolean) [default true] Enable e-mail addresses encoding through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities. (since v1.6.1)

    NOTE: Prior to version 1.6.1, emails would always be obfuscated through dec and hex encoding.

  • openLinksInNewWindow: (boolean) [default false] Open all links in new windows (by adding the attribute target="_blank" to <a> tags) (since v1.7.0)

  • backslashEscapesHTMLTags: (boolean) [default false] Support for HTML Tag escaping. ex: \<div>foo\</div> (since v1.7.2)

  • emoji: (boolean) [default false] Enable emoji support. Ex: this is a :smile: emoji For more info on available emojis, see https://github.com/showdownjs/showdown/wiki/Emojis (since v.1.8.0)

  • underline: (boolean) [default false] EXPERIMENTAL FEATURE Enable support for underline. Syntax is double or triple underscores ex: __underlined word__. With this option enabled, underscores are no longer parses into <em> and <strong>.

  • ellipsis: (boolean) [default true] Replaces three dots with the ellipsis unicode character.

  • completeHTMLDocument: (boolean) [default false] Outputs a complete html document, including <html>, <head> and <body> tags' instead of an HTML fragment. (since v.1.8.5)

  • metadata: (boolean) [default false] Enable support for document metadata (defined at the top of the document between ««« and »»» or between --- and ---). (since v.1.8.5)

    var conv = new showdown.Converter({metadata: true});
    var html = conv.makeHtml(someMd);
    var metadata = conv.getMetadata(); // returns an object with the document metadata
  • splitAdjacentBlockquotes: (boolean) [default false] Split adjacent blockquote blocks.(since v.1.8.6)

  • moreStyling: (boolean) [default false] Adds some useful classes for css styling. (since v2.0.1)

    • Tasklists: Adds the class task-list-item-complete to completed tasks items in GFM tasklists.

NOTE: Please note that until version 1.6.0, all of these options are DISABLED by default in the cli tool.

Flavors

You can also use flavors or presets to set the correct options automatically, so that showdown behaves like popular markdown flavors.

Currently, the following flavors are available:

  • original - original markdown flavor as in John Gruber's spec
  • vanilla - showdown base flavor (as from v1.3.1)
  • github - GFM (GitHub Flavored Markdown)

Global

showdown.setFlavor('github');

Instance

converter.setFlavor('github');

CLI Tool

Showdown also comes bundled with a Command Line Interface tool. You can check the CLI wiki page for more info

Integration with AngularJS

ShowdownJS project also provides seamlessly integration with AngularJS via a "plugin". Please visit https://github.com/showdownjs/ngShowdown for more information.

Integration with TypeScript

If you're using TypeScript you maybe want to use the types from DefinitelyTyped

Integration with SystemJS/JSPM

Integration with SystemJS can be obtained via the third party "system-md" plugin.

Integration with VueJS

To use ShowdownJS as a Vue component quickly, you can check vue-showdown.

XSS vulnerability

Showdown doesn't sanitize the input. This is by design since markdown relies on it to allow certain features to be correctly parsed into HTML. This, however, means XSS injection is quite possible.

Please refer to the wiki article Markdown's XSS Vulnerability (and how to mitigate it) for more information.

Extensions

Showdown allows additional functionality to be loaded via extensions. (you can find a list of known showdown extensions here) You can also find a boilerplate, to create your own extensions in this repository

Client-side Extension Usage

<script src="showdown.js" />
<script src="twitter-extension.js" />

var converter = new showdown.Converter({ extensions: ['twitter'] });

Server-side Extension Usage

var showdown    = require('showdown'),
    myExtension = require('myExtension'),
    converter = new showdown.Converter({ extensions: ['myExtension'] });

Building

Building your clone of the repository is easy.

Prerequesites: Node.js v12, npm and npx must be installed.

  1. run npm install.

  2. run npx grunt build (see Gruntfile.js). This command:

    1. Cleans the repo.
    2. Checks code quality (JSHint and ESLint).
    3. Runs tests.
    4. Creates the distributable and minified files in the dist folder.

Tests

A suite of tests is available which require Node.js. Once Node is installed, run the following command from the project root to install the dependencies:

npm install

Once installed the tests can be run from the project root using:

npm test

New test cases can easily be added. Create a markdown file (ending in .md) which contains the markdown to test. Create a .html file of the exact same name. It will automatically be tested when the tests are executed with mocha.

Contributing

If you wish to contribute please read the following quick guide.

Want a Feature?

You can request a new feature by submitting an issue. If you would like to implement a new feature feel free to issue a Pull Request.

Pull requests (PRs)

PRs are awesome. However, before you submit your pull request consider the following guidelines:

  • Search GitHub for an open or closed Pull Request that relates to your submission. You don't want to duplicate effort.

  • When issuing PRs that change code, make your changes in a new git branch based on develop:

    git checkout -b my-fix-branch develop
  • Run the full test suite before submitting and make sure all tests pass (obviously =P).

  • Try to follow our coding style rules. Breaking them prevents the PR to pass the tests.

  • Refrain from fixing multiple issues in the same pull request. It's preferable to open multiple small PRs instead of one hard to review big one.

  • If the PR introduces a new feature or fixes an issue, please add the appropriate test case.

  • We use conventional commit notes to generate the changelog that follow the conventional changelog spec. It's extremely helpful if your commit messages adhere to these Commit Guidelines.

  • Don't forget to add your name to the CREDITS.md file. We like to give credit were it's due.

  • If we suggest changes then:

    • Make the required updates.
    • Re-run the test suite to ensure tests are still passing.
    • Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
    git rebase develop -i
    git push origin my-fix-branch -f
  • After your pull request is merged, you can safely delete your branch.

If you have time to contribute to this project, we feel obliged that you get credit for it. These rules enable us to review your PR faster and will give you appropriate credit in your GitHub profile. We thank you in advance for your contribution!

Joining the team

We're looking for members to help maintaining Showdown. Please see this issue to express interest or comment on this note.

Credits

Full credit list at https://github.com/showdownjs/showdown/blob/master/CREDITS.md

Showdown is powered by:
webstorm

showdown's People

Contributors

bandantonio avatar butchmarshall avatar cybercase avatar danielruf avatar dchester avatar dennisss avatar dependabot[bot] avatar erisds avatar greenkeeper[bot] avatar henrahmagix avatar jasonmit avatar kkaefer avatar langpavel avatar lovethesource avatar martinbeentjes avatar meteorlxy avatar pdeschen avatar remy avatar rheber avatar schmijos avatar stevemao avatar syntaxrules avatar teleological avatar tivie avatar tpxp avatar tsndr avatar tstone avatar twitwi avatar vladimirv99 avatar voltanfr 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  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

showdown's Issues

Header level start

Hi,
I have a following usecase:

H1 Package.name
H2 SubPackage.name
(showdown.makeHtml(SubPackage.description))

So it would be great if I could call showdown.makeHtml(SubPackage.description,3)
so that in case there is following code in SubPackage.description

\#Given
\#When
\#Then

I could get output like this:
H1 Package.name
H2 SubPackage.name
H3 Given
H3 When
H3 Then

XSS vulnerability

It seems that link and image titles can be abused easily. Here's and example:

[Poolparty!](http://www.missionmission.org/wp-content/uploads/2013/08/pool-party-560x328.jpg" onmouseover=alert(document.cookie) id=test)

This is prevented on titles but not in urls. Fix is pretty easy:

url = escapeCharacters(url,"*_");
url = url.replace(/"/g,"&quot;");

Architecture & Process Changes

Showdown is evolving. I'm interested in exploring options for making larger code architecture and project process changes here.

I'd love to hear from @pdeschen, @tstone and the Showdown community at large regarding the following ideas and any others.

Regarding project management, I'm wondering whether it's time to move things to a Showdown github "organization". I feel a number of the recent contributors ought to be given commit rights and the newly added extension mechanism opens the door for Showdown, um..., extensions and my sense is that it would likely be good for those to be managed individually.

Regarding recording/maintaining the historical record, I feel it's important to be sure we continue to recognize Showdown's roots and John Fraser as the original author. On the other hand, it feels like much of the original examples, the Perl code, etc. could be moved "out of the way". My suggestion here is to create a "legacy" branch (and tag?) which would make it easy to find that stuff, but just as easy to leave it behind and move forward unencumbered.

Thoughts?

Github style code blocks don't auto-escape HTML

<'s and >'s should be converted to &lt; and &gt;

Example:

```html
<div>HTML!</div>
\```

(The leading \ is there to get github to not close the codeblock on [backtick][backtick][backtick])

Underscores in words

As described in Github flavoured markdown, it makes no sense to italicise parts of a word.

Underscores in words usually refer to something like a variable or field name so it is particularly bad when these are parsed out and converted to italics.

Please can showdown be changed to use the github rules for this.

Thanks.

Can't upload your library to my repo?

I tried integrating your library to my project, but when I went on my repo to the javascript folder, the "showdown" folder is not clickable. Deploying also doesn't work since it seems to just be a blank unclickable folder. Is there some sort of licensing issue? I eventually got it to work by just copying the parts I needed (showdown/src/). Still curious though

Passing variable into Extension

I believe I have the need for variables to be passed into extensions. Please correct me if I am not thinking about the solution correctly.

My scenario is tagging a piece of content that will be excluded/included at compile time. I know that I could hide information via classes but I need the content not to be compiled in. This is a well known technique by technical writers for single sourcing documentation (for example in DocBook using attributes, eg revision, condition).

In my overly simple example, I want to only include the content when condition='a'. a is obviously the value that I want to hand in at compile time to base the exclusion on. So, in the code below, a is hardcoded but I would like to pass it in - suggestion below. At this stage, let's not worry about it being in html.

Extension

function(converter) {
        return [
            { type: 'output', filter: function(source){
                var regex = /<\w+\s+(condition)='a'.*?>(.*?)<\/.*?>/gmi;
                return source.replace(regex, "");
            }}
        ];
    };

Markdown

a<span condition='a'>tagging</span>

Compiled to HTML

<p>a</p>

Would I be thinking about it wrong to want options as a second parameter?

var options = { condition: 'a' };
var converter = new Showdown.converter({ extensions: [mine], options });

Extension: mine

function(converter, options) {
        return [
            { type: 'output', filter: function(source){
                console.log(options.condition);
                return source;
            }}
        ];
    };

Emphasis in a link

A _ in a link match for emphasis.

Try with link:
[https://github.com/an_emphasis_link]()

Dom elements and templates together can cause problems.

I'm having a small issue with showdown that is causing problems with my rendering.

{{#markdown}}
This is parsed.

<p>{{> test}}</p>

#This is not parsed.

<p>
{{> test}}
</p>

This is parsed.

{{/markdown}}

And the test template:

<template name="test">Testtext</template>

This is resulting in the part with '#' not being parsed. If I remove the newline between the

and {{> test}} it works fine.

This is the resulting html:

<p>This is parsed.</p>

<p>Testtext</p>

#This is not parsed.

<p>
Testtext
</p>

<p>This is parsed.</p>

I've ended up switching to metoer-markdown as it seems to handle this fine. I could just eliminate the newline but as my

and templates have way more attributes than this simple example I'd prefer not to for clean-ness. It if could be fixed it might save someone else some confusion in the future!

URLs are improperly escaped

Converting the following Markdown:

http://example.com/'onmouseover='alert(document.cookie)'/

yields the following HTML:

<p><a href='http://example.com/'onmouseover='alert(document.cookie)'/'>http://example.com/'onmouseover='alert(document.cookie)'/</a></p>

which in turn is parsed by the browser as:

<p><a href="http://example.com/" onmouseover="alert(document.cookie)" '="">http://example.com/'onmouseover='alert(document.cookie)'/</a></p>

The reason is that URLs are improperly escaped before being inserted into href attributes.

I discovered this by accident while writing a tutorial on XSS. It's a defect in the Showdown library that would allow for unintended script injection if Markdown weren't designed to allow inline HTML to begin with.

Ignore syntax inside <pre> totally

I found that some syntax are not ignored inside <pre> or code block (```). For example image embedding syntax. Also all extensions are not ignored. Is there a tag to ignore all syntax?

Latest grunt-mocha module requires grunt update.

When running npm install:

npm ERR! peerinvalid The package grunt does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants grunt@~0.4

package.json specifies: "grunt-mocha": "*" which is grabbing v0.4.7. We need to either set an older version of grunt-mocha that's compatible with grunt-0.3.17, or upgrade grunt to 0.4.

Nested block quotes

According to the Markdown syntax page ( http://daringfireball.net/projects/markdown/syntax ), markdown is supposed to support nested blockquotes. The example is given...

> This is the first level of quoting.
>
> > This is nested blockquote.
>
> Back to the first level.

What HTML should this produce? Based on the markdown and text in the example, I would assume the HTML output should be:

<blockquote>
  <p>This is the first level of quoting.</p>

  <blockquote>
    <p>This is nested blockquote.</p>
  </blockquote>

  <p>Back to the first level.</p>
</blockquote>

However showdown right now produces:

<blockquote>
  <p>This is the first level of quoting.</p>

  <blockquote>
    <p>This is nested blockquote.
    Back to the first level</p>
  </blockquote>
</blockquote>

Adding multiple titles/headers with the same content produces invalid markup.

Creating a title/header adds the content of the header to the header markup tag's id attribute.

For example:

# foobar
# foobar

produces:

<h1 id="foobar">foobar</h1>
<h1 id="foobar">foobar</h1>

If setting an id attribute is necessary for #hash linking, it should keep track of duplicates appending a unique identifier. e.g. foobar-1, foobar-2, etc or a timestamp foobar-1389214127156, foobar-1389214127157, etc.

If setting an id attribute is unnecessary, this functionality should be removed altogether.

Markdown Extra footnote support

I'm closing down my fork since I can't spare the time to develop this. Maybe you could keep the issue around to see if someone else picked it up...

Extensions Documentation

The documentation for building extensions seems to be pretty good. However, I've been unsuccessful at getting extensions to load.

A couple errors when following the documentation:

  1. TypeError: showdown is not a constructor. I've found that removing the () after "new Showdown"
new Showdown().converter({ extensions: 'twitter' });

... seems to help. However, I hit another hurdle.

  1. I keep getting a "TypeError: converter_options.extensions.forEach is not a function". Upon further inspection, the converter_options array is just an array of strings. There is no forEach function assigned to them.

I'm not really sure how to proceed and I haven't seen any working extension examples anywhere. Is there any way they could be included in the example?

Thanks!

Define an extension syntax

It should probably be capable of:

  • Categorizing the extension as either language extension or output modification
  • Give developers the option of a simple regex/replace syntax, regex/function syntax, or straight out callback function to do whatever you want
  • Extensions should be able dynamically loaded on either the client or server ,then a new converter instantiated with them
  • Allow multiple language modifications to be included in a single extension (ie. a github extension would include 40 or 50 modifications)

Suggestions for implementations can be discussed below:

Broken with Browserify

I attempted to use showdown with browserify and ran into a failure. The failure is due to Showdown trying to access the file system, based on the existence of require/etc.

My main question is.. why, why is it even doing this? If we look at the code in question..

//
// Automatic Extension Loading (node only):
//

if (typeof module !== 'undefind' && typeof exports !== 'undefined' && typeof require !== 'undefind') {
    var fs = require('fs');

    if (fs) {
        // Search extensions folder
        var extensions = fs.readdirSync((__dirname || '.')+'/extensions').filter(function(file){
            return ~file.indexOf('.js');
        }).map(function(file){
            return file.replace(/\.js$/, '');
        });
        // Load extensions into Showdown namespace
        Showdown.forEach(extensions, function(ext){
            var name = stdExtName(ext);
            Showdown.extensions[name] = require('./extensions/' + ext);
        });
    }
}

Why is fs even being used here? This seems like a complex solution for something that a simple index.js file would handle just fine. On top of that, if an index.js file was used then Browserify would work out of the box.

<style> tag is removed

Markdown.pl version 1.0.1 passes through my inline <style> tag unmodified. Showdown removes it.

(Seems like this repo isn't maintained actively anymore perhaps....)

Extension for Embedding YouTube

Has anyone written this already? The README has an example of this, but I don't see support for it. Wanted to check if it was available before writing my own.

Ajax response in extensions

I'm trying to develop a plugin which will send the key to server and get the text.
Looks like ajax implementation is not working in my custom plugin. Is there any way to do that?

replace : function(match, prefix, content, suffix) {
                $.ajax({
                      type: "GET",
                      url: 'data/data.json',
                      async: false,
                      success : function(data) {
                          return data.txt';
                      }
                  });
}

\Z not functional in Chrome 20

Showdown already works around JavaScript's missing \Z in some parts of the code, but not in _StripLinkDefinitions. This causes link definitions with the "Z" character to fail. See gist.

[link]: http://example.com/beforeZafter

The text "after" will be left floating at the end of the converted text.

no need for new, benchmarked refactor results

So I was messing with this for fun. Didnt like the code style, and had a theory that if I pulled out a bunch of large regexes and functions into variables outside of the functions there would be a bit of a performance boost. Well you can see the lackluster results here http://jsperf.com/showdown-basic-optimizations

I would suggest doing away with the constructor newing tho, there is no need for it. Just return the makeHtml function as seen in the ShowdownMod code block in the jsperf page.

Passing in an URL

Hi, I'm thinking about using Showdown in my next small project but I can't grasp it. Is there any way to pass in a URL (to a Markdown file) so it outputs the HTML?

Add additional block elements

The list of block elements in https://github.com/coreyti/showdown/blob/master/src/showdown.js#L328 is incomplete.

This is causing problems in rendering markdown as showdown adds additional <br /> to block elements that aren't on that list. We currently experience this issue in TryGhost/Ghost#2312 where an <audio> tag breaks because of showdown adding additional HTML line breaks inside the element.

@coreyti Not sure if this project is still active, but if you are up to merging a PR for this I'd be happy to send one.

a parse bug

markdown text:

* list

        + item

             - subitem

               The HTML has a superfluous newline before this
               paragraph.

             - subitem

               The HTML here is unchanged.

             - subitem

               The HTML is missing a newline after this
               list subitem.

correct markdown parse :

  • list

    + item
    
         - subitem
    
           The HTML has a superfluous newline before this
           paragraph.
    
         - subitem
    
           The HTML here is unchanged.
    
         - subitem
    
           The HTML is missing a newline after this
           list subitem.
    

the showdown parse :

list

+ item


 - subitem


   The HTML has a superfluous newline before this
   paragraph.


 - subitem


   The HTML here is unchanged.


 - subitem


   The HTML is missing a newline after this
   list subitem.

a table extension output bug

Try this markdown text,the output will be 3 tables:

 | table 1 | Col 2     |
 |======== |===========|
 | row1    | value     |
 | row2    | Value     |

 | table 2 | Col 2     |
 |======== |===========|
 | row1    | value     |
 | row2    | Value     |

how to fix:

edit table.js in line 58-60

      var i=0, lines = text.split('\n'), tbl = [], line, hs, rows, out = [];
      for (i; i<lines.length;i+=1) {

to:

      var i=0, lines = text.split('\n'),  line, hs, rows, out = [];
      for (i; i<lines.length;i+=1) {
      var tbl = [];

Incorrect parsing of underscore and asterisk

If you have text like this:

Hello.this\_is\_a\_variable
and.this.is.another_one

Showdown incorrectly parses it as:

Hello.this<em>is</em>a<em>variable
and.this.is.another</em>one

To fix it, replace lines 984-988:

text = text.replace(/(?![\])(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,
    "<strong>$2</strong>");

text = text.replace(/(?![\])(\*|_)(?=\S)([^\r]*?\S)\1/g,
    "<em>$2</em>");

I'm not a regex pro, but as far as I can tell adding the negative lookahead (?![\]) before the groups works fine. This tells the regex to skip those characters if they're escaped with the backslash '' character.

Thanks!

Safe output

Hi
I've noticed that Showdown doesn't escape the HTML tags.
With Python port of markdown it's possible to have safe output by passing the safe arg to markdown converter, and all the html tags will be removed or replaced by a word.

I guess it's better to just strip HTML tags and remove them completely.

npm module out of date

This is probably one of the more important issues to me. Anyone know who is managing the module in the npm system?

Output of anchor broken

In the example:

[This is a test](http://example.com) foo bar foo

The output is

<p><a href="http://example.com">This is a test</a>foo bar foo</p>

Notice there is no space after the closing </a> tag.

Tested on OSX 10.8 in Chome 27, Firefox 21, Opera 15

Parsing escaped html entities

Showdown has been awesome so far, I just have a small issue with escaped html. For example I encode all html entities before running showdown on the user input. Therefore text like
<http://google.com> // Looks like github is parsing the link with html entities
no longer works because the regexs are not checking for escaped entities.
I have tweaked the regex to look like this:

// autolinking  
text = text.replace(/(?:<|&lt;)((https?|ftp|dict):[^'">\s]+)(?:>|&gt;)/gi,"<a href=\"$1\">$1</a>");  
[ignore]  

Im sure this may affect other parts of the code but this is the only piece that I have changed so far.

Where could I find your documentation?

I would like to find out if the showdown can escape produced html.
Apparently here it does not do so.
Don't see the answer in comments of the script (sure, I could just miss it)

Use with wmd

I am trying to use your version of showdown with wmd, but because of the namespace differences and possibly other issues, the scripts are incompatible.

I am currently using a version of showdown that has

var Attacklab = Attacklab || {}
Attacklab.showdown = Attacklab.showdown || {}

Your version has

var Showdown = {};

Is it possible you can revert your modifications to appear same as original so that it is compatible with other scripts such as wmd?

Is this still in active development?

This is a very nice project. However, I am hesitant to use this because of the pending issues and PRs. Seems like this is not active anymore.

Is this project abandoned? If so, kindly tell me some alternative similar to this one please.

Publish in npm

Can you please publish this module in npm? npm makes it easy to install dependencies for JavaScript projects

发的萨芬

标题1

标题2

标题3

  • 列表1
    测试
  • 列表2
  • 列表3

我是斜体
测试文字里面,我是粗体,很简单
我是粗体

水平线


如果文字后面紧跟着水平线,看看是什么效果

bug - Automatic Extension Loading (node only)

I found misspelling.
please fix 'undefind' to 'undefined'.

showdown.js , line 120

//
// Automatic Extension Loading (node only):
//
if (typeof module !== 'undefind' && typeof exports !== 'undefined' && typeof require !== 'undefind') {
if (typeof module !== 'undefined' && typeof exports !== 'undefined' && typeof require !== 'undefined') {

Grunt lint task needs to be updated with Grunt upgrade.

The current Grunt lint test isn't identifying issues properly, and should probably just be substituted with grunt-contrib-jshint when Grunt is upgraded. This will identify a handfull of errors (below) that need to be cleaned up.

Running "jshint:src" (jshint) task
Linting src/showdown.js ...ERROR
[L120:C19] W122: Invalid typeof value 'undefind'
if (typeof module !== 'undefind' && typeof exports !== 'undefined' && typeof require !== 'undefind') {
[L120:C86] W122: Invalid typeof value 'undefind'
if (typeof module !== 'undefind' && typeof exports !== 'undefined' && typeof require !== 'undefind') {
[L272:C4] W099: Mixed spaces and tabs.
          [ \t]*
[L273:C4] W099: Mixed spaces and tabs.
          \n?        // maybe one newline
[L274:C4] W099: Mixed spaces and tabs.
          [ \t]*
[L276:C4] W099: Mixed spaces and tabs.
          [ \t]*
[L277:C4] W099: Mixed spaces and tabs.
          \n?        // maybe one newline
[L278:C4] W099: Mixed spaces and tabs.
          [ \t]*
[L280:C4] W099: Mixed spaces and tabs.
          (\n*)        // any lines skipped = $3 attacklab: lookbehind removed
[L281:C4] W099: Mixed spaces and tabs.
          ["(]
[L282:C4] W099: Mixed spaces and tabs.
          (.+?)        // title = $4
[L283:C4] W099: Mixed spaces and tabs.
          [")]
[L284:C4] W099: Mixed spaces and tabs.
          [ \t]*
[L287:C3] W099: Mixed spaces and tabs.
        /gm,
[L288:C3] W099: Mixed spaces and tabs.
        function(){...});
[L315:C2] W033: Missing semicolon.
}
[L440:C2] W033: Missing semicolon.
}
[L512:C2] W033: Missing semicolon.
}
[L531:C2] W033: Missing semicolon.
}
[L606:C5] W099: Mixed spaces and tabs.
    (               // wrap whole match in $1
[L616:C2] W033: Missing semicolon.
}
[L619:C12] W041: Use '===' to compare with 'undefined'.
  if (m7 == undefined) m7 = "";
[L622:C13] W099: Mixed spaces and tabs.
  var link_id   = m3.toLowerCase();
[L626:C13] W041: Use '===' to compare with ''.
  if (url == "") {
[L627:C21] W041: Use '===' to compare with ''.
    if (link_id == "") {
[L633:C29] W041: Use '!==' to compare with 'undefined'.
    if (g_urls[link_id] != undefined) {
[L635:C35] W041: Use '!==' to compare with 'undefined'.
      if (g_titles[link_id] != undefined) {
[L652:C15] W041: Use '!==' to compare with ''.
  if (title != "") {
[L661:C2] W033: Missing semicolon.
}
[L720:C2] W033: Missing semicolon.
}
[L725:C13] W099: Mixed spaces and tabs.
  var link_id   = m3.toLowerCase();
[L731:C13] W041: Use '===' to compare with ''.
  if (url == "") {
[L732:C21] W041: Use '===' to compare with ''.
    if (link_id == "") {
[L738:C29] W041: Use '!==' to compare with 'undefined'.
    if (g_urls[link_id] != undefined) {
[L740:C35] W041: Use '!==' to compare with 'undefined'.
      if (g_titles[link_id] != undefined) {
[L765:C2] W033: Missing semicolon.
}
[L812:C2] W033: Missing semicolon.
}
[L858:C53] W032: Unnecessary semicolon.
      list = list.replace(/\n{2,}/g,"\n\n\n");;
[L878:C22] W004: 'list' is already defined.
      var list = list.replace(/\n{2,}/g,"\n\n\n");;
[L878:C57] W032: Unnecessary semicolon.
      var list = list.replace(/\n{2,}/g,"\n\n\n");;
[L889:C2] W033: Missing semicolon.
}
[L960:C2] W033: Missing semicolon.
}
[L1041:C2] W033: Missing semicolon.
}
[L1046:C2] W033: Missing semicolon.
}
[L1053:C3] W099: Mixed spaces and tabs.
//   include literal backticks in the code span. So, this input:
[L1055:C4] W099: Mixed spaces and tabs.
//     Just type ``foo `bar` baz`` at the prompt.
[L1057:C3] W099: Mixed spaces and tabs.
//     Will translate to:
[L1059:C4] W099: Mixed spaces and tabs.
//     <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
[L1067:C4] W099: Mixed spaces and tabs.
//     ... type `` `bar` `` ...
[L1069:C3] W099: Mixed spaces and tabs.
//     Turns to:
>> Too many errors. (73% scanned).

I'm working on getting this all cleaned up 🚰

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.