ogobrecht / markdown-apex-plugin

Oracle APEX Dynamic Action Type Plugin: Markdown
https://apex.oracle.com/pls/apex/f?p=66154
Other
16 stars 1 forks source link
markdown-converter markdown-editor oracle-apex-plugin

Latest version | Online demo

Oracle APEX Dynamic Action Type Plugin: Markdown

This Oracle APEX plugin uses the Stack Overflow JavaScript Markdown implementation to turn textareas into Markdown editors and convert Markdown formatted text into HTML.

Installation

Whats Next?

APEX has its own Markdown implementation now. So this project is no longer maintained. It still works, but don't expect any major maintenance efforts.

How To Use

  1. Install the plugin
  2. On your page create a dynamic action on page load with the action Markdown [Plug-in]
  3. Add the CSS class markdown to your text areas and other content, which should be converted
  4. Optionally create per dynamic content (reports and other refreshable region types) an additional dynamic action on framework event After Refresh with selection type Region

Links

Credits

I would like to say THANK YOU to all the people who share their knowledge. Without this sharing I would not have been able to create this Markdown plugin. Special thanks to John Gruber for his first Markdown implementation in Perl, to John Fraser for his JavaScript port and to Dana Robinson and the people of Stack Exchange Inc. for the modifications and bugfixes. See also the LICENSE.txt for more information.

How The Plugin Works

Options

The plugin options (most options are on application level) can be configured under Shared Components > User Interface > Component Settings > Markdown[Plugin].

You will find there the following options:

Custom Styles

You can add here custom styles for the rendered HTML.

Example: .markdown h1 { text-transform: uppercase; }

Custom Image Function

The Plugin will replace #images# with your configured custom image function.

Enable Sanitizing Converter

With this option two plugins are registered for the converter. One of them sanitizes the output HTML to only include a list of whitelisted HTML tags. The other one attempts to balance opening/closing tags to prevent leaking formating if the HTML is displayed in the browser.

Try To Use Original Value From Display Only Items

This option depends on the option Enable Sanitizing Converter.

The APEX engine does escape special characters in most cases. Sometimes you can disable this like in reports. For read only items you can't disable this and depending on your security settings of your application at a minimum the basic escaping is done.

If you have code blocks in your Markdown text with HTML inside, this could be very annoying, because all the < and > characters are escaped to HTML entities. In fact, your HTML code in code blocks looks very bad, when the item is rendered read only. The preview from the editor is ok, because it is a live preview in your browser without interaction of the APEX engine.

When you enable this plugin option, then the Markdown plugin try to use the original text from the hidden item to render your HTML. From the security side this should be ok, because you can enable this option only when you have also the sanitizer enabled, which does whitelisting of HTML tags and suppresses script tags. You can try this out by injecting javascript code - the converter will sort out the script tags and your code will appear as normal inline text.

Enable Syntax Highlighting In Code Blocks

The used syntax highlighter is highlight.js with the default set of 22 common languages: Apache, Bash, C#, C++, CSS, CoffeeScript, Diff, HTML-XML, HTTP, Ini, JSON, Java, JavaScript, Makefile, Markdown, Nginx, Objective-C, PHP, Perl, Python, Ruby, SQL.

If you need more or other languages (172 available) then you can create your custom highlight.js package, rename it to the same file name used in the plugin and upload it to the plugin files.

Enable Markdown Extra Syntax

Markdown Extra is one of the extensions available for Markdown. It was originally implemented in PHP. For more details see here and here. These Markdown Extra syntax enhancements are also available for the JavaScript based implementation used in this Oracle APEX plugin:

See the next sections for details.

Tables

http://michelf.ca/projects/php-markdown/extra/#table

The following markdown...

| Item      | Value | Qty |
|-----------|------:|:---:|
| Computer  | $1600 |  5  |  
| Phone     |   $12 |  12 |
| *Pipe*    |    $1 | 234 |

...will render to this:

Item Value Qty
Computer $1600 5
Phone $12 12
Pipe $1 234

Span-level markdown inside of table cells will also be converted.

Fenced Code Blocks

http://github.github.com/github-flavored-markdown/

Fenced code blocks are supported à la GitHub. This markdown...

```
var x = 2;
```

...will be transformed into:

<pre>
    <code>var x = 2;</code>
</pre>

If syntax highlighting is enabled, then you can specify the language like so...

```javascript
var x = 2;
```

...which would be converted to:

<pre>
    <code class="language-javascript hljs">var x = 2;</code>
</pre>

If you omit the language, the highlighter tries its best to find out the language. The used highlighter is highlight.js with the default set of 22 common languages: Apache, Bash, C#, C++, CSS, CoffeeScript, Diff, HTML-XML, HTTP, Ini, JSON, Java, JavaScript, Makefile, Markdown, Nginx, Objective-C, PHP, Perl, Python, Ruby, SQL.

If you need more or other languages (172 available) then you can create your highlight.js package, rename it to the same file name used in the plugin and upload it to the plugin files.

Definition Lists

http://michelf.ca/projects/php-markdown/extra/#def-list

Term 1
:   Definition 1

Term 2
:   This definition has a code block.

        code block

becomes:

<dl>
  <dt>Term 1</dt>
  <dd>
    Definition 1
  </dd>
  <dt>Term 2</dt>
  <dd>
    This definition has a code block.
    <pre><code>code block</code></pre>
  </dd>
</dl>

Definitions can contain both inline and block-level markdown.

Footnotes

https://github.com/fletcher/MultiMarkdown/blob/master/Documentation/MultiMarkdown%20User%27s%20Guide.md#footnotes

Here is a footnote[^footnote].

[^footnote]: Here is the *text* of the **footnote**.

becomes:

<p>Here is a footnote<a href="#fn:footnote" id="fnref:footnote" title="See footnote" class="footnote">1</a>.</p>

<div class="footnotes">
<hr>
<ol>
<li id="fn:footnote">Here is the <em>text</em> of the <strong>footnote</strong>. <a href="#fnref:footnote" title="Return to article" class="reversefootnote">↩</a></li>
</ol>
</div>

You need a blank line after each footnote text, like with paragraphs.

Special Attributes

http://michelf.ca/projects/php-markdown/extra/#spe-attr

You can add class and id attributes to headers and gfm fenced code blocks.

``` {#gfm-id .gfm-class}
var foo = bar;
```

## A Header {#header-id}

### Another One ### {#header-id .hclass}

Underlined  {#what}
==========

SmartyPants

http://daringfireball.net/projects/smartypants/

SmartyPants extension converts ASCII punctuation characters into "smart" typographic punctuation HTML entities. For example:

Single backticks : 'Isn't this fun?' → ‘Isn’t this fun?’

Quotes : "Isn't this fun?" → “Isn’t this fun?”

Dashes : This -- is an en-dash and this --- is an em-dash → This – is an en-dash and this — is an em-dash

Newlines

https://help.github.com/articles/github-flavored-markdown#newlines

Newlines à la GitHub (without the need of two white spaces):

Roses are red
Violets are blue

becomes:

<p>Roses are red<br/>
Violets are blue</p>

Strikethrough

https://help.github.com/articles/github-flavored-markdown#strikethrough

Strikethrough à la GitHub:

~~Mistaken text.~~

becomes:

<p><del>Mistaken text.</del></p>

Custom Preview Container

If you want to have a custom preview container instead of the one generated under your text area simply create anywhere on your page a display only item with the name of the text area (editor) and append _PREVIEW to the name.

For an example: If the name of your text area is P3_SAMPLE_MARKDOWN_EDITOR then you name your display only item P3_SAMPLE_MARKDOWN_EDITOR_PREVIEW. The plugin will find this item and use it automatically.

You can also create a container element in the region source of an HTML region with the id attribute set to the mentioned name. (e.g. <div id="P3_SAMPLE_MARKDOWN_EDITOR_PREVIEW"></div>) or you set the static ID of the region itself to this name.

In both cases you have to manage the conditional rendering of your preview container by yourself. If the text area (Markdown editor) can be displayed in read only mode, then the text area IS your (pre)view, because the Markdown plugin simply renders all items except text areas and inputs and you have to hide ore not to render your custom preview container - its useless without an editor...

There is a small helper function shipped with plugin to maximize page items. It depends on your theme, if this helper is working for your or not. If not, then simply modify the helper to your needs, as said - the helper function is really small - here an example call in a dynamic action - you can see this helper live in action in the online demo app:

markdown.maximizeItem('editor', '#P3_SAMPLE_MARKDOWN_EDITOR', 4, 100);
markdown.maximizeItem('preview', '#P3_SAMPLE_MARKDOWN_EDITOR_PREVIEW',2 , 78);

The function itself:

markdown.maximizeItem = function (itemType, selector, regionIsNthParent, offsetBottom, debug) {
    $(selector).each( function() {
        var item = $(this);
        // jQuery eq function start count with 0, we want start count with 1
        var region = item.parents().eq(regionIsNthParent -1);
        var maximizeEditor = function() {
            item.width( region.width() - parseInt(region.css('padding-left')) - parseInt(region.css('padding-right')) )
                .height( $(window).height() - item.offset().top - offsetBottom );
        };
        var maximizePreview = function() {
            region.css( 'overflow','auto' )
                .height( $(window).height() - region.offset().top - offsetBottom );
        };

        if (itemType === 'editor') maximizeEditor();
        else if (itemType === 'preview') maximizePreview();

        if (debug) region.css('border','1px solid red');
        else $(window).resize(function () {
            if (itemType === 'editor') maximizeEditor();
            else if (itemType === 'preview') maximizePreview();
        });
    });
};

Changelog

This Markdown plugin uses semantic versioning.

Please use for all comments and discussions the issues functionality on GitHub.

1.3.1 (2018-01-07)

1.3.0 (2017-03-31)

1.2.0 (not officially released):

1.1.1 (2016-02-15)

1.1.0 (2016-02-14)

1.0.0 (2016-01-01)