├── .gitignore ├── Authors.md ├── LICENSE ├── Readme.md ├── build.xml ├── editor-preview.png ├── editor-source.png ├── manifest.mf ├── nbproject ├── build-impl.xml ├── genfiles.properties ├── platform.properties ├── project.properties └── project.xml ├── release └── modules │ └── ext │ ├── asm-4.1.jar │ ├── asm-analysis-4.1.jar │ ├── asm-tree-4.1.jar │ ├── asm-util-4.1.jar │ ├── parboiled-core-1.1.7.jar │ ├── parboiled-java-1.1.7.jar │ └── pegdown-1.5.0.jar ├── src └── flow │ └── netbeans │ └── markdown │ ├── ExportSerializer.java │ ├── MarkdownCodeTemplateFilter.java │ ├── MarkdownDataObject.java │ ├── MarkdownGenerateHtmlAction.java │ ├── MarkdownOnSaveTask.java │ ├── MarkdownViewHtmlAction.java │ ├── PreviewLinkRenderer.java │ ├── PreviewSerializer.java │ ├── RenderableImpl.java │ ├── api │ ├── RenderOption.java │ └── Renderable.java │ ├── csl │ ├── MarkdownAbbreviationsEntryItem.java │ ├── MarkdownAbbreviationsRootItem.java │ ├── MarkdownInlineVisitor.java │ ├── MarkdownLanguageConfig.java │ ├── MarkdownParser.java │ ├── MarkdownParserResult.java │ ├── MarkdownReferencesEntryItem.java │ ├── MarkdownReferencesRootItem.java │ ├── MarkdownStructureScanner.java │ ├── MarkdownTOCBuilder.java │ ├── MarkdownTOCEntryHandle.java │ ├── MarkdownTOCEntryItem.java │ ├── MarkdownTOCRootItem.java │ └── MarkdownTOCVisitor.java │ ├── highlighter │ ├── MarkdownLexer.java │ ├── MarkdownLexerVisitor.java │ ├── MarkdownToken.java │ ├── MarkdownTokenId.java │ └── MarkdownTokenListBuilder.java │ ├── options │ ├── Bundle.properties │ ├── MarkdownGlobalOptions.java │ ├── MarkdownOptionsPanelController.java │ ├── MarkdownPanel.form │ └── MarkdownPanel.java │ ├── package-info.java │ ├── preview │ ├── AbstractHtmlView.java │ ├── HtmlView.java │ ├── HtmlViewFactory.java │ ├── MarkdownPreviewMVElement.java │ ├── SwingHtmlView.java │ └── ext │ │ └── FXHtmlView.java │ ├── resources │ ├── Bundle.properties │ ├── FontAndColors.xml │ ├── MarkdownExample.md │ ├── MarkdownTemplate.md │ ├── MarkdownTemplateDescription.html │ ├── action-export.png │ ├── action-view.png │ ├── code-templates.xml │ ├── layer.xml │ ├── markdown-mark-16x16.png │ └── text-x-generic.png │ ├── spellchecker │ ├── MarkdownTokenList.java │ └── MarkdownTokenListProvider.java │ ├── typinghooks │ ├── MarkdownDeletedTextInterceptor.java │ ├── MarkdownTypedBreakInterceptor.java │ └── OrderedListReorderer.java │ └── utils │ └── MarkdownDocUtil.java └── test ├── resources ├── PhpMarkdown │ ├── Backslash_escapes.html │ ├── Backslash_escapes.md │ ├── Code_Spans.html │ ├── Code_Spans.md │ ├── Code_block_in_a_list_item.html │ ├── Code_block_in_a_list_item.md │ ├── Email_auto_links.html │ ├── Email_auto_links.md │ ├── Emphasis.html │ ├── Emphasis.md │ ├── Headers.html │ ├── Headers.md │ ├── Horizontal_Rules.html │ ├── Horizontal_Rules.md │ ├── Inline_HTML_(Simple).html │ ├── Inline_HTML_(Simple).md │ ├── Inline_HTML_(Span).html │ ├── Inline_HTML_(Span).md │ ├── Inline_HTML_comments.html │ ├── Inline_HTML_comments.md │ ├── Ins_and_del.html │ ├── Ins_and_del.md │ ├── Links_inline_style.html │ ├── Links_inline_style.md │ ├── MD5_Hashes.html │ ├── MD5_Hashes.md │ ├── Nesting.html │ ├── Nesting.md │ ├── PHP-Specific_Bugs.html │ ├── PHP-Specific_Bugs.md │ ├── Parens_in_URL.html │ ├── Parens_in_URL.md │ ├── Tight_blocks.html │ └── Tight_blocks.md └── PhpMarkdownExtra │ ├── Abbr.html │ ├── Abbr.md │ ├── Definition_Lists.html │ ├── Definition_Lists.md │ ├── Emphasis.html │ ├── Emphasis.md │ ├── Fenced_Code_Blocks.html │ ├── Fenced_Code_Blocks.md │ ├── Footnotes.html │ ├── Footnotes.md │ ├── Inline_HTML_with_Markdown_content.html │ ├── Inline_HTML_with_Markdown_content.md │ ├── Tables.html │ └── Tables.md └── unit ├── data ├── goldenfiles │ ├── headings.pass │ ├── nested.pass │ ├── paragraphs.pass │ └── plain.pass ├── resources │ ├── PhpMarkdown │ │ ├── Backslash_escapes.html │ │ ├── Backslash_escapes.md │ │ ├── Code_Spans.html │ │ ├── Code_Spans.md │ │ ├── Code_block_in_a_list_item.html │ │ ├── Code_block_in_a_list_item.md │ │ ├── Email_auto_links.html │ │ ├── Email_auto_links.md │ │ ├── Emphasis.html │ │ ├── Emphasis.md │ │ ├── Headers.html │ │ ├── Headers.md │ │ ├── Horizontal_Rules.html │ │ ├── Horizontal_Rules.md │ │ ├── Inline_HTML_(Simple).html │ │ ├── Inline_HTML_(Simple).md │ │ ├── Inline_HTML_(Span).html │ │ ├── Inline_HTML_(Span).md │ │ ├── Inline_HTML_comments.html │ │ ├── Inline_HTML_comments.md │ │ ├── Ins_and_del.html │ │ ├── Ins_and_del.md │ │ ├── Links_inline_style.html │ │ ├── Links_inline_style.md │ │ ├── MD5_Hashes.html │ │ ├── MD5_Hashes.md │ │ ├── Nesting.html │ │ ├── Nesting.md │ │ ├── PHP-Specific_Bugs.html │ │ ├── PHP-Specific_Bugs.md │ │ ├── Parens_in_URL.html │ │ ├── Parens_in_URL.md │ │ ├── Tight_blocks.html │ │ └── Tight_blocks.md │ └── PhpMarkdownExtra │ │ ├── Abbr.html │ │ ├── Abbr.md │ │ ├── Definition_Lists.html │ │ ├── Definition_Lists.md │ │ ├── Emphasis.html │ │ ├── Emphasis.md │ │ ├── Fenced_Code_Blocks.html │ │ ├── Fenced_Code_Blocks.md │ │ ├── Footnotes.html │ │ ├── Footnotes.md │ │ ├── Inline_HTML_with_Markdown_content.html │ │ ├── Inline_HTML_with_Markdown_content.md │ │ ├── Tables.html │ │ └── Tables.md └── testfiles │ ├── headings.md │ ├── nested.md │ ├── paragraphs.md │ └── plain.md └── src └── flow └── netbeans └── markdown ├── csl └── MarkdownTOCBuilderTest.java ├── highlighter ├── MarkdownLexerTest.java ├── MarkdownLexerTestBase.java ├── MarkdownLexerVisitorBasicsTest.java ├── MarkdownLexerVisitorExtensionsTest.java ├── MarkdownLexerVisitorTestSupport.java ├── MarkdownTokenIdTest.java └── MarkdownTokenListBuilderTest.java ├── matchers ├── ContainsTokensWithId.java ├── ContainsTokensWithLength.java ├── Empty.java ├── EveryItem.java ├── Matchers.java └── NonZeroLength.java ├── testresources ├── basics │ ├── code_block.md │ ├── code_inline.md │ ├── emphasis.md │ ├── header.md │ ├── horizontal_rule.md │ ├── image_inline.md │ ├── image_reference.md │ ├── link_auto.md │ ├── link_inline.md │ ├── link_reference.md │ ├── list_ordered.md │ ├── list_unordered.md │ └── quote.md └── extensions │ ├── abbreviations.md │ ├── autolinks.md │ ├── definitions.md │ ├── fenced_code_blocks.md │ ├── hardwraps.md │ ├── quotes.md │ ├── smarts.md │ ├── suppress_html_blocks.md │ ├── suppress_inline_html.md │ ├── tables.md │ └── wikilinks.md └── utils └── MarkdownDocUtilTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | /nbproject/private/ 2 | /build/ 3 | -------------------------------------------------------------------------------- /Authors.md: -------------------------------------------------------------------------------- 1 | # Authors 2 | 3 | - Florian Reiss 4 | - junichi11 5 | - Holger Stenger 6 | - Radosław Kowalewski 7 | - Robert Burkhead 8 | - Yann 9 | 10 | Contributions are always welcome and greatly appreciated! 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2011-2015 Florian Reiss 2 | Copyright 2013-2015 Holger Stenger 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | A NetBeans IDE plugin which adds Markdown support. This plugin provides basic syntax highlighting, HTML preview and HTML export when editing a Markdown document. 2 | 3 | # What is Markdown? 4 | 5 | > Markdown is a text-to-HTML conversion tool for web writers. Markdown allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid XHTML (or HTML). 6 | 7 | Source: 8 | 9 | # Installation 10 | 11 | The plugin is [available](http://plugins.netbeans.org/plugin/50964/markdown-support) in the official NetBeans Plugin Portal Update Center. 12 | 13 | You can also download a pre-packaged release: 14 | 15 | - https://github.com/madflow/flow-netbeans-markdown/releases (list of all releases) 16 | - https://github.com/madflow/flow-netbeans-markdown/releases/download/2.3.1/flow-netbeans-markdown.nbm (**note:** version 2.3.1) 17 | 18 | Install the plugin with: `Tools -> Plugins -> Downloaded` 19 | 20 | You may also compile a binary yourself with the **latest development code**. 21 | 22 | 1. git clone git://github.com/madflow/flow-netbeans-markdown.git 23 | 2. Open the folder with NetBeans (Open Project) 24 | 3. (Configure Target Platform if needed) 25 | 4. Choose "Create NBM" from the project menu 26 | 5. Install the plugin with: Tools -> Plugins -> Downloaded 27 | 28 | # Requirements 29 | 30 | - NetBeans >= 8.0 31 | - "NetBeans Plugin Development" plugin must be installed if you want to compile your own binary package. 32 | 33 | # Plugin features 34 | 35 | - Adds Markdown to your "New File" wizard 36 | - Provides basic syntax highlighting 37 | - Provides code folding based on headers 38 | - Provides bread crumbs in the editor based on headers 39 | - Provides a table of contents in the Navigator window 40 | - Enables full fledged preview in the editor window 41 | - Exports your saved file content to an HTML document 42 | - Enables HTML preview of your saved file in your configured web browser 43 | - Lets you customize the HTML output with CSS and alien intelligence (Options->Miscellaneous->Markdown->HTML Export) 44 | - Supports multiple extensions over standard markdown (see [PegDown][], Options->Miscellaneous->Markdown->Extensions) 45 | - Supports auto operations(additoin and removal) for lists (Options->Miscellaneous->Markdown->Miscellaneous) 46 | 47 | # Screenshots 48 | 49 | ![Editor - Source view](editor-source.png "The Source view of the Markdown editor") 50 | 51 | *** 52 | 53 | ![Editor - Preview view](editor-preview.png "The Preview view of the Markdown editor") 54 | 55 | 56 | # Resources 57 | 58 | - [PegDown][] : A pure-Java Markdown processor based on a parboiled PEG parser supporting a number of extensions. 59 | - http://daringfireball.net/projects/markdown/ : Home of the Markdown (Basics, Syntax) 60 | - http://openiconlibrary.sourceforge.net/ : Icons 61 | - [Markdown Mark][mdmark] : A graphic element to identify Markdown files created by [Dustin Curtis][dcurtis] ([Github repo][mdmark-gh]) 62 | 63 | [dcurtis]: http://dustincurtis.com/ 64 | [mdmark]: http://dcurt.is/the-markdown-mark 65 | [mdmark-gh]: https://github.com/dcurtis/markdown-mark 66 | [pegdown]: https://github.com/sirthias/pegdown 67 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Builds, tests, and runs the project flow.netbeans.markdown. 7 | 8 | 9 | -------------------------------------------------------------------------------- /editor-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/editor-preview.png -------------------------------------------------------------------------------- /editor-source.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/editor-source.png -------------------------------------------------------------------------------- /manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | OpenIDE-Module: flow.netbeans.markdown 3 | OpenIDE-Module-Layer: flow/netbeans/markdown/resources/layer.xml 4 | OpenIDE-Module-Localizing-Bundle: flow/netbeans/markdown/resources/Bundle.properties 5 | OpenIDE-Module-Requires: org.openide.windows.WindowManager 6 | OpenIDE-Module-Specification-Version: 2.3.2 7 | 8 | -------------------------------------------------------------------------------- /nbproject/build-impl.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /nbproject/genfiles.properties: -------------------------------------------------------------------------------- 1 | build.xml.data.CRC32=0b698057 2 | build.xml.script.CRC32=1b4e1375 3 | build.xml.stylesheet.CRC32=a56c6a5b@2.72.1 4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. 5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. 6 | nbproject/build-impl.xml.data.CRC32=0b698057 7 | nbproject/build-impl.xml.script.CRC32=ce4ad270 8 | nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.72.1 9 | -------------------------------------------------------------------------------- /nbproject/platform.properties: -------------------------------------------------------------------------------- 1 | cluster.path=\ 2 | ${nbplatform.active.dir}/harness:\ 3 | ${nbplatform.active.dir}/ide:\ 4 | ${nbplatform.active.dir}/nb:\ 5 | ${nbplatform.active.dir}/php:\ 6 | ${nbplatform.active.dir}/platform:\ 7 | ${nbplatform.active.dir}/websvccommon 8 | nbplatform.active=default 9 | -------------------------------------------------------------------------------- /nbproject/project.properties: -------------------------------------------------------------------------------- 1 | # 2 | #Sat Feb 13 17:00:08 CET 2016 3 | javac.source=1.7 4 | file.reference.parboiled-core-1.1.6.jar=release/modules/ext/parboiled-core-1.1.6.jar 5 | nbm.homepage=https://github.com/madflow/flow-netbeans-markdown 6 | file.reference.pegdown-1.4.2.jar=release/modules/ext/pegdown-1.4.2.jar 7 | license.file=LICENSE 8 | file.reference.asm-4.1.jar=release/modules/ext/asm-4.1.jar 9 | nbm.needs.restart=true 10 | nbm.module.author=https://github.com/madflow/flow-netbeans-markdown/blob/nb8/Authors.md 11 | file.reference.asm-analysis-4.1.jar=release/modules/ext/asm-analysis-4.1.jar 12 | keystore=nbproject/private/netbeans-markdown 13 | file.reference.parboiled-java-1.1.6.jar=release/modules/ext/parboiled-java-1.1.6.jar 14 | src-ext.cp.extra=${java.home}/lib/jfxrt.jar 15 | auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml 16 | nbm_alias=netbeans-markdown 17 | file.reference.asm-tree-4.1.jar=release/modules/ext/asm-tree-4.1.jar 18 | file.reference.asm-util-4.1.jar=release/modules/ext/asm-util-4.1.jar 19 | javac.compilerargs=-Xlint -Xlint\:-serial 20 | -------------------------------------------------------------------------------- /release/modules/ext/asm-4.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/release/modules/ext/asm-4.1.jar -------------------------------------------------------------------------------- /release/modules/ext/asm-analysis-4.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/release/modules/ext/asm-analysis-4.1.jar -------------------------------------------------------------------------------- /release/modules/ext/asm-tree-4.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/release/modules/ext/asm-tree-4.1.jar -------------------------------------------------------------------------------- /release/modules/ext/asm-util-4.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/release/modules/ext/asm-util-4.1.jar -------------------------------------------------------------------------------- /release/modules/ext/parboiled-core-1.1.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/release/modules/ext/parboiled-core-1.1.7.jar -------------------------------------------------------------------------------- /release/modules/ext/parboiled-java-1.1.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/release/modules/ext/parboiled-java-1.1.7.jar -------------------------------------------------------------------------------- /release/modules/ext/pegdown-1.5.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/release/modules/ext/pegdown-1.5.0.jar -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/ExportSerializer.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown; 2 | 3 | import org.pegdown.LinkRenderer; 4 | import org.pegdown.ToHtmlSerializer; 5 | 6 | /** 7 | * 8 | * @author madflow 9 | */ 10 | public class ExportSerializer extends ToHtmlSerializer { 11 | 12 | public ExportSerializer(LinkRenderer linkRenderer) { 13 | super(linkRenderer); 14 | } 15 | 16 | @Override 17 | protected void printImageTag(LinkRenderer.Rendering rendering) { 18 | printer.print(""); 25 | } 26 | 27 | private void printAttribute(String name, String value) { 28 | printer.print(' ').print(name).print('=').print('"').print(value).print('"'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/MarkdownCodeTemplateFilter.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown; 2 | 3 | import flow.netbeans.markdown.csl.MarkdownLanguageConfig; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import javax.swing.text.JTextComponent; 7 | import org.netbeans.api.editor.mimelookup.MimeRegistration; 8 | import org.netbeans.lib.editor.codetemplates.api.CodeTemplate; 9 | import org.netbeans.lib.editor.codetemplates.spi.CodeTemplateFilter; 10 | 11 | /** 12 | * 13 | * @author junichi11 14 | */ 15 | public class MarkdownCodeTemplateFilter implements CodeTemplateFilter { 16 | 17 | private static final String MD_CODE = "md-code"; // NOI18N 18 | 19 | @Override 20 | public boolean accept(CodeTemplate template) { 21 | return true; 22 | } 23 | 24 | @MimeRegistration(mimeType = MarkdownLanguageConfig.MIME_TYPE, service = CodeTemplateFilter.ContextBasedFactory.class) 25 | public static final class Factory implements CodeTemplateFilter.ContextBasedFactory { 26 | 27 | @Override 28 | public List getSupportedContexts() { 29 | return Collections.singletonList(MD_CODE); 30 | } 31 | 32 | @Override 33 | public CodeTemplateFilter createFilter(JTextComponent component, int offset) { 34 | return new MarkdownCodeTemplateFilter(); 35 | } 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/MarkdownOnSaveTask.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown; 2 | 3 | import flow.netbeans.markdown.csl.MarkdownLanguageConfig; 4 | import flow.netbeans.markdown.options.MarkdownGlobalOptions; 5 | import javax.swing.text.Document; 6 | import org.netbeans.api.editor.mimelookup.MimeRegistration; 7 | import org.netbeans.modules.editor.NbEditorUtilities; 8 | import org.netbeans.spi.editor.document.OnSaveTask; 9 | 10 | /** 11 | * 12 | * @author junichi11 13 | */ 14 | public final class MarkdownOnSaveTask implements OnSaveTask{ 15 | 16 | private MarkdownDataObject dataObject; 17 | 18 | private MarkdownOnSaveTask(Context context) { 19 | Document document = context.getDocument(); 20 | if (document != null) { 21 | dataObject = (MarkdownDataObject) NbEditorUtilities.getDataObject(document); 22 | } 23 | } 24 | 25 | @Override 26 | public void performTask() { 27 | if (dataObject == null) { 28 | return; 29 | } 30 | 31 | // view html 32 | if (MarkdownGlobalOptions.getInstance().isViewHtmlOnSave()) { 33 | MarkdownViewHtmlAction viewAction = new MarkdownViewHtmlAction(dataObject); 34 | viewAction.actionPerformed(null); 35 | } 36 | 37 | // export html 38 | if (MarkdownGlobalOptions.getInstance().isExportOnSave()) { 39 | MarkdownGenerateHtmlAction exportAction = new MarkdownGenerateHtmlAction(dataObject); 40 | exportAction.exportOnSave(); 41 | } 42 | } 43 | 44 | @Override 45 | public void runLocked(Runnable run) { 46 | run.run(); 47 | } 48 | 49 | @Override 50 | public boolean cancel() { 51 | return true; 52 | } 53 | 54 | @MimeRegistration(mimeType = MarkdownLanguageConfig.MIME_TYPE, service = OnSaveTask.Factory.class, position = 1500) 55 | public static final class FactoryImpl implements Factory { 56 | 57 | @Override 58 | public OnSaveTask createTask(Context context) { 59 | return new MarkdownOnSaveTask(context); 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/MarkdownViewHtmlAction.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown; 2 | 3 | import flow.netbeans.markdown.api.RenderOption; 4 | import flow.netbeans.markdown.api.Renderable; 5 | import java.awt.event.ActionEvent; 6 | import java.awt.event.ActionListener; 7 | import java.io.File; 8 | import java.io.FileOutputStream; 9 | import java.io.IOException; 10 | import java.io.PrintStream; 11 | import java.net.URL; 12 | import java.nio.charset.Charset; 13 | import java.util.EnumSet; 14 | import java.util.Set; 15 | import org.netbeans.api.queries.FileEncodingQuery; 16 | import org.openide.awt.ActionID; 17 | import org.openide.awt.ActionReference; 18 | import org.openide.awt.ActionReferences; 19 | import org.openide.awt.ActionRegistration; 20 | import org.openide.awt.HtmlBrowser.URLDisplayer; 21 | import org.openide.util.Exceptions; 22 | import org.openide.util.NbBundle.Messages; 23 | 24 | @ActionID(category = "File", 25 | id = "flow.netbeans.markdown.MarkdownViewHtmlAction") 26 | @ActionRegistration(displayName = "#CTL_MarkdownViewHtmlAction", iconBase = "flow/netbeans/markdown/resources/action-view.png") 27 | @ActionReferences({ 28 | @ActionReference(path = "Editors/text/x-markdown/Toolbars/Default", position = 270100), 29 | @ActionReference(path = "Editors/text/x-markdown/Popup", position = 0), 30 | @ActionReference(path = "Loaders/text/x-markdown/Actions", position = 251) 31 | }) 32 | @Messages("CTL_MarkdownViewHtmlAction=View HTML") 33 | public final class MarkdownViewHtmlAction implements ActionListener { 34 | 35 | private final MarkdownDataObject context; 36 | 37 | public MarkdownViewHtmlAction(MarkdownDataObject context) { 38 | this.context = context; 39 | } 40 | 41 | @Override 42 | public void actionPerformed(ActionEvent ev) { 43 | try { 44 | Renderable renderable = context.getLookup().lookup(Renderable.class); 45 | 46 | Set renderOptions = EnumSet.of( 47 | RenderOption.PREFER_EDITOR, 48 | RenderOption.RESOLVE_IMAGE_URLS); 49 | String htmlText = renderable.renderAsHtml(renderOptions); 50 | 51 | File temp = File.createTempFile("preview-" + context.getPrimaryFile().getName(), ".html"); 52 | temp.deleteOnExit(); 53 | 54 | // get file encoding 55 | Charset encoding = FileEncodingQuery.getEncoding(context.getPrimaryFile()); 56 | PrintStream out = new PrintStream(new FileOutputStream(temp), false, encoding.name()); 57 | out.print(htmlText); 58 | out.close(); 59 | 60 | URL url = temp.toURI().toURL(); 61 | URLDisplayer.getDefault().showURL(url); 62 | } catch (IOException ex) { 63 | Exceptions.printStackTrace(ex); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/PreviewLinkRenderer.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URISyntaxException; 5 | import java.net.URL; 6 | import org.pegdown.LinkRenderer; 7 | import org.pegdown.ast.AutoLinkNode; 8 | import org.pegdown.ast.ExpLinkNode; 9 | import org.pegdown.ast.MailLinkNode; 10 | import org.pegdown.ast.RefLinkNode; 11 | import org.pegdown.ast.WikiLinkNode; 12 | 13 | /** 14 | * Turns pegdown AST link nodes into rendered links, optionally resolving relative URLs to 15 | * absolute URLs using a given base URL. 16 | * 17 | * @author Holger Stenger 18 | */ 19 | public class PreviewLinkRenderer extends LinkRenderer { 20 | 21 | /** The base URL against which absolute URLs should be resolved. */ 22 | private final URL baseUrl; 23 | 24 | /** Indicates whether relative URLs should be resolved against the base URL. */ 25 | private final boolean resolveLinkUrls; 26 | 27 | /** 28 | * Create a new link renderer that will optionally resolve relative URLs to absolute URLs. 29 | * 30 | * @param baseUrl the base URL against which relative URLs will be resolved. 31 | * @param resolveLinkUrls if true, relative URLs in rendered links will be resolved to 32 | * absolute URLs with the given base URL. 33 | */ 34 | public PreviewLinkRenderer(URL baseUrl, boolean resolveLinkUrls) { 35 | super(); 36 | this.baseUrl = baseUrl; 37 | this.resolveLinkUrls = resolveLinkUrls; 38 | } 39 | 40 | @Override 41 | public LinkRenderer.Rendering render(AutoLinkNode node) { 42 | return transform(super.render(node)); 43 | } 44 | 45 | @Override 46 | public LinkRenderer.Rendering render(MailLinkNode node) { 47 | return transform(super.render(node)); 48 | } 49 | 50 | @Override 51 | public LinkRenderer.Rendering render(WikiLinkNode node) { 52 | return transform(super.render(node)); 53 | } 54 | 55 | @Override 56 | public LinkRenderer.Rendering render(ExpLinkNode node, String text) { 57 | return transform(super.render(node, text)); 58 | } 59 | 60 | @Override 61 | public LinkRenderer.Rendering render(RefLinkNode node, String url, String title, String text) { 62 | return transform(super.render(node, url, title, text)); 63 | } 64 | 65 | /** 66 | * Resolves relative URLs against a base URL to return an absolute URL. 67 | * 68 | * @param uriText the possibly relative URL to resolve 69 | * @return the absolute form of the provided relative URL; if the URL is already absolute, or if it 70 | * would otherwise result in an invalid URL when resolved against the base URL, then the 71 | * original string is returned unmodified 72 | */ 73 | private String resolveUrl(final String uriText) { 74 | try { 75 | return baseUrl.toURI().resolve(uriText).toURL().toExternalForm(); 76 | } 77 | catch (URISyntaxException ex) { 78 | } 79 | catch (MalformedURLException ex) { 80 | } 81 | return uriText; 82 | } 83 | 84 | /** 85 | * Transforms the rendered link's href URL to its absolute form using a base URL, 86 | * if URL resolution is turned on. 87 | * 88 | * @param rendering the previously rendered link 89 | * @return if URL resolution is turned on and the link is relative, then the rendered 90 | * link with the href URL in its absolute form using the base URL provided to 91 | * this renderer; otherwise the original rendered link 92 | */ 93 | private LinkRenderer.Rendering transform(LinkRenderer.Rendering rendering) { 94 | if (resolveLinkUrls && (rendering.href != null)) { 95 | LinkRenderer.Rendering resolvedRendering = new LinkRenderer.Rendering( 96 | resolveUrl(rendering.href), rendering.text); 97 | for (LinkRenderer.Attribute attr : rendering.attributes) { 98 | resolvedRendering.withAttribute(attr); 99 | } 100 | return resolvedRendering; 101 | } else { 102 | return rendering; 103 | } 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/PreviewSerializer.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URISyntaxException; 5 | import java.net.URL; 6 | import org.pegdown.LinkRenderer; 7 | import org.pegdown.ToHtmlSerializer; 8 | import org.pegdown.ast.SuperNode; 9 | 10 | /** 11 | * 12 | * @author Holger Stenger 13 | */ 14 | public class PreviewSerializer extends ToHtmlSerializer { 15 | private final URL baseUrl; 16 | 17 | private final boolean resolveImageUrls; 18 | 19 | public PreviewSerializer(final URL baseUrl) { 20 | this(baseUrl, true, false); 21 | } 22 | 23 | public PreviewSerializer(URL baseUrl, boolean resolveImageUrls, boolean resolveLinkUrls) { 24 | super(new PreviewLinkRenderer(baseUrl, resolveLinkUrls)); 25 | this.baseUrl = baseUrl; 26 | this.resolveImageUrls = resolveImageUrls; 27 | } 28 | 29 | private String resolveUrl(final String url) { 30 | try { 31 | return baseUrl.toURI().resolve(url).toURL().toExternalForm(); 32 | } 33 | catch (URISyntaxException ex) { 34 | } 35 | catch (MalformedURLException ex) { 36 | } 37 | return url; 38 | } 39 | 40 | private String resolveImageUrl(final String url) { 41 | if (resolveImageUrls) { 42 | return resolveUrl(url); 43 | } 44 | else { 45 | return url; 46 | } 47 | } 48 | 49 | protected void printImageTag(SuperNode imageNode, String url) { 50 | printer.print("\"")"); 52 | } 53 | 54 | @Override 55 | protected void printImageTag(LinkRenderer.Rendering rendering) { 56 | printer.print(""); 63 | } 64 | 65 | private void printAttribute(String name, String value) { 66 | printer.print(' ').print(name).print('=').print('"').print(value).print('"'); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/api/RenderOption.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.api; 3 | 4 | /** 5 | * 6 | * @author Holger Stenger 7 | */ 8 | public enum RenderOption { 9 | /** Resolve relative links using source document location. */ 10 | RESOLVE_LINK_URLS, 11 | /** Resolve relative image paths using source document location. */ 12 | RESOLVE_IMAGE_URLS, 13 | /** Generate output which can be rendered by Swing. */ 14 | SWING_COMPATIBLE, 15 | /** If the file is currently opened in the editor, use the editor content instead of the file content. */ 16 | PREFER_EDITOR 17 | } 18 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/api/Renderable.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.api; 3 | 4 | import java.io.IOException; 5 | import java.util.Set; 6 | 7 | /** 8 | * 9 | * @author Holger Stenger 10 | */ 11 | public interface Renderable { 12 | String renderAsHtml(Set renderOptions) throws IOException; 13 | } 14 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/csl/MarkdownAbbreviationsEntryItem.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.csl; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | import java.util.Set; 6 | import javax.swing.ImageIcon; 7 | import org.netbeans.modules.csl.api.ElementHandle; 8 | import org.netbeans.modules.csl.api.ElementKind; 9 | import org.netbeans.modules.csl.api.HtmlFormatter; 10 | import org.netbeans.modules.csl.api.Modifier; 11 | import org.netbeans.modules.csl.api.StructureItem; 12 | import org.openide.filesystems.FileObject; 13 | import org.pegdown.ast.AbbreviationNode; 14 | 15 | /** 16 | * 17 | * @author Holger 18 | */ 19 | public class MarkdownAbbreviationsEntryItem implements StructureItem { 20 | private final FileObject file; 21 | 22 | private final AbbreviationNode node; 23 | 24 | private final String name; 25 | 26 | private final String expansion; 27 | 28 | public MarkdownAbbreviationsEntryItem(FileObject file, AbbreviationNode node) { 29 | this.file = file; 30 | this.node = node; 31 | MarkdownInlineVisitor visitor = new MarkdownInlineVisitor(); 32 | node.accept(visitor); 33 | this.name = visitor.getPlainText(); 34 | if (node.getExpansion() != null) { 35 | visitor = new MarkdownInlineVisitor(); 36 | node.getExpansion().accept(visitor); 37 | this.expansion = visitor.getPlainText().trim(); 38 | } 39 | else { 40 | this.expansion = ""; 41 | } 42 | } 43 | 44 | @Override 45 | public String getName() { 46 | return name; 47 | } 48 | 49 | @Override 50 | public String getSortText() { 51 | return getName(); 52 | } 53 | 54 | @Override 55 | public String getHtml(HtmlFormatter formatter) { 56 | formatter.appendText(getName()); 57 | if (!expansion.isEmpty()) { 58 | formatter.appendHtml(" "); 59 | formatter.appendText(expansion); 60 | formatter.appendHtml(""); 61 | } 62 | return formatter.getText(); 63 | } 64 | 65 | @Override 66 | public ElementHandle getElementHandle() { 67 | return null; 68 | } 69 | 70 | @Override 71 | public ElementKind getKind() { 72 | return ElementKind.CONSTANT; 73 | } 74 | 75 | @Override 76 | public Set getModifiers() { 77 | return Collections.emptySet(); 78 | } 79 | 80 | @Override 81 | public boolean isLeaf() { 82 | return true; 83 | } 84 | 85 | @Override 86 | public List getNestedItems() { 87 | return Collections.emptyList(); 88 | } 89 | 90 | @Override 91 | public long getPosition() { 92 | return node.getStartIndex(); 93 | } 94 | 95 | @Override 96 | public long getEndPosition() { 97 | return node.getEndIndex(); 98 | } 99 | 100 | @Override 101 | public ImageIcon getCustomIcon() { 102 | return null; 103 | } 104 | 105 | @Override 106 | public int hashCode() { 107 | int hash = 7; 108 | hash = 29 * hash + (this.file != null ? this.file.hashCode() : 0); 109 | hash = 29 * hash + (this.name != null ? this.name.hashCode() : 0); 110 | return hash; 111 | } 112 | 113 | @Override 114 | public boolean equals(Object obj) { 115 | if (obj == null) { 116 | return false; 117 | } 118 | if (getClass() != obj.getClass()) { 119 | return false; 120 | } 121 | final MarkdownAbbreviationsEntryItem other = (MarkdownAbbreviationsEntryItem) obj; 122 | if (this.file != other.file && (this.file == null || !this.file.equals(other.file))) { 123 | return false; 124 | } 125 | if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { 126 | return false; 127 | } 128 | return true; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/csl/MarkdownAbbreviationsRootItem.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.csl; 3 | 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.List; 7 | import java.util.Set; 8 | import javax.swing.ImageIcon; 9 | import org.netbeans.modules.csl.api.ElementHandle; 10 | import org.netbeans.modules.csl.api.ElementKind; 11 | import org.netbeans.modules.csl.api.HtmlFormatter; 12 | import org.netbeans.modules.csl.api.Modifier; 13 | import org.netbeans.modules.csl.api.StructureItem; 14 | import org.openide.filesystems.FileObject; 15 | import org.openide.util.NbBundle; 16 | import org.pegdown.ast.AbbreviationNode; 17 | import org.pegdown.ast.RootNode; 18 | 19 | /** 20 | * 21 | * @author Holger 22 | */ 23 | @NbBundle.Messages({ 24 | "TXT_MarkdownAbbreviationsRootItem=Abbreviations" 25 | }) 26 | public class MarkdownAbbreviationsRootItem implements StructureItem { 27 | private final FileObject file; 28 | 29 | private final RootNode node; 30 | private final List nestedItems; 31 | 32 | public MarkdownAbbreviationsRootItem(FileObject file, RootNode node) { 33 | this.file = file; 34 | this.node = node; 35 | nestedItems = new ArrayList(); 36 | for (AbbreviationNode abbrNode : node.getAbbreviations()) { 37 | nestedItems.add(new MarkdownAbbreviationsEntryItem(file, abbrNode)); 38 | } 39 | } 40 | 41 | @Override 42 | public String getName() { 43 | return Bundle.TXT_MarkdownAbbreviationsRootItem(); 44 | } 45 | 46 | @Override 47 | public String getSortText() { 48 | return "3Abbreviations"; 49 | } 50 | 51 | @Override 52 | public String getHtml(HtmlFormatter formatter) { 53 | formatter.appendText(getName()); 54 | return formatter.getText(); 55 | } 56 | 57 | @Override 58 | public ElementHandle getElementHandle() { 59 | return null; 60 | } 61 | 62 | @Override 63 | public ElementKind getKind() { 64 | return ElementKind.PACKAGE; 65 | } 66 | 67 | @Override 68 | public Set getModifiers() { 69 | return Collections.emptySet(); 70 | } 71 | 72 | @Override 73 | public boolean isLeaf() { 74 | return false; 75 | } 76 | 77 | @Override 78 | public List getNestedItems() { 79 | return Collections.unmodifiableList(nestedItems); 80 | } 81 | 82 | @Override 83 | public long getPosition() { 84 | return 0; 85 | } 86 | 87 | @Override 88 | public long getEndPosition() { 89 | return 0; 90 | } 91 | 92 | @Override 93 | public ImageIcon getCustomIcon() { 94 | return null; 95 | } 96 | 97 | @Override 98 | public int hashCode() { 99 | int hash = 7; 100 | hash = 61 * hash + (this.file != null ? this.file.hashCode() : 0); 101 | return hash; 102 | } 103 | 104 | @Override 105 | public boolean equals(Object obj) { 106 | if (obj == null) { 107 | return false; 108 | } 109 | if (getClass() != obj.getClass()) { 110 | return false; 111 | } 112 | final MarkdownAbbreviationsRootItem other = (MarkdownAbbreviationsRootItem) obj; 113 | if (this.file != other.file && (this.file == null || !this.file.equals(other.file))) { 114 | return false; 115 | } 116 | return true; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/csl/MarkdownLanguageConfig.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.csl; 2 | 3 | import flow.netbeans.markdown.highlighter.MarkdownTokenId; 4 | import org.netbeans.api.lexer.Language; 5 | import org.netbeans.modules.csl.api.StructureScanner; 6 | import org.netbeans.modules.csl.spi.DefaultLanguageConfig; 7 | import org.netbeans.modules.csl.spi.LanguageRegistration; 8 | import org.netbeans.modules.parsing.spi.Parser; 9 | 10 | @LanguageRegistration(mimeType = MarkdownLanguageConfig.MIME_TYPE) 11 | public class MarkdownLanguageConfig extends DefaultLanguageConfig { 12 | 13 | public static final String MIME_TYPE = "text/x-markdown"; //NOI18N 14 | 15 | @Override 16 | public Language getLexerLanguage() { 17 | return MarkdownTokenId.language(); 18 | } 19 | 20 | @Override 21 | public String getDisplayName() { 22 | return "Markdown"; //NOI18N 23 | } 24 | 25 | @Override 26 | public Parser getParser() { 27 | return new MarkdownParser(); 28 | } 29 | 30 | @Override 31 | public boolean hasStructureScanner() { 32 | return true; 33 | } 34 | 35 | @Override 36 | public StructureScanner getStructureScanner() { 37 | return new MarkdownStructureScanner(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/csl/MarkdownParser.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.csl; 3 | 4 | import flow.netbeans.markdown.options.MarkdownGlobalOptions; 5 | import javax.swing.event.ChangeListener; 6 | import org.netbeans.modules.parsing.api.Snapshot; 7 | import org.netbeans.modules.parsing.api.Task; 8 | import org.netbeans.modules.parsing.spi.ParseException; 9 | import org.netbeans.modules.parsing.spi.Parser; 10 | import org.netbeans.modules.parsing.spi.SourceModificationEvent; 11 | import org.pegdown.PegDownProcessor; 12 | import org.pegdown.ast.RootNode; 13 | 14 | /** 15 | * 16 | * @author Holger 17 | */ 18 | public class MarkdownParser extends Parser { 19 | private Snapshot snapshot; 20 | private RootNode rootNode; 21 | private int extensions; 22 | 23 | public MarkdownParser() { 24 | } 25 | 26 | @Override 27 | public void parse(Snapshot snapshot, Task task, SourceModificationEvent event) throws ParseException { 28 | this.snapshot = snapshot; 29 | 30 | CharSequence text = snapshot.getText(); 31 | 32 | this.extensions = MarkdownGlobalOptions.getInstance().getExtensionsValue(); 33 | PegDownProcessor markdownProcessor = new PegDownProcessor(extensions); 34 | 35 | rootNode = markdownProcessor.parser.parse(text.toString().toCharArray()); 36 | } 37 | 38 | @Override 39 | public Result getResult(Task task) throws ParseException { 40 | return new MarkdownParserResult(snapshot, rootNode, extensions); 41 | } 42 | 43 | @Override 44 | public void addChangeListener(ChangeListener changeListener) { 45 | } 46 | 47 | @Override 48 | public void removeChangeListener(ChangeListener changeListener) { 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/csl/MarkdownParserResult.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.csl; 3 | 4 | import java.util.Collections; 5 | import java.util.List; 6 | import org.netbeans.modules.csl.api.Error; 7 | import org.netbeans.modules.csl.spi.ParserResult; 8 | import org.netbeans.modules.parsing.api.Snapshot; 9 | import org.netbeans.modules.parsing.spi.ParseException; 10 | import org.pegdown.ast.RootNode; 11 | 12 | /** 13 | * 14 | * @author Holger 15 | */ 16 | public class MarkdownParserResult extends ParserResult { 17 | private final RootNode rootNode; 18 | 19 | private boolean valid; 20 | private final int extensions; 21 | 22 | public MarkdownParserResult(Snapshot snapshot, RootNode rootNode, int extensions) { 23 | super(snapshot); 24 | valid = true; 25 | this.rootNode = rootNode; 26 | this.extensions = extensions; 27 | } 28 | 29 | public RootNode getRootNode() throws ParseException { 30 | if (!valid) { 31 | throw new ParseException(); 32 | } 33 | return rootNode; 34 | } 35 | 36 | public int getExtensions() throws ParseException { 37 | if (!valid) { 38 | throw new ParseException(); 39 | } 40 | return extensions; 41 | } 42 | 43 | @Override 44 | protected void invalidate() { 45 | valid = false; 46 | } 47 | 48 | @Override 49 | public List getDiagnostics() { 50 | return Collections.emptyList(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/csl/MarkdownReferencesEntryItem.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.csl; 3 | 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.Set; 7 | import javax.swing.ImageIcon; 8 | import org.netbeans.modules.csl.api.ElementHandle; 9 | import org.netbeans.modules.csl.api.ElementKind; 10 | import org.netbeans.modules.csl.api.HtmlFormatter; 11 | import org.netbeans.modules.csl.api.Modifier; 12 | import org.netbeans.modules.csl.api.StructureItem; 13 | import org.openide.filesystems.FileObject; 14 | import org.pegdown.ast.ReferenceNode; 15 | 16 | /** 17 | * 18 | * @author Holger 19 | */ 20 | public class MarkdownReferencesEntryItem implements StructureItem { 21 | private final FileObject file; 22 | 23 | private final ReferenceNode node; 24 | 25 | private final String name; 26 | 27 | public MarkdownReferencesEntryItem(FileObject file, ReferenceNode node) { 28 | this.file = file; 29 | this.node = node; 30 | MarkdownInlineVisitor visitor = new MarkdownInlineVisitor(); 31 | node.accept(visitor); 32 | this.name = visitor.getPlainText(); 33 | } 34 | 35 | @Override 36 | public String getName() { 37 | return name; 38 | } 39 | 40 | @Override 41 | public String getSortText() { 42 | return getName(); 43 | } 44 | 45 | @Override 46 | public String getHtml(HtmlFormatter formatter) { 47 | formatter.appendText(getName()); 48 | formatter.appendHtml(" "); 49 | formatter.appendText(node.getUrl()); 50 | formatter.appendHtml(""); 51 | return formatter.getText(); 52 | } 53 | 54 | @Override 55 | public ElementHandle getElementHandle() { 56 | return null; 57 | } 58 | 59 | @Override 60 | public ElementKind getKind() { 61 | return ElementKind.CONSTANT; 62 | } 63 | 64 | @Override 65 | public Set getModifiers() { 66 | return Collections.emptySet(); 67 | } 68 | 69 | @Override 70 | public boolean isLeaf() { 71 | return true; 72 | } 73 | 74 | @Override 75 | public List getNestedItems() { 76 | return Collections.emptyList(); 77 | } 78 | 79 | @Override 80 | public long getPosition() { 81 | return node.getStartIndex(); 82 | } 83 | 84 | @Override 85 | public long getEndPosition() { 86 | return node.getEndIndex(); 87 | } 88 | 89 | @Override 90 | public ImageIcon getCustomIcon() { 91 | return null; 92 | } 93 | 94 | @Override 95 | public int hashCode() { 96 | int hash = 7; 97 | hash = 29 * hash + (this.file != null ? this.file.hashCode() : 0); 98 | hash = 29 * hash + (this.name != null ? this.name.hashCode() : 0); 99 | return hash; 100 | } 101 | 102 | @Override 103 | public boolean equals(Object obj) { 104 | if (obj == null) { 105 | return false; 106 | } 107 | if (getClass() != obj.getClass()) { 108 | return false; 109 | } 110 | final MarkdownReferencesEntryItem other = (MarkdownReferencesEntryItem) obj; 111 | if (this.file != other.file && (this.file == null || !this.file.equals(other.file))) { 112 | return false; 113 | } 114 | if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { 115 | return false; 116 | } 117 | return true; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/csl/MarkdownReferencesRootItem.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.csl; 3 | 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.List; 7 | import java.util.Set; 8 | import javax.swing.ImageIcon; 9 | import org.netbeans.modules.csl.api.ElementHandle; 10 | import org.netbeans.modules.csl.api.ElementKind; 11 | import org.netbeans.modules.csl.api.HtmlFormatter; 12 | import org.netbeans.modules.csl.api.Modifier; 13 | import org.netbeans.modules.csl.api.StructureItem; 14 | import org.openide.filesystems.FileObject; 15 | import org.openide.util.NbBundle; 16 | import org.pegdown.ast.ReferenceNode; 17 | import org.pegdown.ast.RootNode; 18 | 19 | /** 20 | * 21 | * @author Holger 22 | */ 23 | @NbBundle.Messages({ 24 | "TXT_MarkdownReferencesRootItem=References" 25 | }) 26 | public class MarkdownReferencesRootItem implements StructureItem { 27 | private final FileObject file; 28 | 29 | private final RootNode node; 30 | private final List nestedItems; 31 | 32 | public MarkdownReferencesRootItem(FileObject file, RootNode node) { 33 | this.file = file; 34 | this.node = node; 35 | nestedItems = new ArrayList(); 36 | for (ReferenceNode refNode : node.getReferences()) { 37 | nestedItems.add(new MarkdownReferencesEntryItem(file, refNode)); 38 | } 39 | } 40 | 41 | @Override 42 | public String getName() { 43 | return Bundle.TXT_MarkdownReferencesRootItem(); 44 | } 45 | 46 | @Override 47 | public String getSortText() { 48 | return "2References"; 49 | } 50 | 51 | @Override 52 | public String getHtml(HtmlFormatter formatter) { 53 | formatter.appendText(getName()); 54 | return formatter.getText(); 55 | } 56 | 57 | @Override 58 | public ElementHandle getElementHandle() { 59 | return null; 60 | } 61 | 62 | @Override 63 | public ElementKind getKind() { 64 | return ElementKind.PACKAGE; 65 | } 66 | 67 | @Override 68 | public Set getModifiers() { 69 | return Collections.emptySet(); 70 | } 71 | 72 | @Override 73 | public boolean isLeaf() { 74 | return false; 75 | } 76 | 77 | @Override 78 | public List getNestedItems() { 79 | return Collections.unmodifiableList(nestedItems); 80 | } 81 | 82 | @Override 83 | public long getPosition() { 84 | return 0; 85 | } 86 | 87 | @Override 88 | public long getEndPosition() { 89 | return 0; 90 | } 91 | 92 | @Override 93 | public ImageIcon getCustomIcon() { 94 | return null; 95 | } 96 | 97 | @Override 98 | public int hashCode() { 99 | int hash = 7; 100 | hash = 61 * hash + (this.file != null ? this.file.hashCode() : 0); 101 | return hash; 102 | } 103 | 104 | @Override 105 | public boolean equals(Object obj) { 106 | if (obj == null) { 107 | return false; 108 | } 109 | if (getClass() != obj.getClass()) { 110 | return false; 111 | } 112 | final MarkdownReferencesRootItem other = (MarkdownReferencesRootItem) obj; 113 | if (this.file != other.file && (this.file == null || !this.file.equals(other.file))) { 114 | return false; 115 | } 116 | return true; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/csl/MarkdownStructureScanner.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.csl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | import java.util.Map; 8 | import org.netbeans.modules.csl.api.OffsetRange; 9 | import org.netbeans.modules.csl.api.StructureItem; 10 | import org.netbeans.modules.csl.api.StructureScanner; 11 | import org.netbeans.modules.csl.spi.ParserResult; 12 | import org.netbeans.modules.parsing.spi.ParseException; 13 | import org.openide.filesystems.FileObject; 14 | import org.openide.util.Exceptions; 15 | import org.pegdown.Extensions; 16 | import org.pegdown.ast.Node; 17 | import org.pegdown.ast.RootNode; 18 | 19 | /** 20 | * 21 | * @author Holger 22 | */ 23 | public class MarkdownStructureScanner implements StructureScanner { 24 | 25 | public MarkdownStructureScanner() { 26 | } 27 | 28 | @Override 29 | public List scan(ParserResult pr) { 30 | List items = null; 31 | if (pr instanceof MarkdownParserResult) { 32 | MarkdownParserResult result = (MarkdownParserResult) pr; 33 | try { 34 | RootNode rootNode = result.getRootNode(); 35 | int extensions = result.getExtensions(); 36 | if (rootNode != null) { 37 | FileObject file = pr.getSnapshot().getSource().getFileObject(); 38 | MarkdownTOCVisitor visitor = new MarkdownTOCVisitor(file); 39 | rootNode.accept(visitor); 40 | MarkdownTOCRootItem tocRootItem 41 | = new MarkdownTOCRootItem(file, rootNode, visitor.getTOCEntryItems()); 42 | MarkdownReferencesRootItem refsRootItem 43 | = new MarkdownReferencesRootItem(file, rootNode); 44 | 45 | if ((extensions & Extensions.ABBREVIATIONS) != 0) { 46 | MarkdownAbbreviationsRootItem abbrRootItem 47 | = new MarkdownAbbreviationsRootItem(file, rootNode); 48 | items = Arrays.asList(tocRootItem, refsRootItem, abbrRootItem); 49 | } else { 50 | items = Arrays.asList(tocRootItem, refsRootItem); 51 | } 52 | } 53 | } 54 | catch (ParseException ex) { 55 | //Exceptions.printStackTrace(ex); 56 | } 57 | } 58 | if (items == null) { 59 | items = Collections.emptyList(); 60 | } 61 | return items; 62 | } 63 | 64 | @Override 65 | public Map> folds(ParserResult pr) { 66 | Map> foldsByType = null; 67 | if (pr instanceof MarkdownParserResult) { 68 | MarkdownParserResult result = (MarkdownParserResult) pr; 69 | try { 70 | RootNode rootNode = result.getRootNode(); 71 | if (rootNode != null) { 72 | List sectionFolds = new ArrayList(); 73 | for (Node node : rootNode.getChildren()) { 74 | MarkdownTOCVisitor visitor = new MarkdownTOCVisitor(pr.getSnapshot().getSource().getFileObject()); 75 | rootNode.accept(visitor); 76 | sectionFolds = visitor.getOffsetRanges(); 77 | } 78 | foldsByType = Collections.singletonMap("comments", sectionFolds); 79 | } 80 | } 81 | catch (ParseException ex) { 82 | Exceptions.printStackTrace(ex); 83 | } 84 | } 85 | if (foldsByType == null) { 86 | foldsByType = Collections.emptyMap(); 87 | } 88 | return foldsByType; 89 | } 90 | 91 | @Override 92 | public Configuration getConfiguration() { 93 | return new Configuration(false, false); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/csl/MarkdownTOCEntryHandle.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.csl; 3 | 4 | import java.util.Collections; 5 | import java.util.Set; 6 | import org.netbeans.modules.csl.api.ElementHandle; 7 | import org.netbeans.modules.csl.api.ElementKind; 8 | import org.netbeans.modules.csl.api.Modifier; 9 | import org.netbeans.modules.csl.api.OffsetRange; 10 | import org.netbeans.modules.csl.spi.ParserResult; 11 | import org.openide.filesystems.FileObject; 12 | 13 | /** 14 | * 15 | * @author Holger 16 | */ 17 | public class MarkdownTOCEntryHandle implements ElementHandle { 18 | private final FileObject file; 19 | private final String name; 20 | private final int startIndex; 21 | private final int endIndex; 22 | 23 | public MarkdownTOCEntryHandle(FileObject file, String name, int startIndex, int endIndex) { 24 | this.file = file; 25 | this.name = name; 26 | this.startIndex = startIndex; 27 | this.endIndex = endIndex; 28 | } 29 | 30 | @Override 31 | public FileObject getFileObject() { 32 | return file; 33 | } 34 | 35 | @Override 36 | public String getMimeType() { 37 | return null; 38 | } 39 | 40 | @Override 41 | public String getName() { 42 | return name; 43 | } 44 | 45 | @Override 46 | public String getIn() { 47 | return null; 48 | } 49 | 50 | @Override 51 | public ElementKind getKind() { 52 | return ElementKind.TAG; 53 | } 54 | 55 | @Override 56 | public Set getModifiers() { 57 | return Collections.emptySet(); 58 | } 59 | 60 | @Override 61 | public boolean signatureEquals(ElementHandle eh) { 62 | if (eh instanceof MarkdownTOCEntryHandle) { 63 | return name.equals(((MarkdownTOCEntryHandle) eh).name); 64 | } 65 | return false; 66 | } 67 | 68 | @Override 69 | public OffsetRange getOffsetRange(ParserResult pr) { 70 | return new OffsetRange(startIndex, endIndex); 71 | } 72 | 73 | @Override 74 | public int hashCode() { 75 | int hash = 7; 76 | hash = 53 * hash + (this.file != null ? this.file.hashCode() : 0); 77 | hash = 53 * hash + (this.name != null ? this.name.hashCode() : 0); 78 | return hash; 79 | } 80 | 81 | @Override 82 | public boolean equals(Object obj) { 83 | if (obj == null) { 84 | return false; 85 | } 86 | if (getClass() != obj.getClass()) { 87 | return false; 88 | } 89 | final MarkdownTOCEntryHandle other = (MarkdownTOCEntryHandle) obj; 90 | if (this.file != other.file && (this.file == null || !this.file.equals(other.file))) { 91 | return false; 92 | } 93 | if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { 94 | return false; 95 | } 96 | return true; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/csl/MarkdownTOCEntryItem.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.csl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.Set; 7 | import javax.swing.ImageIcon; 8 | import org.netbeans.modules.csl.api.ElementHandle; 9 | import org.netbeans.modules.csl.api.ElementKind; 10 | import org.netbeans.modules.csl.api.HtmlFormatter; 11 | import org.netbeans.modules.csl.api.Modifier; 12 | import org.netbeans.modules.csl.api.StructureItem; 13 | import org.openide.filesystems.FileObject; 14 | import org.pegdown.ast.HeaderNode; 15 | 16 | /** 17 | * 18 | * @author Holger 19 | */ 20 | public class MarkdownTOCEntryItem implements StructureItem { 21 | private final FileObject file; 22 | private final HeaderNode node; 23 | 24 | private final String name; 25 | 26 | private final String sortText; 27 | 28 | private final int endIndex; 29 | 30 | private final int startIndex; 31 | 32 | private final List nestedItems; 33 | 34 | public MarkdownTOCEntryItem(FileObject file, HeaderNode node, String sortText, int startIndex, int endIndex, 35 | List nestedItems) { 36 | this.file = file; 37 | this.node = node; 38 | this.sortText = sortText; 39 | this.endIndex = endIndex; 40 | this.nestedItems = new ArrayList(nestedItems); 41 | MarkdownInlineVisitor visitor = new MarkdownInlineVisitor(); 42 | node.accept(visitor); 43 | this.name = visitor.getPlainText(); 44 | this.startIndex = startIndex; 45 | } 46 | 47 | @Override 48 | public String getName() { 49 | return name; 50 | } 51 | 52 | @Override 53 | public String getSortText() { 54 | return sortText; 55 | } 56 | 57 | @Override 58 | public String getHtml(HtmlFormatter formatter) { 59 | // TODO: Format embedded links or other markdown? 60 | formatter.appendText(getName()); 61 | return formatter.getText(); 62 | } 63 | 64 | @Override 65 | public ElementHandle getElementHandle() { 66 | // TODO: This method should not return null! 67 | // return new MarkdownTOCEntryHandle(file, getName(), startIndex, endIndex); 68 | return null; 69 | } 70 | 71 | @Override 72 | public ElementKind getKind() { 73 | return ElementKind.TAG; 74 | } 75 | 76 | @Override 77 | public Set getModifiers() { 78 | return Collections.emptySet(); 79 | } 80 | 81 | @Override 82 | public boolean isLeaf() { 83 | return nestedItems.isEmpty(); 84 | } 85 | 86 | @Override 87 | public List getNestedItems() { 88 | return Collections.unmodifiableList(nestedItems); 89 | } 90 | 91 | @Override 92 | public long getPosition() { 93 | return startIndex; 94 | } 95 | 96 | @Override 97 | public long getEndPosition() { 98 | return endIndex; 99 | } 100 | 101 | @Override 102 | public ImageIcon getCustomIcon() { 103 | return null; 104 | } 105 | 106 | @Override 107 | public int hashCode() { 108 | int hash = 7; 109 | hash = 23 * hash + (this.file != null ? this.file.hashCode() : 0); 110 | hash = 23 * hash + (this.name != null ? this.name.hashCode() : 0); 111 | return hash; 112 | } 113 | 114 | @Override 115 | public boolean equals(Object obj) { 116 | if (obj == null) { 117 | return false; 118 | } 119 | if (getClass() != obj.getClass()) { 120 | return false; 121 | } 122 | final MarkdownTOCEntryItem other = (MarkdownTOCEntryItem) obj; 123 | if (this.file != other.file && (this.file == null || !this.file.equals(other.file))) { 124 | return false; 125 | } 126 | if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { 127 | return false; 128 | } 129 | return true; 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/csl/MarkdownTOCRootItem.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.csl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.Set; 7 | import javax.swing.ImageIcon; 8 | import org.netbeans.modules.csl.api.ElementHandle; 9 | import org.netbeans.modules.csl.api.ElementKind; 10 | import org.netbeans.modules.csl.api.HtmlFormatter; 11 | import org.netbeans.modules.csl.api.Modifier; 12 | import org.netbeans.modules.csl.api.StructureItem; 13 | import org.openide.filesystems.FileObject; 14 | import org.openide.util.NbBundle; 15 | import org.pegdown.ast.RootNode; 16 | 17 | /** 18 | * 19 | * @author Holger 20 | */ 21 | @NbBundle.Messages({ 22 | "TXT_MarkdownTOCRootItem=Contents" 23 | }) 24 | public class MarkdownTOCRootItem implements StructureItem { 25 | private final FileObject file; 26 | 27 | private final RootNode rootNode; 28 | 29 | private final List nestedItems; 30 | 31 | public MarkdownTOCRootItem(FileObject file, RootNode rootNode, List nestedItems) { 32 | this.file = file; 33 | this.rootNode = rootNode; 34 | this.nestedItems = new ArrayList(nestedItems); 35 | } 36 | 37 | @Override 38 | public String getName() { 39 | return Bundle.TXT_MarkdownTOCRootItem(); 40 | } 41 | 42 | @Override 43 | public String getSortText() { 44 | return "1Contents"; 45 | } 46 | 47 | @Override 48 | public String getHtml(HtmlFormatter formatter) { 49 | formatter.appendText(getName()); 50 | return formatter.getText(); 51 | } 52 | 53 | @Override 54 | public ElementHandle getElementHandle() { 55 | return null; 56 | } 57 | 58 | @Override 59 | public ElementKind getKind() { 60 | return ElementKind.PACKAGE; 61 | } 62 | 63 | @Override 64 | public Set getModifiers() { 65 | return Collections.emptySet(); 66 | } 67 | 68 | @Override 69 | public boolean isLeaf() { 70 | return nestedItems.isEmpty(); 71 | } 72 | 73 | @Override 74 | public List getNestedItems() { 75 | return Collections.unmodifiableList(nestedItems); 76 | } 77 | 78 | @Override 79 | public long getPosition() { 80 | return rootNode.getStartIndex(); 81 | } 82 | 83 | @Override 84 | public long getEndPosition() { 85 | return rootNode.getEndIndex(); 86 | } 87 | 88 | @Override 89 | public ImageIcon getCustomIcon() { 90 | return null; 91 | } 92 | 93 | @Override 94 | public int hashCode() { 95 | int hash = 7; 96 | hash = 83 * hash + (this.file != null ? this.file.hashCode() : 0); 97 | return hash; 98 | } 99 | 100 | @Override 101 | public boolean equals(Object obj) { 102 | if (obj == null) { 103 | return false; 104 | } 105 | if (getClass() != obj.getClass()) { 106 | return false; 107 | } 108 | final MarkdownTOCRootItem other = (MarkdownTOCRootItem) obj; 109 | if (this.file != other.file && (this.file == null || !this.file.equals(other.file))) { 110 | return false; 111 | } 112 | return true; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/highlighter/MarkdownToken.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.highlighter; 2 | 3 | public class MarkdownToken { 4 | 5 | private final MarkdownTokenId id; 6 | private final int startIndex; 7 | private final int endIndex; 8 | 9 | public MarkdownToken(MarkdownTokenId id, int startIndex, int endIndex) { 10 | this.id = id; 11 | this.startIndex = startIndex; 12 | this.endIndex = endIndex; 13 | } 14 | 15 | public MarkdownTokenId getId() { 16 | return id; 17 | } 18 | 19 | public int getStartIndex() { 20 | return startIndex; 21 | } 22 | 23 | public int getEndIndex() { 24 | return endIndex; 25 | } 26 | 27 | public int getLength() { 28 | return endIndex - startIndex; 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return id + "(" + getLength() + ")[" + startIndex + "-" + endIndex + "]"; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/highlighter/MarkdownTokenId.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.highlighter; 2 | 3 | import flow.netbeans.markdown.csl.MarkdownLanguageConfig; 4 | import java.util.Collection; 5 | import java.util.EnumSet; 6 | import org.netbeans.api.lexer.InputAttributes; 7 | import org.netbeans.api.lexer.Language; 8 | import org.netbeans.api.lexer.LanguagePath; 9 | import org.netbeans.api.lexer.Token; 10 | import org.netbeans.api.lexer.TokenId; 11 | import org.netbeans.spi.lexer.LanguageEmbedding; 12 | import org.netbeans.spi.lexer.LanguageHierarchy; 13 | import org.netbeans.spi.lexer.Lexer; 14 | import org.netbeans.spi.lexer.LexerRestartInfo; 15 | 16 | public enum MarkdownTokenId implements TokenId { 17 | 18 | ABBREVIATION, 19 | ANCHORLINK, 20 | AUTOLINK, 21 | BLOCKQUOTE, 22 | BULLETLIST, 23 | CODE, 24 | EMPH, 25 | EXPIMAGE, 26 | EXPLINK, 27 | HEADER1, 28 | HEADER2, 29 | HEADER3, 30 | HEADER4, 31 | HEADER5, 32 | HEADER6, 33 | HORIZONTALRULE, 34 | HTMLBLOCK, 35 | INLINEHTML, 36 | LISTITEM, 37 | MAILLINK, 38 | ORDEREDLIST, 39 | PLAIN, 40 | STRONG, 41 | TABLE, 42 | VERBATIM, 43 | WIKILINK, 44 | DEFINITION, 45 | DEFINITION_LIST, 46 | DEFINITION_TERM, 47 | REFERENCE, 48 | QUOTED, 49 | REF_IMAGE, 50 | REF_LINK, 51 | WHITESPACE, 52 | STRIKETHROUGH; 53 | 54 | private static final Language LANGUAGE = new LanguageHierarchy() { 55 | 56 | @Override 57 | protected Collection createTokenIds() { 58 | return EnumSet.allOf(MarkdownTokenId.class); 59 | } 60 | 61 | @Override 62 | protected Lexer createLexer(LexerRestartInfo info) { 63 | return MarkdownLexer.create(info); 64 | } 65 | 66 | @Override 67 | protected String mimeType() { 68 | return MarkdownLanguageConfig.MIME_TYPE; 69 | } 70 | 71 | @Override 72 | protected LanguageEmbedding embedding(Token token, LanguagePath languagePath, InputAttributes inputAttributes) { 73 | if ((token.id() == MarkdownTokenId.HTMLBLOCK) || (token.id() == MarkdownTokenId.INLINEHTML)) { 74 | Language htmlLanguage = Language.find("text/html"); 75 | if (htmlLanguage != null) { 76 | return LanguageEmbedding.create(htmlLanguage, 0, 0); 77 | } 78 | } 79 | return null; 80 | } 81 | }.language(); 82 | 83 | @Override 84 | public String primaryCategory() { 85 | return this.name().toLowerCase(); 86 | } 87 | 88 | public static Language language() { 89 | return LANGUAGE; 90 | } 91 | } -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/options/Bundle.properties: -------------------------------------------------------------------------------- 1 | MarkdownPanel.FENCED_CODE_BLOCKS.text=FENCED CODE BLOCKS 2 | MarkdownPanel.HTML_BLOCK_SUPPRESSION.text=HTML BLOCK SUPPRESSION 3 | MarkdownPanel.INLINE_HTML_SUPPRESSION.text=INLINE HTML SUPPRESSION 4 | MarkdownPanel.WIKILINKS.text=WIKILINKS 5 | MarkdownPanel.SMARTS.text=SMARTS 6 | MarkdownPanel.QUOTES.text=QUOTES 7 | MarkdownPanel.ABBREVIATIONS.text=ABBREVIATIONS 8 | MarkdownPanel.HARDWRAPS.text=HARDWRAPS 9 | MarkdownPanel.AUTOLINKS.text=AUTOLINKS 10 | MarkdownPanel.TABLES.text=TABLE 11 | MarkdownPanel.DEFINITION_LISTS.text=DEFINITION LISTS 12 | MarkdownPanel.jCheckBox1.text=jCheckBox1 13 | MarkdownPanel.SMARTS.toolTipText=Beautifies apostrophes, ellipses ("..." and ". . .") and dashes ("--" and "---") 14 | MarkdownPanel.QUOTES.toolTipText=Beautifies single quotes, double quotes and double angle quotes (\u00ab and \u00bb) 15 | MarkdownPanel.ABBREVIATIONS.toolTipText=Abbreviations in the way of PHP Markdown Extra. 16 | MarkdownPanel.HARDWRAPS.toolTipText=Alternative handling of newlines, see Github-flavoured-Markdown 17 | MarkdownPanel.AUTOLINKS.toolTipText=Plain (undelimited) autolinks the way Github-flavoured-Markdown implements them. 18 | MarkdownPanel.TABLES.toolTipText=Tables similar to MultiMarkdown (which is in turn like the PHP Markdown Extra tables, but with colspan support). 19 | MarkdownPanel.DEFINITION_LISTS.toolTipText=Definition lists in the way of PHP Markdown Extra. 20 | MarkdownPanel.FENCED_CODE_BLOCKS.toolTipText=Fenced Code Blocks in the way of PHP Markdown Extra or Github-flavoured-Markdown. 21 | MarkdownPanel.HTML_BLOCK_SUPPRESSION.toolTipText=Suppresses the output of HTML blocks. 22 | MarkdownPanel.INLINE_HTML_SUPPRESSION.toolTipText=Suppresses the output of inline HTML elements. 23 | MarkdownPanel.WIKILINKS.toolTipText=Support [[Wiki-style links]] with a customizable URL rendering logic. 24 | MarkdownPanel.HTML_TEMPLATE.text=\n\n\n\n\n{%CONTENT%}\n\n 25 | MarkdownPanel.HTML_EXPORT_PANEL.TabConstraints.tabTitle=HTML Export 26 | MarkdownPanel.EXTENSIONS_PANEL.TabConstraints.tabTitle=Extensions 27 | MarkdownPanel.HTML_PANEL_HEADER.text=Template for HTML Export or Preview 28 | MarkdownPanel.EXTENSIONS_PANEL_HEADER.text=Enable one or more of the following extensions over standard Markdown 29 | MarkdownPanel.STRIKETHROUGH.toolTipText=Support strikethroughs as supported in Pandoc and Github. 30 | MarkdownPanel.STRIKETHROUGH.text=STRIKETHROUGH 31 | MarkdownPanel.EXPORT_ON_SAVE.text_1=Export to HTML on save 32 | MarkdownPanel.FX_HTML_VIEW_ENABLED.text=Use JavaFX to display preview in editor 33 | MarkdownPanel.REMOVE_ORDERED_LIST_NUMBER.toolTipText=Number is also removed when white space is removed 34 | MarkdownPanel.REMOVE_ORDERED_LIST_NUMBER.text_1=Remove ordered list number 35 | MarkdownPanel.REORDER_ORDERED_LIST_NUMBER.toolTipText=Reorder ordered list number when number is added/removed 36 | MarkdownPanel.REORDER_ORDERED_LIST_NUMBER.text=Reorder ordered list number 37 | MarkdownPanel.REMOVE_EMPTY_LIST.toolTipText=If list is empty, it's removed when new line is inserted 38 | MarkdownPanel.REMOVE_EMPTY_LIST.text=Remove empty list 39 | MarkdownPanel.AUTO_ADDITION_LIST.toolTipText=Add operators(*, -, +, >) when new line is inserted 40 | MarkdownPanel.AUTO_ADDITION_LIST.text=Auto addition for lists and block quotes operator 41 | MarkdownPanel.TYPING_HOOKS.text_1=Auto operation for lists and quotes (+,*, -, 1., >) 42 | MarkdownPanel.SAVE_IN_SOURCE_DIR.text=Save in same folder as markdown file 43 | MarkdownPanel.VIEW_HTML_ON_SAVE.text=View Html On Save 44 | MarkdownPanel.MISC_PANEL.TabConstraints.tabTitle=Miscellaneous 45 | MarkdownPanel.USE_CUSTOM_PREVIEW_REFRESH_INTERVAL.text_1=Use custom preview refresh interval 46 | MarkdownPanel.CUSTOM_PREVIEW_REFRESH_INTERVAL_LBL.text=Preview refresh interval: 47 | MarkdownPanel.CUSTOM_PREVIEW_REFRESH_INTERVAL.toolTipText=Preview refresh interval, between 10 and 10,000 milliseconds (0.01 and 10.0 seconds) 48 | MarkdownPanel.CUSTOM_PREVIEW_REFRESH_INTERVAL_LBL_MS.text=ms 49 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/options/MarkdownOptionsPanelController.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.options; 2 | 3 | import java.beans.PropertyChangeListener; 4 | import java.beans.PropertyChangeSupport; 5 | import javax.swing.JComponent; 6 | import org.netbeans.spi.options.OptionsPanelController; 7 | import org.openide.util.HelpCtx; 8 | import org.openide.util.Lookup; 9 | 10 | @OptionsPanelController.SubRegistration( 11 | location = "Advanced", 12 | displayName = "#AdvancedOption_DisplayName_Markdown", 13 | keywords = "#AdvancedOption_Keywords_Markdown", 14 | keywordsCategory = "Advanced/Markdown") 15 | @org.openide.util.NbBundle.Messages({"AdvancedOption_DisplayName_Markdown=Markdown", "AdvancedOption_Keywords_Markdown=Markdown"}) 16 | public final class MarkdownOptionsPanelController extends OptionsPanelController { 17 | 18 | private MarkdownPanel panel; 19 | private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); 20 | private boolean changed; 21 | 22 | @Override 23 | public void update() { 24 | getPanel().load(); 25 | changed = false; 26 | } 27 | 28 | @Override 29 | public void applyChanges() { 30 | getPanel().store(); 31 | changed = false; 32 | } 33 | 34 | @Override 35 | public void cancel() { 36 | // need not do anything special, if no changes have been persisted yet 37 | } 38 | 39 | @Override 40 | public boolean isValid() { 41 | return getPanel().valid(); 42 | } 43 | 44 | @Override 45 | public boolean isChanged() { 46 | return changed; 47 | } 48 | 49 | @Override 50 | public HelpCtx getHelpCtx() { 51 | return null; // new HelpCtx("...ID") if you have a help set 52 | } 53 | 54 | @Override 55 | public JComponent getComponent(Lookup masterLookup) { 56 | return getPanel(); 57 | } 58 | 59 | @Override 60 | public void addPropertyChangeListener(PropertyChangeListener l) { 61 | pcs.addPropertyChangeListener(l); 62 | } 63 | 64 | @Override 65 | public void removePropertyChangeListener(PropertyChangeListener l) { 66 | pcs.removePropertyChangeListener(l); 67 | } 68 | 69 | private MarkdownPanel getPanel() { 70 | if (panel == null) { 71 | panel = new MarkdownPanel(this); 72 | } 73 | return panel; 74 | } 75 | 76 | void changed() { 77 | if (!changed) { 78 | changed = true; 79 | pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true); 80 | } 81 | pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null); 82 | } 83 | } -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/package-info.java: -------------------------------------------------------------------------------- 1 | @org.netbeans.api.templates.TemplateRegistration( 2 | content = "resources/MarkdownTemplate.md", 3 | displayName = "flow.netbeans.markdown.resources.Bundle#Templates/Other/MarkdownTemplate.md", 4 | description = "resources/MarkdownTemplateDescription.html", 5 | folder = "Other", 6 | requireProject = false 7 | ) 8 | package flow.netbeans.markdown; 9 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/preview/AbstractHtmlView.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.preview; 3 | 4 | import java.beans.PropertyChangeListener; 5 | import java.beans.PropertyChangeSupport; 6 | import java.net.MalformedURLException; 7 | import java.net.URL; 8 | import javax.swing.event.SwingPropertyChangeSupport; 9 | import org.netbeans.api.annotations.common.CheckForNull; 10 | import org.openide.awt.HtmlBrowser; 11 | 12 | /** 13 | * 14 | * @author Holger Stenger 15 | */ 16 | public abstract class AbstractHtmlView implements HtmlView { 17 | private final PropertyChangeSupport pcs; 18 | 19 | private String statusMessage; 20 | 21 | public AbstractHtmlView() { 22 | pcs = new SwingPropertyChangeSupport(this, true); 23 | statusMessage = null; 24 | } 25 | 26 | public void addPropertyChangeListener(PropertyChangeListener listener) { 27 | pcs.addPropertyChangeListener(listener); 28 | } 29 | 30 | public void removePropertyChangeListener(PropertyChangeListener listener) { 31 | pcs.removePropertyChangeListener(listener); 32 | } 33 | 34 | @Override 35 | @CheckForNull 36 | public String getStatusMessage() { 37 | return statusMessage; 38 | } 39 | 40 | protected void setStatusMessage(final String newValue) { 41 | final String oldValue = statusMessage; 42 | statusMessage = newValue; 43 | firePropertyChange(PROP_STATUS_MESSAGE, oldValue, newValue); 44 | } 45 | 46 | protected void firePropertyChange(final String propertyName, final Object oldValue, final Object newValue) { 47 | pcs.firePropertyChange(propertyName, oldValue, newValue); 48 | } 49 | 50 | protected void showURLExternal(final URL url) { 51 | HtmlBrowser.URLDisplayer.getDefault().showURLExternal(url); 52 | } 53 | 54 | protected void showURLExternal(final String url) { 55 | try { 56 | showURLExternal(new URL(url)); 57 | } 58 | catch (MalformedURLException ex) { 59 | //Exceptions.printStackTrace(ex); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/preview/HtmlView.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.preview; 3 | 4 | import java.beans.PropertyChangeListener; 5 | import javax.swing.JComponent; 6 | import org.netbeans.api.annotations.common.CheckForNull; 7 | 8 | /** 9 | * 10 | * @author Holger Stenger 11 | */ 12 | public interface HtmlView { 13 | static final String PROP_STATUS_MESSAGE = "StatusMessage"; 14 | 15 | void addPropertyChangeListener(PropertyChangeListener listener); 16 | 17 | void removePropertyChangeListener(PropertyChangeListener listener); 18 | 19 | JComponent getComponent(); 20 | 21 | void setContent(String content); 22 | 23 | boolean isHtmlFullySupported(); 24 | 25 | @CheckForNull 26 | String getStatusMessage(); 27 | } 28 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/preview/HtmlViewFactory.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.preview; 3 | 4 | import flow.netbeans.markdown.options.MarkdownGlobalOptions; 5 | import java.lang.reflect.Constructor; 6 | import java.lang.reflect.Method; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | 10 | /** 11 | * 12 | * @author Holger Stenger 13 | */ 14 | public class HtmlViewFactory { 15 | private static final Logger LOG = Logger.getLogger(HtmlViewFactory.class.getName()); 16 | 17 | public HtmlViewFactory() { 18 | } 19 | 20 | public HtmlView createHtmlView() { 21 | if (MarkdownGlobalOptions.getInstance().isFXHtmlViewEnabled()) { 22 | try { 23 | return createFXHtmlView(); 24 | } catch (UnsupportedOperationException ex) { 25 | LOG.log(Level.INFO, "Falling back to Swing implementation", ex); 26 | } 27 | } 28 | return createDefaultHtmlView(); 29 | } 30 | 31 | public HtmlView createDefaultHtmlView() { 32 | return new SwingHtmlView(); 33 | } 34 | 35 | private HtmlView createFXHtmlView() throws UnsupportedOperationException { 36 | ClassLoader cl = getClassLoader(); 37 | checkFXFeatures(cl); 38 | return createFXHtmlView(cl); 39 | } 40 | 41 | private ClassLoader getClassLoader() throws UnsupportedOperationException { 42 | return HtmlViewFactory.class.getClassLoader(); 43 | } 44 | 45 | private HtmlView createFXHtmlView(ClassLoader cl) throws UnsupportedOperationException { 46 | try { 47 | Class htmlViewClass = cl.loadClass("flow.netbeans.markdown.preview.ext.FXHtmlView"); 48 | Constructor htmlViewConstructor = htmlViewClass.getConstructor(); 49 | return (HtmlView) htmlViewConstructor.newInstance(); 50 | } 51 | catch (Throwable ex) { 52 | throw new UnsupportedOperationException(ex); 53 | } 54 | } 55 | 56 | public void checkFXFeatures(ClassLoader cl) throws UnsupportedOperationException { 57 | try { 58 | Class platformClass = cl.loadClass("javafx.application.Platform"); 59 | Method setImplicitExitMethod = platformClass.getMethod("setImplicitExit", boolean.class); 60 | Class jfxPanelClass = cl.loadClass("javafx.embed.swing.JFXPanel"); 61 | } 62 | catch (ClassNotFoundException ex) { 63 | throw new UnsupportedOperationException(ex); 64 | } 65 | catch (NoSuchMethodException ex) { 66 | throw new UnsupportedOperationException(ex); 67 | } 68 | catch (SecurityException ex) { 69 | throw new UnsupportedOperationException(ex); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/preview/SwingHtmlView.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.preview; 3 | 4 | import javax.swing.BorderFactory; 5 | import javax.swing.JComponent; 6 | import javax.swing.JScrollPane; 7 | import javax.swing.JTextPane; 8 | import javax.swing.event.HyperlinkEvent; 9 | import javax.swing.event.HyperlinkListener; 10 | 11 | /** 12 | * 13 | * @author Holger Stenger 14 | */ 15 | public class SwingHtmlView extends AbstractHtmlView { 16 | private final JTextPane textPane; 17 | 18 | private final JScrollPane scrollPane; 19 | 20 | public SwingHtmlView() { 21 | textPane = new JTextPane(); 22 | textPane.setContentType("text/html"); 23 | textPane.setEditable(false); 24 | textPane.addHyperlinkListener(new HyperlinkListener() { 25 | @Override 26 | public void hyperlinkUpdate(HyperlinkEvent e) { 27 | if (HyperlinkEvent.EventType.ENTERED.equals(e.getEventType())) { 28 | final String statusMessage = e.getDescription(); 29 | setStatusMessage(statusMessage); 30 | } else if (HyperlinkEvent.EventType.EXITED.equals(e.getEventType())) { 31 | setStatusMessage(null); 32 | } else if (HyperlinkEvent.EventType.ACTIVATED.equals(e.getEventType())) { 33 | if (e.getURL() != null) { 34 | showURLExternal(e.getURL()); 35 | } 36 | } 37 | } 38 | }); 39 | 40 | scrollPane = new JScrollPane(textPane); 41 | scrollPane.setBorder(BorderFactory.createEmptyBorder()); 42 | } 43 | 44 | @Override 45 | public JComponent getComponent() { 46 | return scrollPane; 47 | } 48 | 49 | @Override 50 | public void setContent(String content) { 51 | textPane.setText(content); 52 | } 53 | 54 | @Override 55 | public boolean isHtmlFullySupported() { 56 | return false; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/resources/Bundle.properties: -------------------------------------------------------------------------------- 1 | CTL_MarkdownAction=Markdown 2 | CTL_MarkdownTopComponent=Markdown Window 3 | HINT_MarkdownTopComponent=This is a Markdown window 4 | OpenIDE-Module-Display-Category=Languages Support 5 | OpenIDE-Module-Long-Description=\ 6 | A NetBeans IDE plugin which adds Markdown support. \ 7 | This plugin provides syntax highlighting, HTML preview and HTML export when editing a Markdown document.\n\n\ 8 | Please report issues and star the repository at:\n\nhttps://github.com/madflow/flow-netbeans-markdown 9 | OpenIDE-Module-Name=Markdown Support 10 | OpenIDE-Module-Short-Description=Markdown support for the NetBeans IDE 11 | Services/MIMEResolver/MarkdownResolver.xml=Markdown Files 12 | Templates/Other/MarkdownTemplate.md=Markdown file 13 | Editors/text/x-markdown=Markdown 14 | text/x-markdown=Markdown 15 | abbreviation=Abbreviation 16 | autolink=Autolink 17 | anchorlink=Anchor Link 18 | blockquote=Block Quote 19 | bulletlist=Bullet List 20 | code=Code 21 | definition=Definition 22 | definition_list=Definition List 23 | definition_term=Definition Term 24 | emph=Emphasized 25 | expimage=Inline Image 26 | explink=Inline Link 27 | header=Header 28 | header1=Header 1 29 | header2=Header 2 30 | header3=Header 3 31 | header4=Header 4 32 | header5=Header 5 33 | header6=Header 6 34 | horizontalrule=Horizontal Rule 35 | htmlblock=HTML Block 36 | image=Image 37 | inlinehtml=Inline HTML 38 | link=Link 39 | listitem=List Item 40 | maillink=Mail Link 41 | orderedlist=Ordered List 42 | plain=Plain Text 43 | quoted=Quoted 44 | ref_image=Reference Image 45 | ref_link=Reference Link 46 | reference=Reference 47 | strong=Strong 48 | table=Table 49 | verbatim=Verbatim 50 | whitespace=Whitespace 51 | wikilink=Wiki Link 52 | strikethrough=Strikethrough 53 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/resources/FontAndColors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/resources/MarkdownExample.md: -------------------------------------------------------------------------------- 1 | # First Level Header 2 | ## Second Level Header 3 | ### Third Level Header 4 | #### Fourth Level Header 5 | ##### Fifth Level Header 6 | ###### Sixth Level Header 7 | 8 | *Emphasis* and **strong emphasis** 9 | 10 | Inline `code` in a paragraph. 11 | 12 | > Blockquote 13 | 14 | [Link][1] or 15 | 16 | ![Image](http://www.example.com/favicon.png) 17 | 18 | public class Code { /* ... */ } 19 | 20 | * Item A 21 | * Item B 22 | 23 | 1. Item 1 24 | 1. Item 2 25 | 26 | [1]: http://daringfireball.net/projects/markdown/ "Markdown" 27 | 28 | # Extensions 29 | 30 | https://help.github.com/articles/github-flavored-markdown or user@example.com 31 | 32 | [[http://en.wikipedia.org/wiki/Markdown]] 33 | 34 | This | is 35 | ---- | ---- 36 | a | table 37 | 38 | ``` 39 | public class GitHubFencedCode {} 40 | ``` 41 | ~~~ 42 | public class PHPMarkdownExtraFencedCode {} 43 | ~~~ 44 | 45 | Definition list 46 | : A list of terms with one or more definition for each term 47 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/resources/MarkdownTemplate.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/src/flow/netbeans/markdown/resources/MarkdownTemplate.md -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/resources/MarkdownTemplateDescription.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Creates an empty Markdown file. You can edit the file in the IDE's Source Editor. 7 | 8 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/resources/action-export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/src/flow/netbeans/markdown/resources/action-export.png -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/resources/action-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/src/flow/netbeans/markdown/resources/action-view.png -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/resources/layer.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/resources/markdown-mark-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/src/flow/netbeans/markdown/resources/markdown-mark-16x16.png -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/resources/text-x-generic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madflow/flow-netbeans-markdown/69e00006c85e69c2a1e798a7bd5624af0e5aac59/src/flow/netbeans/markdown/resources/text-x-generic.png -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/spellchecker/MarkdownTokenListProvider.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.spellchecker; 2 | 3 | import flow.netbeans.markdown.csl.MarkdownLanguageConfig; 4 | import javax.swing.text.Document; 5 | import org.netbeans.api.editor.mimelookup.MimeRegistration; 6 | import org.netbeans.editor.BaseDocument; 7 | import org.netbeans.modules.spellchecker.spi.language.TokenList; 8 | import org.netbeans.modules.spellchecker.spi.language.TokenListProvider; 9 | 10 | /** 11 | * 12 | * @author Holger Stenger 13 | */ 14 | @MimeRegistration(mimeType = MarkdownLanguageConfig.MIME_TYPE, 15 | service = TokenListProvider.class, position = 1000) 16 | public class MarkdownTokenListProvider implements TokenListProvider { 17 | 18 | public MarkdownTokenListProvider() { 19 | } 20 | 21 | @Override 22 | public TokenList findTokenList(Document doc) { 23 | if (doc instanceof BaseDocument) { 24 | BaseDocument baseDoc = (BaseDocument) doc; 25 | final Object mimeType = baseDoc.getProperty("mimeType"); 26 | if (MarkdownLanguageConfig.MIME_TYPE.equals(mimeType)) { 27 | return new MarkdownTokenList(doc); 28 | } 29 | } 30 | return null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/typinghooks/MarkdownDeletedTextInterceptor.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.typinghooks; 2 | 3 | import flow.netbeans.markdown.csl.MarkdownLanguageConfig; 4 | import flow.netbeans.markdown.highlighter.MarkdownTokenId; 5 | import flow.netbeans.markdown.options.MarkdownGlobalOptions; 6 | import flow.netbeans.markdown.utils.MarkdownDocUtil; 7 | import javax.swing.text.BadLocationException; 8 | import javax.swing.text.Document; 9 | import org.netbeans.api.editor.mimelookup.MimePath; 10 | import org.netbeans.api.editor.mimelookup.MimeRegistration; 11 | import org.netbeans.api.lexer.Token; 12 | import org.netbeans.api.lexer.TokenSequence; 13 | import org.netbeans.spi.editor.typinghooks.DeletedTextInterceptor; 14 | 15 | /** 16 | * 17 | * @author junichi11 18 | */ 19 | public class MarkdownDeletedTextInterceptor implements DeletedTextInterceptor { 20 | 21 | @Override 22 | public boolean beforeRemove(Context context) throws BadLocationException { 23 | if (!isEnabled()) { 24 | return false; 25 | } 26 | 27 | char ch = context.getText().charAt(0); 28 | if (ch != '.' && ch != ' ') { // NOI18N 29 | return false; 30 | } 31 | Document document = context.getDocument(); 32 | int caretOffset = context.getOffset(); 33 | TokenSequence ts = MarkdownDocUtil.getTokenSequence(document); 34 | ts.move(caretOffset); 35 | if (ch == ' ') { // NOI18N 36 | ts.movePrevious(); 37 | Token token = ts.token(); 38 | if (caretOffset != ts.offset() + token.length()) { 39 | return false; 40 | } 41 | } else { 42 | ts.moveNext(); 43 | } 44 | 45 | Token token = ts.token(); 46 | if (token == null || token.id() != MarkdownTokenId.ORDEREDLIST) { 47 | return false; 48 | } 49 | 50 | String tokenText = token.text().toString(); 51 | // may text is ' ' 52 | if (tokenText.matches("\\d+\\.")) { // NOI18N 53 | return false; 54 | } 55 | 56 | // compute offset and length for removing 57 | int removeStartOffset = ts.offset(); 58 | int removeLength = tokenText.length(); 59 | if (ts.movePrevious()) { 60 | Token previousToken = ts.token(); 61 | if (previousToken != null) { 62 | String previousText = previousToken.text().toString(); 63 | int lastIndexOfNewLine = previousText.lastIndexOf('\n'); // NOI18N 64 | if (lastIndexOfNewLine != -1) { 65 | removeStartOffset = ts.offset() + lastIndexOfNewLine; 66 | int indent = previousToken.length() - lastIndexOfNewLine; 67 | removeLength = removeLength + indent; 68 | } 69 | } 70 | } 71 | 72 | // reorder 73 | OrderedListReorderer reorderer = new OrderedListReorderer(context.getComponent(), document, caretOffset); 74 | reorderer.reorder(false, removeStartOffset, removeLength); 75 | return true; 76 | } 77 | 78 | @Override 79 | public void remove(Context context) throws BadLocationException { 80 | } 81 | 82 | @Override 83 | public void afterRemove(Context context) throws BadLocationException { 84 | } 85 | 86 | @Override 87 | public void cancelled(Context context) { 88 | } 89 | 90 | private boolean isEnabled() { 91 | return MarkdownGlobalOptions.getInstance().isTypingHooks(); 92 | } 93 | 94 | @MimeRegistration(mimeType = MarkdownLanguageConfig.MIME_TYPE, service = DeletedTextInterceptor.Factory.class) 95 | public static class Factory implements DeletedTextInterceptor.Factory { 96 | 97 | @Override 98 | public DeletedTextInterceptor createDeletedTextInterceptor(MimePath mimePath) { 99 | return new MarkdownDeletedTextInterceptor(); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/flow/netbeans/markdown/utils/MarkdownDocUtil.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.utils; 2 | 3 | import flow.netbeans.markdown.highlighter.MarkdownTokenId; 4 | import javax.swing.text.AbstractDocument; 5 | import javax.swing.text.BadLocationException; 6 | import javax.swing.text.Document; 7 | import javax.swing.text.StyledDocument; 8 | import org.netbeans.api.lexer.TokenHierarchy; 9 | import org.netbeans.api.lexer.TokenSequence; 10 | import org.openide.text.NbDocument; 11 | import org.openide.util.Exceptions; 12 | 13 | /** 14 | * 15 | * @author junichi11 16 | */ 17 | public final class MarkdownDocUtil { 18 | 19 | private MarkdownDocUtil() { 20 | } 21 | 22 | /** 23 | * Get TokenSequence. 24 | * 25 | * @param document 26 | * @return TokenSequence 27 | */ 28 | public static TokenSequence getTokenSequence(Document document) { 29 | TokenHierarchy tokenHierarchy = TokenHierarchy.get(document); 30 | AbstractDocument ad = (AbstractDocument) document; 31 | ad.readLock(); 32 | TokenSequence ts; 33 | try { 34 | ts = tokenHierarchy.tokenSequence(MarkdownTokenId.language()); 35 | } finally { 36 | ad.readUnlock(); 37 | } 38 | return ts; 39 | } 40 | 41 | /** 42 | * Get indent string for caret offset position. 43 | * 44 | * @param document document 45 | * @param caretOffset caret offset 46 | * @return indent string if indent exists, empty string otherwise 47 | */ 48 | public static String getIndentString(Document document, int caretOffset) { 49 | String indentString = ""; // NOI18N 50 | if (document instanceof StyledDocument) { 51 | StyledDocument sd = (StyledDocument) document; 52 | int lineNumber = NbDocument.findLineNumber(sd, caretOffset); 53 | int lineOffset = NbDocument.findLineOffset(sd, lineNumber); 54 | try { 55 | String currentLine = document.getText(lineOffset, caretOffset - lineOffset); 56 | for (int i = 0; i < currentLine.length(); i++) { 57 | char ch = currentLine.charAt(i); 58 | if (ch != ' ' && ch != '\t') { // NOI18N 59 | break; 60 | } 61 | indentString = indentString + ch; 62 | } 63 | } catch (BadLocationException ex) { 64 | Exceptions.printStackTrace(ex); 65 | } 66 | } 67 | return indentString; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Backslash_escapes.html: -------------------------------------------------------------------------------- 1 |

Tricky combinaisons:

2 | 3 |

backslash with -- two dashes

4 | 5 |

backslash with > greater than

6 | 7 |

[test](not a link)

8 | 9 |

*no emphasis*

10 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Backslash_escapes.md: -------------------------------------------------------------------------------- 1 | Tricky combinaisons: 2 | 3 | backslash with \-- two dashes 4 | 5 | backslash with \> greater than 6 | 7 | \[test](not a link) 8 | 9 | \*no emphasis* -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Code_Spans.html: -------------------------------------------------------------------------------- 1 |

From <!-- to --> 2 | on two lines.

3 | 4 |

From <!-- 5 | to --> 6 | on three lines.

7 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Code_Spans.md: -------------------------------------------------------------------------------- 1 | From `` 2 | on two lines. 3 | 4 | From `` 6 | on three lines. 7 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Code_block_in_a_list_item.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • List Item:

    3 | 4 |
    code block
     5 | 
     6 | with a blank line
     7 | 
    8 | 9 |

    within a list item.

  • 10 |
-------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Code_block_in_a_list_item.md: -------------------------------------------------------------------------------- 1 | 2 | * List Item: 3 | 4 | code block 5 | 6 | with a blank line 7 | 8 | within a list item. -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Email_auto_links.html: -------------------------------------------------------------------------------- 1 |

michel.fortin@michelf.com

2 | 3 |

International domain names: help@tūdaliņ.lv

4 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Email_auto_links.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | International domain names: -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Emphasis.html: -------------------------------------------------------------------------------- 1 |

Combined emphasis:

2 | 3 |
    4 |
  1. test test
  2. 5 |
  3. test test
  4. 6 |
  5. test test
  6. 7 |
  7. test test
  8. 8 |
  9. test test
  10. 9 |
  11. test test
  12. 10 |
  13. test test
  14. 11 |
  15. test test
  16. 12 |
  17. test test
  18. 13 |
  19. test test
  20. 14 |
  21. test test
  22. 15 |
  23. test test
  24. 16 |
  25. test test
  26. 17 |
  27. test test
  28. 18 |
  29. test test
  30. 19 |
  31. test test
  32. 20 |
21 | 22 |

Incorrect nesting:

23 | 24 |
    25 |
  1. *test test* test
  2. 26 |
  3. _test test_ test
  4. 27 |
  5. **test test* test*
  6. 28 |
  7. __test test_ test_
  8. 29 |
  9. test *test test*
  10. 30 |
  11. test _test test_
  12. 31 |
  13. test test test
  14. 32 |
  15. test test test
  16. 33 |
34 | 35 |

No emphasis:

36 | 37 |
    38 |
  1. test* test *test
  2. 39 |
  3. test** test **test
  4. 40 |
  5. test_ test _test
  6. 41 |
  7. test__ test __test
  8. 42 |
43 | 44 |

Middle-word emphasis (asterisks):

45 | 46 |
    47 |
  1. ab
  2. 48 |
  3. ab
  4. 49 |
  5. abc
  6. 50 |
  7. ab
  8. 51 |
  9. ab
  10. 52 |
  11. abc
  12. 53 |
54 | 55 |

Middle-word emphasis (underscore):

56 | 57 |
    58 |
  1. ab
  2. 59 |
  3. ab
  4. 60 |
  5. abc
  6. 61 |
  7. ab
  8. 62 |
  9. ab
  10. 63 |
  11. abc
  12. 64 |
65 | 66 |

mypreciousfile.txt

67 | 68 |

Tricky Cases

69 | 70 |

E**. Test TestTestTest

71 | 72 |

E**. Test Test Test Test

73 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Emphasis.md: -------------------------------------------------------------------------------- 1 | Combined emphasis: 2 | 3 | 1. ***test test*** 4 | 2. ___test test___ 5 | 3. *test **test*** 6 | 4. **test *test*** 7 | 5. ***test* test** 8 | 6. ***test** test* 9 | 7. ***test* test** 10 | 8. **test *test*** 11 | 9. *test **test*** 12 | 10. _test __test___ 13 | 11. __test _test___ 14 | 12. ___test_ test__ 15 | 13. ___test__ test_ 16 | 14. ___test_ test__ 17 | 15. __test _test___ 18 | 16. _test __test___ 19 | 20 | 21 | Incorrect nesting: 22 | 23 | 1. *test **test* test** 24 | 2. _test __test_ test__ 25 | 3. **test *test** test* 26 | 4. __test _test__ test_ 27 | 5. *test *test* test* 28 | 6. _test _test_ test_ 29 | 7. **test **test** test** 30 | 8. __test __test__ test__ 31 | 32 | 33 | 34 | No emphasis: 35 | 36 | 1. test* test *test 37 | 2. test** test **test 38 | 3. test_ test _test 39 | 4. test__ test __test 40 | 41 | 42 | 43 | Middle-word emphasis (asterisks): 44 | 45 | 1. *a*b 46 | 2. a*b* 47 | 3. a*b*c 48 | 4. **a**b 49 | 5. a**b** 50 | 6. a**b**c 51 | 52 | 53 | Middle-word emphasis (underscore): 54 | 55 | 1. _a_b 56 | 2. a_b_ 57 | 3. a_b_c 58 | 4. __a__b 59 | 5. a__b__ 60 | 6. a__b__c 61 | 62 | my_precious_file.txt 63 | 64 | 65 | ## Tricky Cases 66 | 67 | E**. **Test** TestTestTest 68 | 69 | E**. **Test** Test Test Test 70 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Headers.html: -------------------------------------------------------------------------------- 1 |

Header

2 | 3 |

Header

4 | 5 |

Header

6 | 7 |
8 | 9 |

Header

10 | 11 |

Paragraph

12 | 13 |

Header

14 | 15 |

Paragraph

16 | 17 |

Header

18 | 19 |

Paragraph

20 | 21 |
22 | 23 |

Paragraph

24 | 25 |

Header

26 | 27 |

Paragraph

28 | 29 |

Paragraph

30 | 31 |

Header

32 | 33 |

Paragraph

34 | 35 |

Paragraph

36 | 37 |

Header

38 | 39 |

Paragraph

40 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Headers.md: -------------------------------------------------------------------------------- 1 | Header ====== Header ------ ### Header - - - Header ====== Paragraph Header ------ Paragraph ### Header Paragraph - - - Paragraph Header ====== Paragraph Paragraph Header ------ Paragraph Paragraph ### Header Paragraph -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Horizontal_Rules.html: -------------------------------------------------------------------------------- 1 |

Horizontal rules:

2 | 3 |
4 | 5 |
6 | 7 |
8 | 9 |
10 | 11 |
12 | 13 |

Not horizontal rules (testing for a bug in 1.0.1j):

14 | 15 |

+++

16 | 17 |

,,,

18 | 19 |

===

20 | 21 |

???

22 | 23 |

AAA

24 | 25 |

jjj

26 | 27 |

j j j

28 | 29 |

n n n

30 | 31 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Horizontal_Rules.md: -------------------------------------------------------------------------------- 1 | Horizontal rules: 2 | 3 | - - - 4 | 5 | * * * 6 | 7 | *** 8 | 9 | --- 10 | 11 | ___ 12 | 13 | Not horizontal rules (testing for a bug in 1.0.1j): 14 | 15 | +++ 16 | 17 | ,,, 18 | 19 | === 20 | 21 | ??? 22 | 23 | AAA 24 | 25 | jjj 26 | 27 | j j j 28 | 29 | n n n 30 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Inline_HTML_(Simple).html: -------------------------------------------------------------------------------- 1 |

With some attributes:

2 | 3 |
4 | foo 5 |
6 | 7 |
9 | foo 10 |
11 | 12 |

Hr's:

13 | 14 |
-------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Inline_HTML_(Simple).md: -------------------------------------------------------------------------------- 1 | With some attributes: 2 | 3 |
4 | foo 5 |
6 | 7 |
9 | foo 10 |
11 | 12 | Hr's: 13 | 14 |
16 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Inline_HTML_(Span).html: -------------------------------------------------------------------------------- 1 |

ACINACS

2 | 3 |

SB 4 | SB

-------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Inline_HTML_(Span).md: -------------------------------------------------------------------------------- 1 | ACINACS 2 | 3 | SB 4 | SB -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Inline_HTML_comments.html: -------------------------------------------------------------------------------- 1 |

Paragraph one.

2 | 3 | 4 | 5 |

Paragraph two.

6 | 7 | 8 | 9 |

The end.

10 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Inline_HTML_comments.md: -------------------------------------------------------------------------------- 1 | Paragraph one. 2 | 3 | 4 | 5 | Paragraph two. 6 | 7 | 8 | 9 | The end. 10 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Ins_and_del.html: -------------------------------------------------------------------------------- 1 |

Here is a block tag ins:

2 | 3 | 4 |

Some text

5 |
6 | 7 |

And here it is inside a paragraph.

8 | 9 |

And here it is in the middle of a paragraph.

10 | 11 | 12 |

Some text

13 |
14 | 15 |

And here is ins as a paragraph.

16 | 17 |

And here it is in the middle of a paragraph.

18 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Ins_and_del.md: -------------------------------------------------------------------------------- 1 | Here is a block tag ins: 2 | 3 | 4 |

Some text

5 |
6 | 7 | And here it is inside a paragraph. 8 | 9 | And here it is in the middle of a paragraph. 10 | 11 | 12 |

Some text

13 |
14 | 15 | And here is ins as a paragraph. 16 | 17 | And here it is in the middle of a paragraph. 18 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Links_inline_style.html: -------------------------------------------------------------------------------- 1 |

silly URL w/ angle brackets.

2 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Links_inline_style.md: -------------------------------------------------------------------------------- 1 | [silly URL w/ angle brackets](). 2 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/MD5_Hashes.html: -------------------------------------------------------------------------------- 1 |

Character Escapes

2 | 3 |

The MD5 value for + is "26b17225b626fb9238849fd60eabdf60".

4 | 5 |

HTML Blocks

6 | 7 |

test

8 | 9 |

The MD5 value for <p>test</p> is:

10 | 11 |

6205333b793f34273d75379350b36826

12 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/MD5_Hashes.md: -------------------------------------------------------------------------------- 1 | # Character Escapes 2 | 3 | The MD5 value for `+` is "26b17225b626fb9238849fd60eabdf60". 4 | 5 | # HTML Blocks 6 | 7 |

test

8 | 9 | The MD5 value for `

test

` is: 10 | 11 | 6205333b793f34273d75379350b36826 -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Nesting.html: -------------------------------------------------------------------------------- 1 |

Valid nesting:

2 | 3 |

Link

4 | 5 |

Link

6 | 7 |

Link

8 | 9 |

Invalid nesting:

10 | 11 |
12 | 
13 | #commented out
14 | [[Link](url)](url)
15 | 
16 | 
17 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Nesting.md: -------------------------------------------------------------------------------- 1 | Valid nesting: 2 | 3 | **[Link](url)** 4 | 5 | [**Link**](url) 6 | 7 | **[**Link**](url)** 8 | 9 | Invalid nesting: 10 | 11 | #commented out 12 | [[Link](url)](url) -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/PHP-Specific_Bugs.html: -------------------------------------------------------------------------------- 1 |

This tests for a bug where quotes escaped by PHP when using 2 | preg_replace with the /e modifier must be correctly unescaped 3 | (hence the _UnslashQuotes function found only in PHP Markdown).

4 | 5 |

Headers below should appear exactly as they are typed (no backslash 6 | added or removed).

7 | 8 |

Header "quoted\" again \""

9 | 10 |

Header "quoted\" again \""

11 | 12 |

Header "quoted\" again \""

13 | 14 |

Test with tabs for _Detab:

15 | 16 |
Code    'block' with    some    "tabs"  and "quotes"
17 | 
18 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/PHP-Specific_Bugs.md: -------------------------------------------------------------------------------- 1 | This tests for a bug where quotes escaped by PHP when using 2 | `preg_replace` with the `/e` modifier must be correctly unescaped 3 | (hence the `_UnslashQuotes` function found only in PHP Markdown). 4 | 5 | 6 | 7 | Headers below should appear exactly as they are typed (no backslash 8 | added or removed). 9 | 10 | Header "quoted\" again \\"" 11 | =========================== 12 | 13 | Header "quoted\" again \\"" 14 | --------------------------- 15 | 16 | ### Header "quoted\" again \\"" ### 17 | 18 | 19 | 20 | Test with tabs for `_Detab`: 21 | 22 | Code 'block' with some "tabs" and "quotes" 23 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Parens_in_URL.html: -------------------------------------------------------------------------------- 1 |

Inline link 1 with parens.

2 | 3 |

Inline link 2 with parens.

4 | 5 |

Inline link 3 with non-escaped parens.

6 | 7 |

Inline link 4 with non-escaped parens.

8 | 9 |

Reference link 1 with parens.

10 | 11 |

Reference link 2 with parens.

-------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Parens_in_URL.md: -------------------------------------------------------------------------------- 1 | [Inline link 1 with parens](/url\(test\) "title"). 2 | 3 | [Inline link 2 with parens]( "title"). 4 | 5 | [Inline link 3 with non-escaped parens](/url(test) "title"). 6 | 7 | [Inline link 4 with non-escaped parens]( "title"). 8 | 9 | [Reference link 1 with parens][1]. 10 | 11 | [Reference link 2 with parens][2]. 12 | 13 | [1]: /url(test) "title" 14 | [2]: "title" 15 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Tight_blocks.html: -------------------------------------------------------------------------------- 1 |

Paragraph and no space: 2 | * ciao

3 | 4 |

Paragraph and 1 space: 5 | * ciao

6 | 7 |

Paragraph and 3 spaces: 8 | * ciao

9 | 10 |

Paragraph and 4 spaces: 11 | * ciao

12 | 13 |

Paragraph before header:

14 | 15 |

Header

16 | 17 |

Paragraph before blockquote:

18 | 19 |
20 |

Some quote.

21 |
22 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdown/Tight_blocks.md: -------------------------------------------------------------------------------- 1 | Paragraph and no space: * ciao Paragraph and 1 space: * ciao Paragraph and 3 spaces: * ciao Paragraph and 4 spaces: * ciao Paragraph before header: #Header Paragraph before blockquote: >Some quote. -------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Abbr.html: -------------------------------------------------------------------------------- 1 |

Some text about HTML, SGML and HTML4.

2 | 3 |

Let's talk about the U.S.A., (É.U. or É.-U. d'A. in French).

4 | 5 |

And here we have a CD, some CDs, and some other CD's.

6 | 7 |

Let's transfert documents through TCP/IP, using TCP packets.

8 | 9 |
10 | 11 |

Bienvenue sur CMS.

12 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Abbr.md: -------------------------------------------------------------------------------- 1 | Some text about HTML, SGML and HTML4. 2 | 3 | Let's talk about the U.S.A., (É.U. or É.-U. d'A. in French). 4 | 5 | *[HTML4]: Hyper Text Markup Language version 4 6 | *[HTML]: Hyper Text Markup Language 7 | *[SGML]: Standard Generalized Markup Language 8 | *[U.S.A.]: United States of America 9 | *[É.U.] : États-Unis d'Amérique 10 | *[É.-U. d'A.] : États-Unis d'Amérique 11 | 12 | And here we have a CD, some CDs, and some other CD's. 13 | 14 | *[CD]: Compact Disk 15 | 16 | Let's transfert documents through TCP/IP, using TCP packets. 17 | 18 | *[IP]: Internet Protocol 19 | *[TCP]: Transmission Control Protocol 20 | 21 | --- 22 | 23 | Bienvenue sur [CMS](http://www.bidulecms.com "Bidule CMS"). 24 | 25 | *[CMS]: Content Management System -------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Definition_Lists.html: -------------------------------------------------------------------------------- 1 |

A simple definition list:

2 | 3 |
4 |
Term 1
5 |
Definition 1
6 | 7 |
Term 2
8 |
Definition 2
9 |
10 | 11 |

With multiple terms:

12 | 13 |
14 |
Term 1
15 |
Term 2
16 |
Definition 1
17 | 18 |
Term 3
19 |
Term 4
20 |
Definition 2
21 |
22 | 23 |

With multiple definitions:

24 | 25 |
26 |
Term 1
27 |
Definition 1
28 | 29 |
Definition 2
30 | 31 |
Term 2
32 |
Definition 3
33 | 34 |
Definition 4
35 |
36 | 37 |

With multiple lines per definition:

38 | 39 |
40 |
Term 1
41 |
Definition 1 line 1 ... 42 | Definition 1 line 2
43 | 44 |
Definition 2 line 1 ... 45 | Definition 2 line 2
46 | 47 |
Term 2
48 |
Definition 3 line 2 ... 49 | Definition 3 line 2
50 | 51 |
Definition 4 line 2 ... 52 | Definition 4 line 2
53 |
54 | 55 |

With paragraphs:

56 | 57 |
58 |
Term 1
59 |
60 |

Definition 1 (paragraph)

61 |
62 | 63 |
Term 2
64 |
65 |

Definition 2 (paragraph)

66 |
67 |
68 | 69 |

With multiple paragraphs:

70 | 71 |
72 |
Term 1
73 |
74 |

Definition 1 paragraph 1 line 1 ... 75 | Definition 1 paragraph 1 line 2

76 | 77 |

Definition 1 paragraph 2 line 1 ... 78 | Definition 1 paragraph 2 line 2

79 |
80 | 81 |
Term 2
82 |
83 |

Definition 1 paragraph 1 line 1 ... 84 | Definition 1 paragraph 1 line 2 (lazy)

85 | 86 |

Definition 1 paragraph 2 line 1 ... 87 | Definition 1 paragraph 2 line 2 (lazy)

88 |
89 |
90 | 91 |
92 | 93 |

A mix:

94 | 95 |
96 |
Term 1
97 |
Term 2
98 |
99 |

Definition 1 paragraph 1 line 1 ... 100 | Definition 1 paragraph 1 line 2 (lazy)

101 | 102 |

Definition 1 paragraph 2 line 1 ... 103 | Definition 1 paragraph 2 line 2

104 |
105 | 106 |
107 |

Definition 2 paragraph 1 line 1 ... 108 | Definition 2 paragraph 1 line 2 (lazy)

109 |
110 | 111 |
Term 3
112 |
Definition 3 (no paragraph)
113 | 114 |
Definition 4 (no paragraph)
115 | 116 |
Definition 5 line 1 ... 117 | Definition 5 line 2 (no paragraph)
118 | 119 |
120 |

Definition 6 paragraph 1 line 1 ... 121 | Definition 6 paragraph 1 line 2

122 |
123 | 124 |
Definition 7 (no paragraph)
125 | 126 |
127 |

Definition 8 paragraph 1 line 1 (forced paragraph) ... 128 | Definition 8 paragraph 1 line 2

129 | 130 |

Definition 8 paragraph 2 line 1

131 |
132 | 133 |
Term 4
134 |
135 |

Definition 9 paragraph 1 line 1 (forced paragraph) ... 136 | Definition 9 paragraph 1 line 2

137 | 138 |

Definition 9 paragraph 2 line 1

139 |
140 | 141 |
Definition 10 (no paragraph)
142 |
143 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Definition_Lists.md: -------------------------------------------------------------------------------- 1 | A simple definition list: 2 | 3 | Term 1 4 | : Definition 1 5 | 6 | Term 2 7 | : Definition 2 8 | 9 | With multiple terms: 10 | 11 | Term 1 12 | Term 2 13 | : Definition 1 14 | 15 | Term 3 16 | Term 4 17 | : Definition 2 18 | 19 | With multiple definitions: 20 | 21 | Term 1 22 | : Definition 1 23 | : Definition 2 24 | 25 | Term 2 26 | : Definition 3 27 | : Definition 4 28 | 29 | With multiple lines per definition: 30 | 31 | Term 1 32 | : Definition 1 line 1 ... 33 | Definition 1 line 2 34 | : Definition 2 line 1 ... 35 | Definition 2 line 2 36 | 37 | Term 2 38 | : Definition 3 line 2 ... 39 | Definition 3 line 2 40 | : Definition 4 line 2 ... 41 | Definition 4 line 2 42 | 43 | With paragraphs: 44 | 45 | Term 1 46 | 47 | : Definition 1 (paragraph) 48 | 49 | Term 2 50 | 51 | : Definition 2 (paragraph) 52 | 53 | With multiple paragraphs: 54 | 55 | Term 1 56 | 57 | : Definition 1 paragraph 1 line 1 ... 58 | Definition 1 paragraph 1 line 2 59 | 60 | Definition 1 paragraph 2 line 1 ... 61 | Definition 1 paragraph 2 line 2 62 | 63 | Term 2 64 | 65 | : Definition 1 paragraph 1 line 1 ... 66 | Definition 1 paragraph 1 line 2 (lazy) 67 | 68 | Definition 1 paragraph 2 line 1 ... 69 | Definition 1 paragraph 2 line 2 (lazy) 70 | 71 | * * * 72 | 73 | A mix: 74 | 75 | Term 1 76 | Term 2 77 | 78 | : Definition 1 paragraph 1 line 1 ... 79 | Definition 1 paragraph 1 line 2 (lazy) 80 | 81 | Definition 1 paragraph 2 line 1 ... 82 | Definition 1 paragraph 2 line 2 83 | 84 | : Definition 2 paragraph 1 line 1 ... 85 | Definition 2 paragraph 1 line 2 (lazy) 86 | 87 | Term 3 88 | : Definition 3 (no paragraph) 89 | : Definition 4 (no paragraph) 90 | : Definition 5 line 1 ... 91 | Definition 5 line 2 (no paragraph) 92 | 93 | : Definition 6 paragraph 1 line 1 ... 94 | Definition 6 paragraph 1 line 2 95 | : Definition 7 (no paragraph) 96 | : Definition 8 paragraph 1 line 1 (forced paragraph) ... 97 | Definition 8 paragraph 1 line 2 98 | 99 | Definition 8 paragraph 2 line 1 100 | 101 | Term 4 102 | : Definition 9 paragraph 1 line 1 (forced paragraph) ... 103 | Definition 9 paragraph 1 line 2 104 | 105 | Definition 9 paragraph 2 line 1 106 | : Definition 10 (no paragraph) -------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Emphasis.html: -------------------------------------------------------------------------------- 1 |

Combined emphasis:

2 | 3 |
    4 |
  1. test test
  2. 5 |
  3. test test
  4. 6 |
  5. test test
  6. 7 |
  7. test test
  8. 8 |
  9. test test
  10. 9 |
  11. test test
  12. 10 |
  13. test test
  14. 11 |
  15. test test
  16. 12 |
  17. test test
  18. 13 |
  19. test test
  20. 14 |
  21. test test
  22. 15 |
  23. test test
  24. 16 |
  25. test test
  26. 17 |
  27. test test
  28. 18 |
  29. test test
  30. 19 |
  31. test test
  32. 20 |
21 | 22 |

Incorrect nesting:

23 | 24 |
    25 |
  1. *test test* test
  2. 26 |
  3. _test test_ test
  4. 27 |
  5. **test test* test*
  6. 28 |
  7. __test test_ test_
  8. 29 |
  9. test *test test*
  10. 30 |
  11. test _test test_
  12. 31 |
  13. test test test
  14. 32 |
  15. test test test
  16. 33 |
34 | 35 |

No emphasis:

36 | 37 |
    38 |
  1. test* test *test
  2. 39 |
  3. test** test **test
  4. 40 |
  5. test_ test _test
  6. 41 |
  7. test__ test __test
  8. 42 |
43 | 44 |

Middle-word emphasis (asterisks):

45 | 46 |
    47 |
  1. ab
  2. 48 |
  3. ab
  4. 49 |
  5. abc
  6. 50 |
  7. ab
  8. 51 |
  9. ab
  10. 52 |
  11. abc
  12. 53 |
54 | 55 |

Middle-word emphasis (underscore):

56 | 57 |
    58 |
  1. _a_b
  2. 59 |
  3. a_b_
  4. 60 |
  5. a_b_c
  6. 61 |
  7. __a__b
  8. 62 |
  9. a__b__
  10. 63 |
  11. a__b__c
  12. 64 |
65 | 66 |

my_precious_file.txt

67 | 68 |

Tricky Cases

69 | 70 |

E**. Test TestTestTest

71 | 72 |

E**. Test Test Test Test

73 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Emphasis.md: -------------------------------------------------------------------------------- 1 | Combined emphasis: 2 | 3 | 1. ***test test*** 4 | 2. ___test test___ 5 | 3. *test **test*** 6 | 4. **test *test*** 7 | 5. ***test* test** 8 | 6. ***test** test* 9 | 7. ***test* test** 10 | 8. **test *test*** 11 | 9. *test **test*** 12 | 10. _test __test___ 13 | 11. __test _test___ 14 | 12. ___test_ test__ 15 | 13. ___test__ test_ 16 | 14. ___test_ test__ 17 | 15. __test _test___ 18 | 16. _test __test___ 19 | 20 | 21 | Incorrect nesting: 22 | 23 | 1. *test **test* test** 24 | 2. _test __test_ test__ 25 | 3. **test *test** test* 26 | 4. __test _test__ test_ 27 | 5. *test *test* test* 28 | 6. _test _test_ test_ 29 | 7. **test **test** test** 30 | 8. __test __test__ test__ 31 | 32 | 33 | 34 | No emphasis: 35 | 36 | 1. test* test *test 37 | 2. test** test **test 38 | 3. test_ test _test 39 | 4. test__ test __test 40 | 41 | 42 | 43 | Middle-word emphasis (asterisks): 44 | 45 | 1. *a*b 46 | 2. a*b* 47 | 3. a*b*c 48 | 4. **a**b 49 | 5. a**b** 50 | 6. a**b**c 51 | 52 | 53 | Middle-word emphasis (underscore): 54 | 55 | 1. _a_b 56 | 2. a_b_ 57 | 3. a_b_c 58 | 4. __a__b 59 | 5. a__b__ 60 | 6. a__b__c 61 | 62 | my_precious_file.txt 63 | 64 | 65 | ## Tricky Cases 66 | 67 | E**. **Test** TestTestTest 68 | 69 | E**. **Test** Test Test Test 70 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Fenced_Code_Blocks.html: -------------------------------------------------------------------------------- 1 |
Fenced
 2 | 
3 | 4 |

Code block starting and ending with empty lines:

5 | 6 |


Fenced 7 | 8 | 9 |
10 | 11 |

Indented code block containing fenced code block sample:

12 | 13 |
~~~
14 | Fenced
15 | ~~~
16 | 
17 | 18 |

Fenced code block with indented code block sample:

19 | 20 |
Some text
21 | 
22 |     Indented code block sample code
23 | 
24 | 25 |

Fenced code block with long markers:

26 | 27 |
Fenced
28 | 
29 | 30 |

Empty Fenced code block:

31 |

~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~

32 | 33 |

Fenced code block with fenced code block markers of different length in it:

34 | 35 |
In code block
36 | ~~~
37 | Still in code block
38 | ~~~~~
39 | Still in code block
40 | 
41 | 42 |

Fenced code block with Markdown header and horizontal rule:

43 | 44 |
#test
45 | ---
46 | 
47 | 48 |

Fenced code block with link definitions, footnote definition and 49 | abbreviation definitions:

50 | 51 |
[example]: http://example.com/
52 | 
53 | [^1]: Footnote def
54 | 
55 | *[HTML]: HyperText Markup Language
56 | 
57 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Fenced_Code_Blocks.md: -------------------------------------------------------------------------------- 1 | ~~~ 2 | Fenced 3 | ~~~ 4 | 5 | Code block starting and ending with empty lines: 6 | 7 | ~~~ 8 | 9 | 10 | Fenced 11 | 12 | 13 | ~~~ 14 | 15 | Indented code block containing fenced code block sample: 16 | 17 | ~~~ 18 | Fenced 19 | ~~~ 20 | 21 | Fenced code block with indented code block sample: 22 | 23 | ~~~ 24 | Some text 25 | 26 | Indented code block sample code 27 | ~~~ 28 | 29 | Fenced code block with long markers: 30 | 31 | ~~~~~~~~~~~~~~~~~~ 32 | Fenced 33 | ~~~~~~~~~~~~~~~~~~ 34 | 35 | Empty Fenced code block: 36 | 37 | ~~~~~~~~~~~~~~~~~~ 38 | ~~~~~~~~~~~~~~~~~~ 39 | 40 | Fenced code block with fenced code block markers of different length in it: 41 | 42 | ~~~~ 43 | In code block 44 | ~~~ 45 | Still in code block 46 | ~~~~~ 47 | Still in code block 48 | ~~~~ 49 | 50 | Fenced code block with Markdown header and horizontal rule: 51 | 52 | ~~~ 53 | #test 54 | --- 55 | ~~~ 56 | 57 | Fenced code block with link definitions, footnote definition and 58 | abbreviation definitions: 59 | 60 | ~~~ 61 | [example]: http://example.com/ 62 | 63 | [^1]: Footnote def 64 | 65 | *[HTML]: HyperText Markup Language 66 | ~~~ -------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Footnotes.html: -------------------------------------------------------------------------------- 1 |

This is the first paragraph.1

2 | 3 |
    4 |
  • List item one.2
  • 5 |
  • List item two.3
  • 6 |
7 | 8 |

Header4

9 | 10 |

Some paragraph with a footnote5, and another6.

11 | 12 |

Another paragraph with a named footnote7.

13 | 14 |

This paragraph should not have a footnote marker since 15 | the footnote is undefined.[^3]

16 | 17 |

This paragraph should not have a footnote marker since 18 | the footnote has already been used before.[^1]

19 | 20 |

This paragraph links to a footnote with plenty of 21 | block-level content.8

22 | 23 |

This paragraph host the footnote reference within a 24 | footnote test9.

25 | 26 |
27 |
28 |
    29 | 30 |
  1. 31 |

    This is the first note. 

    32 |
  2. 33 | 34 |
  3. 35 |

    This is the second note. 

    36 |
  4. 37 | 38 |
  5. 39 |

    This is the third note, defined out of order. 

    40 |
  6. 41 | 42 |
  7. 43 |

    This is the fourth note. 

    44 |
  8. 45 | 46 |
  9. 47 |

    Content for fifth footnote. 

    48 |
  10. 49 | 50 |
  11. 51 |

    Content for sixth footnote spaning on 52 | three lines, with some span-level markup like 53 | emphasis, a link

    54 |
  12. 55 | 56 |
  13. 57 |

    Footnote beginning on the line next to the marker. 

    58 |
  14. 59 | 60 |
  15. 61 |

    Paragraph.

    62 | 63 |
      64 |
    • List item
    • 65 |
    66 | 67 |
    68 |

    Blockquote

    69 |
    70 | 71 |
    Code block
    72 | 
    73 | 74 |

    75 |
  16. 76 | 77 |
  17. 78 |

    This footnote attemps to refer to another footnote. This 79 | should be impossible.[^impossible] 

    80 |
  18. 81 | 82 |
83 |
84 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Footnotes.md: -------------------------------------------------------------------------------- 1 | This is the first paragraph.[^first] 2 | 3 | [^first]: This is the first note. 4 | 5 | * List item one.[^second] 6 | * List item two.[^third] 7 | 8 | [^third]: This is the third note, defined out of order. 9 | [^second]: This is the second note. 10 | [^fourth]: This is the fourth note. 11 | 12 | # Header[^fourth] 13 | 14 | Some paragraph with a footnote[^1], and another[^2]. 15 | 16 | [^1]: Content for fifth footnote. 17 | [^2]: Content for sixth footnote spaning on 18 | three lines, with some span-level markup like 19 | _emphasis_, a [link][]. 20 | 21 | [link]: http://www.michelf.com/ 22 | 23 | Another paragraph with a named footnote[^fn-name]. 24 | 25 | [^fn-name]: 26 | Footnote beginning on the line next to the marker. 27 | 28 | This paragraph should not have a footnote marker since 29 | the footnote is undefined.[^3] 30 | 31 | This paragraph should not have a footnote marker since 32 | the footnote has already been used before.[^1] 33 | 34 | This paragraph links to a footnote with plenty of 35 | block-level content.[^block] 36 | 37 | [^block]: 38 | Paragraph. 39 | 40 | * List item 41 | 42 | > Blockquote 43 | 44 | Code block 45 | 46 | This paragraph host the footnote reference within a 47 | footnote test[^reference]. 48 | 49 | [^reference]: 50 | This footnote attemps to refer to another footnote. This 51 | should be impossible.[^impossible] 52 | 53 | [^impossible]: 54 | This footnote should not appear, as it is refered from 55 | another footnote, which is not allowed. 56 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Inline_HTML_with_Markdown_content.html: -------------------------------------------------------------------------------- 1 |

Markdown inside code blocks

2 | 3 |
4 | 5 |

foo

6 | 7 |
8 | 9 |
10 | 11 |

foo

12 | 13 |
14 | 15 |
16 | 17 |

foo

18 | 19 |
20 | 21 | 22 | 23 |
test emphasis (span)
24 | 25 | 26 | 27 |
test emphasis (span)
28 | 29 | 30 | 35 |
31 | 32 |

test emphasis (block)

33 | 34 |
36 | 37 |

More complicated

38 | 39 | 40 | 42 | 44 | 51 |
41 | * this is not a list item
43 | * this is not a list item
45 | 46 |
    47 |
  • this is a list item
  • 48 |
49 | 50 |
52 | 53 |

With indent

54 | 55 |
56 |
57 | 58 |

This text is no code block: if it was, the 59 | closing <div> would be too and the HTML block 60 | would be invalid.

61 | 62 |

Markdown content in HTML blocks is assumed to be 63 | indented the same as the block opening tag.

64 | 65 |

This should be the third paragraph after the header.

66 | 67 |
68 |
69 | 70 |

Code block with rogue </div>s in Markdown code span and block

71 | 72 |
73 |
74 | 75 |

This is a code block however:

76 | 77 |
</div>
 78 | 
79 | 80 |

Funny isn't it? Here is a code span: </div>.

81 | 82 |
83 |
84 | 85 |
86 |
87 | 88 |
    89 |
  • List item, not a code block
  • 90 |
91 | 92 |

Some text

93 | 94 |
This is a code block.
 95 | 
96 | 97 |
98 |
99 | 100 |

No code block in markdown span mode

101 | 102 |

103 | This is not a code block since Markdown parse paragraph 104 | content as span. Code spans like </p> are allowed though. 105 |

106 | 107 |

Hello world

108 | 109 |

Preserving attributes and tags on more than one line:

110 | 111 |

113 | Some span content. 114 |

115 | 116 |

Header confusion bug

117 | 118 | 119 | 120 | 124 | 125 |
Hello World! 121 | ============ 122 | 123 | Hello World!
-------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Inline_HTML_with_Markdown_content.md: -------------------------------------------------------------------------------- 1 | # Markdown inside code blocks 2 | 3 |
4 | foo 5 |
6 | 7 |
8 | foo 9 |
10 | 11 |
12 | foo 13 |
14 | 15 | 16 | 17 |
test _emphasis_ (span)
18 | 19 | 20 | 21 |
test _emphasis_ (span)
22 | 23 | 24 | 25 |
test _emphasis_ (block)
26 | 27 | ## More complicated 28 | 29 | 30 | 32 | 34 | 37 |
31 | * this is _not_ a list item
33 | * this is _not_ a list item
35 | * this _is_ a list item 36 |
38 | 39 | ## With indent 40 | 41 |
42 |
43 | This text is no code block: if it was, the 44 | closing `
` would be too and the HTML block 45 | would be invalid. 46 | 47 | Markdown content in HTML blocks is assumed to be 48 | indented the same as the block opening tag. 49 | 50 | **This should be the third paragraph after the header.** 51 |
52 |
53 | 54 | ## Code block with rogue `
`s in Markdown code span and block 55 | 56 |
57 |
58 | 59 | This is a code block however: 60 | 61 |
62 | 63 | Funny isn't it? Here is a code span: `
`. 64 | 65 | 66 | 67 | 68 |
69 |
70 | * List item, not a code block 71 | 72 | Some text 73 | 74 | This is a code block. 75 |
76 |
77 | 78 | ## No code block in markdown span mode 79 | 80 |

81 | This is not a code block since Markdown parse paragraph 82 | content as span. Code spans like `

` are allowed though. 83 |

84 | 85 |

_Hello_ _world_

86 | 87 | ## Preserving attributes and tags on more than one line: 88 | 89 |

91 | Some _span_ content. 92 |

93 | 94 | 95 | ## Header confusion bug 96 | 97 | 98 | 99 | 103 | 104 |
Hello World! 100 | ============ 101 | 102 | Hello World!
105 | -------------------------------------------------------------------------------- /test/resources/PhpMarkdownExtra/Tables.md: -------------------------------------------------------------------------------- 1 | # Simple tables 2 | 3 | Header 1 | Header 2 4 | --------- | --------- 5 | Cell 1 | Cell 2 6 | Cell 3 | Cell 4 7 | 8 | With leading pipes: 9 | 10 | | Header 1 | Header 2 11 | | --------- | --------- 12 | | Cell 1 | Cell 2 13 | | Cell 3 | Cell 4 14 | 15 | With tailing pipes: 16 | 17 | Header 1 | Header 2 | 18 | --------- | --------- | 19 | Cell 1 | Cell 2 | 20 | Cell 3 | Cell 4 | 21 | 22 | With leading and tailing pipes: 23 | 24 | | Header 1 | Header 2 | 25 | | --------- | --------- | 26 | | Cell 1 | Cell 2 | 27 | | Cell 3 | Cell 4 | 28 | 29 | * * * 30 | 31 | # One-column one-row table 32 | 33 | With leading pipes: 34 | 35 | | Header 36 | | ------- 37 | | Cell 38 | 39 | With tailing pipes: 40 | 41 | Header | 42 | ------- | 43 | Cell | 44 | 45 | With leading and tailing pipes: 46 | 47 | | Header | 48 | | ------- | 49 | | Cell | 50 | 51 | * * * 52 | 53 | Table alignement: 54 | 55 | | Default | Right | Center | Left | 56 | | --------- |:--------- |:---------:| ---------:| 57 | | Long Cell | Long Cell | Long Cell | Long Cell | 58 | | Cell | Cell | Cell | Cell | 59 | 60 | Table alignement (alternate spacing): 61 | 62 | | Default | Right | Center | Left | 63 | | --------- | :-------- | :-------: | --------: | 64 | | Long Cell | Long Cell | Long Cell | Long Cell | 65 | | Cell | Cell | Cell | Cell | 66 | 67 | * * * 68 | 69 | # Empty cells 70 | 71 | | Header 1 | Header 2 | 72 | | --------- | --------- | 73 | | A | B | 74 | | C | | 75 | 76 | Header 1 | Header 2 77 | --------- | --------- 78 | A | B 79 | | D 80 | 81 | * * * 82 | 83 | # Missing tailing pipe 84 | 85 | Header 1 | Header 2 86 | --------- | --------- | 87 | Cell | Cell | 88 | Cell | Cell | 89 | 90 | Header 1 | Header 2 | 91 | --------- | --------- 92 | Cell | Cell | 93 | Cell | Cell | 94 | 95 | Header 1 | Header 2 | 96 | --------- | --------- | 97 | Cell | Cell 98 | Cell | Cell | 99 | 100 | Header 1 | Header 2 | 101 | --------- | --------- | 102 | Cell | Cell | 103 | Cell | Cell 104 | 105 | -------------------------------------------------------------------------------- /test/unit/data/goldenfiles/headings.pass: -------------------------------------------------------------------------------- 1 | token #0 HEADER1 [# H1\n] -------------------------------------------------------------------------------- /test/unit/data/goldenfiles/nested.pass: -------------------------------------------------------------------------------- 1 | token #0 PLAIN [a ] 2 | token #1 EMPH [*b ] 3 | token #2 STRONG [__c__] 4 | token #3 EMPH [ d*] 5 | token #4 PLAIN [ e\n] 6 | -------------------------------------------------------------------------------- /test/unit/data/goldenfiles/paragraphs.pass: -------------------------------------------------------------------------------- 1 | token #0 PLAIN [Die Goldstumpfnase (Rhinopithecus roxellana) ist eine Primatenart aus der Gruppe der Schlankaffen (Presbytini).\n] -------------------------------------------------------------------------------- /test/unit/data/goldenfiles/plain.pass: -------------------------------------------------------------------------------- 1 | token #0 PLAIN [a*b__c__d*e\n] 2 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Backslash_escapes.html: -------------------------------------------------------------------------------- 1 |

Tricky combinaisons:

2 | 3 |

backslash with -- two dashes

4 | 5 |

backslash with > greater than

6 | 7 |

[test](not a link)

8 | 9 |

*no emphasis*

10 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Backslash_escapes.md: -------------------------------------------------------------------------------- 1 | Tricky combinaisons: 2 | 3 | backslash with \-- two dashes 4 | 5 | backslash with \> greater than 6 | 7 | \[test](not a link) 8 | 9 | \*no emphasis* -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Code_Spans.html: -------------------------------------------------------------------------------- 1 |

From <!-- to --> 2 | on two lines.

3 | 4 |

From <!-- 5 | to --> 6 | on three lines.

7 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Code_Spans.md: -------------------------------------------------------------------------------- 1 | From `` 2 | on two lines. 3 | 4 | From `` 6 | on three lines. 7 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Code_block_in_a_list_item.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • List Item:

    3 | 4 |
    code block
     5 | 
     6 | with a blank line
     7 | 
    8 | 9 |

    within a list item.

  • 10 |
-------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Code_block_in_a_list_item.md: -------------------------------------------------------------------------------- 1 | 2 | * List Item: 3 | 4 | code block 5 | 6 | with a blank line 7 | 8 | within a list item. -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Email_auto_links.html: -------------------------------------------------------------------------------- 1 |

michel.fortin@michelf.com

2 | 3 |

International domain names: help@tūdaliņ.lv

4 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Email_auto_links.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | International domain names: -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Emphasis.html: -------------------------------------------------------------------------------- 1 |

Combined emphasis:

2 | 3 |
    4 |
  1. test test
  2. 5 |
  3. test test
  4. 6 |
  5. test test
  6. 7 |
  7. test test
  8. 8 |
  9. test test
  10. 9 |
  11. test test
  12. 10 |
  13. test test
  14. 11 |
  15. test test
  16. 12 |
  17. test test
  18. 13 |
  19. test test
  20. 14 |
  21. test test
  22. 15 |
  23. test test
  24. 16 |
  25. test test
  26. 17 |
  27. test test
  28. 18 |
  29. test test
  30. 19 |
  31. test test
  32. 20 |
21 | 22 |

Incorrect nesting:

23 | 24 |
    25 |
  1. *test test* test
  2. 26 |
  3. _test test_ test
  4. 27 |
  5. **test test* test*
  6. 28 |
  7. __test test_ test_
  8. 29 |
  9. test *test test*
  10. 30 |
  11. test _test test_
  12. 31 |
  13. test test test
  14. 32 |
  15. test test test
  16. 33 |
34 | 35 |

No emphasis:

36 | 37 |
    38 |
  1. test* test *test
  2. 39 |
  3. test** test **test
  4. 40 |
  5. test_ test _test
  6. 41 |
  7. test__ test __test
  8. 42 |
43 | 44 |

Middle-word emphasis (asterisks):

45 | 46 |
    47 |
  1. ab
  2. 48 |
  3. ab
  4. 49 |
  5. abc
  6. 50 |
  7. ab
  8. 51 |
  9. ab
  10. 52 |
  11. abc
  12. 53 |
54 | 55 |

Middle-word emphasis (underscore):

56 | 57 |
    58 |
  1. ab
  2. 59 |
  3. ab
  4. 60 |
  5. abc
  6. 61 |
  7. ab
  8. 62 |
  9. ab
  10. 63 |
  11. abc
  12. 64 |
65 | 66 |

mypreciousfile.txt

67 | 68 |

Tricky Cases

69 | 70 |

E**. Test TestTestTest

71 | 72 |

E**. Test Test Test Test

73 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Emphasis.md: -------------------------------------------------------------------------------- 1 | Combined emphasis: 2 | 3 | 1. ***test test*** 4 | 2. ___test test___ 5 | 3. *test **test*** 6 | 4. **test *test*** 7 | 5. ***test* test** 8 | 6. ***test** test* 9 | 7. ***test* test** 10 | 8. **test *test*** 11 | 9. *test **test*** 12 | 10. _test __test___ 13 | 11. __test _test___ 14 | 12. ___test_ test__ 15 | 13. ___test__ test_ 16 | 14. ___test_ test__ 17 | 15. __test _test___ 18 | 16. _test __test___ 19 | 20 | 21 | Incorrect nesting: 22 | 23 | 1. *test **test* test** 24 | 2. _test __test_ test__ 25 | 3. **test *test** test* 26 | 4. __test _test__ test_ 27 | 5. *test *test* test* 28 | 6. _test _test_ test_ 29 | 7. **test **test** test** 30 | 8. __test __test__ test__ 31 | 32 | 33 | 34 | No emphasis: 35 | 36 | 1. test* test *test 37 | 2. test** test **test 38 | 3. test_ test _test 39 | 4. test__ test __test 40 | 41 | 42 | 43 | Middle-word emphasis (asterisks): 44 | 45 | 1. *a*b 46 | 2. a*b* 47 | 3. a*b*c 48 | 4. **a**b 49 | 5. a**b** 50 | 6. a**b**c 51 | 52 | 53 | Middle-word emphasis (underscore): 54 | 55 | 1. _a_b 56 | 2. a_b_ 57 | 3. a_b_c 58 | 4. __a__b 59 | 5. a__b__ 60 | 6. a__b__c 61 | 62 | my_precious_file.txt 63 | 64 | 65 | ## Tricky Cases 66 | 67 | E**. **Test** TestTestTest 68 | 69 | E**. **Test** Test Test Test 70 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Headers.html: -------------------------------------------------------------------------------- 1 |

Header

2 | 3 |

Header

4 | 5 |

Header

6 | 7 |
8 | 9 |

Header

10 | 11 |

Paragraph

12 | 13 |

Header

14 | 15 |

Paragraph

16 | 17 |

Header

18 | 19 |

Paragraph

20 | 21 |
22 | 23 |

Paragraph

24 | 25 |

Header

26 | 27 |

Paragraph

28 | 29 |

Paragraph

30 | 31 |

Header

32 | 33 |

Paragraph

34 | 35 |

Paragraph

36 | 37 |

Header

38 | 39 |

Paragraph

40 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Headers.md: -------------------------------------------------------------------------------- 1 | Header ====== Header ------ ### Header - - - Header ====== Paragraph Header ------ Paragraph ### Header Paragraph - - - Paragraph Header ====== Paragraph Paragraph Header ------ Paragraph Paragraph ### Header Paragraph -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Horizontal_Rules.html: -------------------------------------------------------------------------------- 1 |

Horizontal rules:

2 | 3 |
4 | 5 |
6 | 7 |
8 | 9 |
10 | 11 |
12 | 13 |

Not horizontal rules (testing for a bug in 1.0.1j):

14 | 15 |

+++

16 | 17 |

,,,

18 | 19 |

===

20 | 21 |

???

22 | 23 |

AAA

24 | 25 |

jjj

26 | 27 |

j j j

28 | 29 |

n n n

30 | 31 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Horizontal_Rules.md: -------------------------------------------------------------------------------- 1 | Horizontal rules: 2 | 3 | - - - 4 | 5 | * * * 6 | 7 | *** 8 | 9 | --- 10 | 11 | ___ 12 | 13 | Not horizontal rules (testing for a bug in 1.0.1j): 14 | 15 | +++ 16 | 17 | ,,, 18 | 19 | === 20 | 21 | ??? 22 | 23 | AAA 24 | 25 | jjj 26 | 27 | j j j 28 | 29 | n n n 30 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Inline_HTML_(Simple).html: -------------------------------------------------------------------------------- 1 |

With some attributes:

2 | 3 |
4 | foo 5 |
6 | 7 |
9 | foo 10 |
11 | 12 |

Hr's:

13 | 14 |
-------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Inline_HTML_(Simple).md: -------------------------------------------------------------------------------- 1 | With some attributes: 2 | 3 |
4 | foo 5 |
6 | 7 |
9 | foo 10 |
11 | 12 | Hr's: 13 | 14 |
16 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Inline_HTML_(Span).html: -------------------------------------------------------------------------------- 1 |

ACINACS

2 | 3 |

SB 4 | SB

-------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Inline_HTML_(Span).md: -------------------------------------------------------------------------------- 1 | ACINACS 2 | 3 | SB 4 | SB -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Inline_HTML_comments.html: -------------------------------------------------------------------------------- 1 |

Paragraph one.

2 | 3 | 4 | 5 |

Paragraph two.

6 | 7 | 8 | 9 |

The end.

10 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Inline_HTML_comments.md: -------------------------------------------------------------------------------- 1 | Paragraph one. 2 | 3 | 4 | 5 | Paragraph two. 6 | 7 | 8 | 9 | The end. 10 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Ins_and_del.html: -------------------------------------------------------------------------------- 1 |

Here is a block tag ins:

2 | 3 | 4 |

Some text

5 |
6 | 7 |

And here it is inside a paragraph.

8 | 9 |

And here it is in the middle of a paragraph.

10 | 11 | 12 |

Some text

13 |
14 | 15 |

And here is ins as a paragraph.

16 | 17 |

And here it is in the middle of a paragraph.

18 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Ins_and_del.md: -------------------------------------------------------------------------------- 1 | Here is a block tag ins: 2 | 3 | 4 |

Some text

5 |
6 | 7 | And here it is inside a paragraph. 8 | 9 | And here it is in the middle of a paragraph. 10 | 11 | 12 |

Some text

13 |
14 | 15 | And here is ins as a paragraph. 16 | 17 | And here it is in the middle of a paragraph. 18 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Links_inline_style.html: -------------------------------------------------------------------------------- 1 |

silly URL w/ angle brackets.

2 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Links_inline_style.md: -------------------------------------------------------------------------------- 1 | [silly URL w/ angle brackets](). 2 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/MD5_Hashes.html: -------------------------------------------------------------------------------- 1 |

Character Escapes

2 | 3 |

The MD5 value for + is "26b17225b626fb9238849fd60eabdf60".

4 | 5 |

HTML Blocks

6 | 7 |

test

8 | 9 |

The MD5 value for <p>test</p> is:

10 | 11 |

6205333b793f34273d75379350b36826

12 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/MD5_Hashes.md: -------------------------------------------------------------------------------- 1 | # Character Escapes 2 | 3 | The MD5 value for `+` is "26b17225b626fb9238849fd60eabdf60". 4 | 5 | # HTML Blocks 6 | 7 |

test

8 | 9 | The MD5 value for `

test

` is: 10 | 11 | 6205333b793f34273d75379350b36826 -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Nesting.html: -------------------------------------------------------------------------------- 1 |

Valid nesting:

2 | 3 |

Link

4 | 5 |

Link

6 | 7 |

Link

8 | 9 |

Invalid nesting:

10 | 11 |
12 | 
13 | #commented out
14 | [[Link](url)](url)
15 | 
16 | 
17 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Nesting.md: -------------------------------------------------------------------------------- 1 | Valid nesting: 2 | 3 | **[Link](url)** 4 | 5 | [**Link**](url) 6 | 7 | **[**Link**](url)** 8 | 9 | Invalid nesting: 10 | 11 | #commented out 12 | [[Link](url)](url) -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/PHP-Specific_Bugs.html: -------------------------------------------------------------------------------- 1 |

This tests for a bug where quotes escaped by PHP when using 2 | preg_replace with the /e modifier must be correctly unescaped 3 | (hence the _UnslashQuotes function found only in PHP Markdown).

4 | 5 |

Headers below should appear exactly as they are typed (no backslash 6 | added or removed).

7 | 8 |

Header "quoted\" again \""

9 | 10 |

Header "quoted\" again \""

11 | 12 |

Header "quoted\" again \""

13 | 14 |

Test with tabs for _Detab:

15 | 16 |
Code    'block' with    some    "tabs"  and "quotes"
17 | 
18 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/PHP-Specific_Bugs.md: -------------------------------------------------------------------------------- 1 | This tests for a bug where quotes escaped by PHP when using 2 | `preg_replace` with the `/e` modifier must be correctly unescaped 3 | (hence the `_UnslashQuotes` function found only in PHP Markdown). 4 | 5 | 6 | 7 | Headers below should appear exactly as they are typed (no backslash 8 | added or removed). 9 | 10 | Header "quoted\" again \\"" 11 | =========================== 12 | 13 | Header "quoted\" again \\"" 14 | --------------------------- 15 | 16 | ### Header "quoted\" again \\"" ### 17 | 18 | 19 | 20 | Test with tabs for `_Detab`: 21 | 22 | Code 'block' with some "tabs" and "quotes" 23 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Parens_in_URL.html: -------------------------------------------------------------------------------- 1 |

Inline link 1 with parens.

2 | 3 |

Inline link 2 with parens.

4 | 5 |

Inline link 3 with non-escaped parens.

6 | 7 |

Inline link 4 with non-escaped parens.

8 | 9 |

Reference link 1 with parens.

10 | 11 |

Reference link 2 with parens.

-------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Parens_in_URL.md: -------------------------------------------------------------------------------- 1 | [Inline link 1 with parens](/url\(test\) "title"). 2 | 3 | [Inline link 2 with parens]( "title"). 4 | 5 | [Inline link 3 with non-escaped parens](/url(test) "title"). 6 | 7 | [Inline link 4 with non-escaped parens]( "title"). 8 | 9 | [Reference link 1 with parens][1]. 10 | 11 | [Reference link 2 with parens][2]. 12 | 13 | [1]: /url(test) "title" 14 | [2]: "title" 15 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Tight_blocks.html: -------------------------------------------------------------------------------- 1 |

Paragraph and no space: 2 | * ciao

3 | 4 |

Paragraph and 1 space: 5 | * ciao

6 | 7 |

Paragraph and 3 spaces: 8 | * ciao

9 | 10 |

Paragraph and 4 spaces: 11 | * ciao

12 | 13 |

Paragraph before header:

14 | 15 |

Header

16 | 17 |

Paragraph before blockquote:

18 | 19 |
20 |

Some quote.

21 |
22 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdown/Tight_blocks.md: -------------------------------------------------------------------------------- 1 | Paragraph and no space: * ciao Paragraph and 1 space: * ciao Paragraph and 3 spaces: * ciao Paragraph and 4 spaces: * ciao Paragraph before header: #Header Paragraph before blockquote: >Some quote. -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Abbr.html: -------------------------------------------------------------------------------- 1 |

Some text about HTML, SGML and HTML4.

2 | 3 |

Let's talk about the U.S.A., (É.U. or É.-U. d'A. in French).

4 | 5 |

And here we have a CD, some CDs, and some other CD's.

6 | 7 |

Let's transfert documents through TCP/IP, using TCP packets.

8 | 9 |
10 | 11 |

Bienvenue sur CMS.

12 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Abbr.md: -------------------------------------------------------------------------------- 1 | Some text about HTML, SGML and HTML4. 2 | 3 | Let's talk about the U.S.A., (É.U. or É.-U. d'A. in French). 4 | 5 | *[HTML4]: Hyper Text Markup Language version 4 6 | *[HTML]: Hyper Text Markup Language 7 | *[SGML]: Standard Generalized Markup Language 8 | *[U.S.A.]: United States of America 9 | *[É.U.] : États-Unis d'Amérique 10 | *[É.-U. d'A.] : États-Unis d'Amérique 11 | 12 | And here we have a CD, some CDs, and some other CD's. 13 | 14 | *[CD]: Compact Disk 15 | 16 | Let's transfert documents through TCP/IP, using TCP packets. 17 | 18 | *[IP]: Internet Protocol 19 | *[TCP]: Transmission Control Protocol 20 | 21 | --- 22 | 23 | Bienvenue sur [CMS](http://www.bidulecms.com "Bidule CMS"). 24 | 25 | *[CMS]: Content Management System -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Definition_Lists.html: -------------------------------------------------------------------------------- 1 |

A simple definition list:

2 | 3 |
4 |
Term 1
5 |
Definition 1
6 | 7 |
Term 2
8 |
Definition 2
9 |
10 | 11 |

With multiple terms:

12 | 13 |
14 |
Term 1
15 |
Term 2
16 |
Definition 1
17 | 18 |
Term 3
19 |
Term 4
20 |
Definition 2
21 |
22 | 23 |

With multiple definitions:

24 | 25 |
26 |
Term 1
27 |
Definition 1
28 | 29 |
Definition 2
30 | 31 |
Term 2
32 |
Definition 3
33 | 34 |
Definition 4
35 |
36 | 37 |

With multiple lines per definition:

38 | 39 |
40 |
Term 1
41 |
Definition 1 line 1 ... 42 | Definition 1 line 2
43 | 44 |
Definition 2 line 1 ... 45 | Definition 2 line 2
46 | 47 |
Term 2
48 |
Definition 3 line 2 ... 49 | Definition 3 line 2
50 | 51 |
Definition 4 line 2 ... 52 | Definition 4 line 2
53 |
54 | 55 |

With paragraphs:

56 | 57 |
58 |
Term 1
59 |
60 |

Definition 1 (paragraph)

61 |
62 | 63 |
Term 2
64 |
65 |

Definition 2 (paragraph)

66 |
67 |
68 | 69 |

With multiple paragraphs:

70 | 71 |
72 |
Term 1
73 |
74 |

Definition 1 paragraph 1 line 1 ... 75 | Definition 1 paragraph 1 line 2

76 | 77 |

Definition 1 paragraph 2 line 1 ... 78 | Definition 1 paragraph 2 line 2

79 |
80 | 81 |
Term 2
82 |
83 |

Definition 1 paragraph 1 line 1 ... 84 | Definition 1 paragraph 1 line 2 (lazy)

85 | 86 |

Definition 1 paragraph 2 line 1 ... 87 | Definition 1 paragraph 2 line 2 (lazy)

88 |
89 |
90 | 91 |
92 | 93 |

A mix:

94 | 95 |
96 |
Term 1
97 |
Term 2
98 |
99 |

Definition 1 paragraph 1 line 1 ... 100 | Definition 1 paragraph 1 line 2 (lazy)

101 | 102 |

Definition 1 paragraph 2 line 1 ... 103 | Definition 1 paragraph 2 line 2

104 |
105 | 106 |
107 |

Definition 2 paragraph 1 line 1 ... 108 | Definition 2 paragraph 1 line 2 (lazy)

109 |
110 | 111 |
Term 3
112 |
Definition 3 (no paragraph)
113 | 114 |
Definition 4 (no paragraph)
115 | 116 |
Definition 5 line 1 ... 117 | Definition 5 line 2 (no paragraph)
118 | 119 |
120 |

Definition 6 paragraph 1 line 1 ... 121 | Definition 6 paragraph 1 line 2

122 |
123 | 124 |
Definition 7 (no paragraph)
125 | 126 |
127 |

Definition 8 paragraph 1 line 1 (forced paragraph) ... 128 | Definition 8 paragraph 1 line 2

129 | 130 |

Definition 8 paragraph 2 line 1

131 |
132 | 133 |
Term 4
134 |
135 |

Definition 9 paragraph 1 line 1 (forced paragraph) ... 136 | Definition 9 paragraph 1 line 2

137 | 138 |

Definition 9 paragraph 2 line 1

139 |
140 | 141 |
Definition 10 (no paragraph)
142 |
143 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Definition_Lists.md: -------------------------------------------------------------------------------- 1 | A simple definition list: 2 | 3 | Term 1 4 | : Definition 1 5 | 6 | Term 2 7 | : Definition 2 8 | 9 | With multiple terms: 10 | 11 | Term 1 12 | Term 2 13 | : Definition 1 14 | 15 | Term 3 16 | Term 4 17 | : Definition 2 18 | 19 | With multiple definitions: 20 | 21 | Term 1 22 | : Definition 1 23 | : Definition 2 24 | 25 | Term 2 26 | : Definition 3 27 | : Definition 4 28 | 29 | With multiple lines per definition: 30 | 31 | Term 1 32 | : Definition 1 line 1 ... 33 | Definition 1 line 2 34 | : Definition 2 line 1 ... 35 | Definition 2 line 2 36 | 37 | Term 2 38 | : Definition 3 line 2 ... 39 | Definition 3 line 2 40 | : Definition 4 line 2 ... 41 | Definition 4 line 2 42 | 43 | With paragraphs: 44 | 45 | Term 1 46 | 47 | : Definition 1 (paragraph) 48 | 49 | Term 2 50 | 51 | : Definition 2 (paragraph) 52 | 53 | With multiple paragraphs: 54 | 55 | Term 1 56 | 57 | : Definition 1 paragraph 1 line 1 ... 58 | Definition 1 paragraph 1 line 2 59 | 60 | Definition 1 paragraph 2 line 1 ... 61 | Definition 1 paragraph 2 line 2 62 | 63 | Term 2 64 | 65 | : Definition 1 paragraph 1 line 1 ... 66 | Definition 1 paragraph 1 line 2 (lazy) 67 | 68 | Definition 1 paragraph 2 line 1 ... 69 | Definition 1 paragraph 2 line 2 (lazy) 70 | 71 | * * * 72 | 73 | A mix: 74 | 75 | Term 1 76 | Term 2 77 | 78 | : Definition 1 paragraph 1 line 1 ... 79 | Definition 1 paragraph 1 line 2 (lazy) 80 | 81 | Definition 1 paragraph 2 line 1 ... 82 | Definition 1 paragraph 2 line 2 83 | 84 | : Definition 2 paragraph 1 line 1 ... 85 | Definition 2 paragraph 1 line 2 (lazy) 86 | 87 | Term 3 88 | : Definition 3 (no paragraph) 89 | : Definition 4 (no paragraph) 90 | : Definition 5 line 1 ... 91 | Definition 5 line 2 (no paragraph) 92 | 93 | : Definition 6 paragraph 1 line 1 ... 94 | Definition 6 paragraph 1 line 2 95 | : Definition 7 (no paragraph) 96 | : Definition 8 paragraph 1 line 1 (forced paragraph) ... 97 | Definition 8 paragraph 1 line 2 98 | 99 | Definition 8 paragraph 2 line 1 100 | 101 | Term 4 102 | : Definition 9 paragraph 1 line 1 (forced paragraph) ... 103 | Definition 9 paragraph 1 line 2 104 | 105 | Definition 9 paragraph 2 line 1 106 | : Definition 10 (no paragraph) -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Emphasis.html: -------------------------------------------------------------------------------- 1 |

Combined emphasis:

2 | 3 |
    4 |
  1. test test
  2. 5 |
  3. test test
  4. 6 |
  5. test test
  6. 7 |
  7. test test
  8. 8 |
  9. test test
  10. 9 |
  11. test test
  12. 10 |
  13. test test
  14. 11 |
  15. test test
  16. 12 |
  17. test test
  18. 13 |
  19. test test
  20. 14 |
  21. test test
  22. 15 |
  23. test test
  24. 16 |
  25. test test
  26. 17 |
  27. test test
  28. 18 |
  29. test test
  30. 19 |
  31. test test
  32. 20 |
21 | 22 |

Incorrect nesting:

23 | 24 |
    25 |
  1. *test test* test
  2. 26 |
  3. _test test_ test
  4. 27 |
  5. **test test* test*
  6. 28 |
  7. __test test_ test_
  8. 29 |
  9. test *test test*
  10. 30 |
  11. test _test test_
  12. 31 |
  13. test test test
  14. 32 |
  15. test test test
  16. 33 |
34 | 35 |

No emphasis:

36 | 37 |
    38 |
  1. test* test *test
  2. 39 |
  3. test** test **test
  4. 40 |
  5. test_ test _test
  6. 41 |
  7. test__ test __test
  8. 42 |
43 | 44 |

Middle-word emphasis (asterisks):

45 | 46 |
    47 |
  1. ab
  2. 48 |
  3. ab
  4. 49 |
  5. abc
  6. 50 |
  7. ab
  8. 51 |
  9. ab
  10. 52 |
  11. abc
  12. 53 |
54 | 55 |

Middle-word emphasis (underscore):

56 | 57 |
    58 |
  1. _a_b
  2. 59 |
  3. a_b_
  4. 60 |
  5. a_b_c
  6. 61 |
  7. __a__b
  8. 62 |
  9. a__b__
  10. 63 |
  11. a__b__c
  12. 64 |
65 | 66 |

my_precious_file.txt

67 | 68 |

Tricky Cases

69 | 70 |

E**. Test TestTestTest

71 | 72 |

E**. Test Test Test Test

73 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Emphasis.md: -------------------------------------------------------------------------------- 1 | Combined emphasis: 2 | 3 | 1. ***test test*** 4 | 2. ___test test___ 5 | 3. *test **test*** 6 | 4. **test *test*** 7 | 5. ***test* test** 8 | 6. ***test** test* 9 | 7. ***test* test** 10 | 8. **test *test*** 11 | 9. *test **test*** 12 | 10. _test __test___ 13 | 11. __test _test___ 14 | 12. ___test_ test__ 15 | 13. ___test__ test_ 16 | 14. ___test_ test__ 17 | 15. __test _test___ 18 | 16. _test __test___ 19 | 20 | 21 | Incorrect nesting: 22 | 23 | 1. *test **test* test** 24 | 2. _test __test_ test__ 25 | 3. **test *test** test* 26 | 4. __test _test__ test_ 27 | 5. *test *test* test* 28 | 6. _test _test_ test_ 29 | 7. **test **test** test** 30 | 8. __test __test__ test__ 31 | 32 | 33 | 34 | No emphasis: 35 | 36 | 1. test* test *test 37 | 2. test** test **test 38 | 3. test_ test _test 39 | 4. test__ test __test 40 | 41 | 42 | 43 | Middle-word emphasis (asterisks): 44 | 45 | 1. *a*b 46 | 2. a*b* 47 | 3. a*b*c 48 | 4. **a**b 49 | 5. a**b** 50 | 6. a**b**c 51 | 52 | 53 | Middle-word emphasis (underscore): 54 | 55 | 1. _a_b 56 | 2. a_b_ 57 | 3. a_b_c 58 | 4. __a__b 59 | 5. a__b__ 60 | 6. a__b__c 61 | 62 | my_precious_file.txt 63 | 64 | 65 | ## Tricky Cases 66 | 67 | E**. **Test** TestTestTest 68 | 69 | E**. **Test** Test Test Test 70 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Fenced_Code_Blocks.html: -------------------------------------------------------------------------------- 1 |
Fenced
 2 | 
3 | 4 |

Code block starting and ending with empty lines:

5 | 6 |


Fenced 7 | 8 | 9 |
10 | 11 |

Indented code block containing fenced code block sample:

12 | 13 |
~~~
14 | Fenced
15 | ~~~
16 | 
17 | 18 |

Fenced code block with indented code block sample:

19 | 20 |
Some text
21 | 
22 |     Indented code block sample code
23 | 
24 | 25 |

Fenced code block with long markers:

26 | 27 |
Fenced
28 | 
29 | 30 |

Empty Fenced code block:

31 |

~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~

32 | 33 |

Fenced code block with fenced code block markers of different length in it:

34 | 35 |
In code block
36 | ~~~
37 | Still in code block
38 | ~~~~~
39 | Still in code block
40 | 
41 | 42 |

Fenced code block with Markdown header and horizontal rule:

43 | 44 |
#test
45 | ---
46 | 
47 | 48 |

Fenced code block with link definitions, footnote definition and 49 | abbreviation definitions:

50 | 51 |
[example]: http://example.com/
52 | 
53 | [^1]: Footnote def
54 | 
55 | *[HTML]: HyperText Markup Language
56 | 
57 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Fenced_Code_Blocks.md: -------------------------------------------------------------------------------- 1 | ~~~ 2 | Fenced 3 | ~~~ 4 | 5 | Code block starting and ending with empty lines: 6 | 7 | ~~~ 8 | 9 | 10 | Fenced 11 | 12 | 13 | ~~~ 14 | 15 | Indented code block containing fenced code block sample: 16 | 17 | ~~~ 18 | Fenced 19 | ~~~ 20 | 21 | Fenced code block with indented code block sample: 22 | 23 | ~~~ 24 | Some text 25 | 26 | Indented code block sample code 27 | ~~~ 28 | 29 | Fenced code block with long markers: 30 | 31 | ~~~~~~~~~~~~~~~~~~ 32 | Fenced 33 | ~~~~~~~~~~~~~~~~~~ 34 | 35 | Empty Fenced code block: 36 | 37 | ~~~~~~~~~~~~~~~~~~ 38 | ~~~~~~~~~~~~~~~~~~ 39 | 40 | Fenced code block with fenced code block markers of different length in it: 41 | 42 | ~~~~ 43 | In code block 44 | ~~~ 45 | Still in code block 46 | ~~~~~ 47 | Still in code block 48 | ~~~~ 49 | 50 | Fenced code block with Markdown header and horizontal rule: 51 | 52 | ~~~ 53 | #test 54 | --- 55 | ~~~ 56 | 57 | Fenced code block with link definitions, footnote definition and 58 | abbreviation definitions: 59 | 60 | ~~~ 61 | [example]: http://example.com/ 62 | 63 | [^1]: Footnote def 64 | 65 | *[HTML]: HyperText Markup Language 66 | ~~~ -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Footnotes.html: -------------------------------------------------------------------------------- 1 |

This is the first paragraph.1

2 | 3 |
    4 |
  • List item one.2
  • 5 |
  • List item two.3
  • 6 |
7 | 8 |

Header4

9 | 10 |

Some paragraph with a footnote5, and another6.

11 | 12 |

Another paragraph with a named footnote7.

13 | 14 |

This paragraph should not have a footnote marker since 15 | the footnote is undefined.[^3]

16 | 17 |

This paragraph should not have a footnote marker since 18 | the footnote has already been used before.[^1]

19 | 20 |

This paragraph links to a footnote with plenty of 21 | block-level content.8

22 | 23 |

This paragraph host the footnote reference within a 24 | footnote test9.

25 | 26 |
27 |
28 |
    29 | 30 |
  1. 31 |

    This is the first note. 

    32 |
  2. 33 | 34 |
  3. 35 |

    This is the second note. 

    36 |
  4. 37 | 38 |
  5. 39 |

    This is the third note, defined out of order. 

    40 |
  6. 41 | 42 |
  7. 43 |

    This is the fourth note. 

    44 |
  8. 45 | 46 |
  9. 47 |

    Content for fifth footnote. 

    48 |
  10. 49 | 50 |
  11. 51 |

    Content for sixth footnote spaning on 52 | three lines, with some span-level markup like 53 | emphasis, a link

    54 |
  12. 55 | 56 |
  13. 57 |

    Footnote beginning on the line next to the marker. 

    58 |
  14. 59 | 60 |
  15. 61 |

    Paragraph.

    62 | 63 |
      64 |
    • List item
    • 65 |
    66 | 67 |
    68 |

    Blockquote

    69 |
    70 | 71 |
    Code block
    72 | 
    73 | 74 |

    75 |
  16. 76 | 77 |
  17. 78 |

    This footnote attemps to refer to another footnote. This 79 | should be impossible.[^impossible] 

    80 |
  18. 81 | 82 |
83 |
84 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Footnotes.md: -------------------------------------------------------------------------------- 1 | This is the first paragraph.[^first] 2 | 3 | [^first]: This is the first note. 4 | 5 | * List item one.[^second] 6 | * List item two.[^third] 7 | 8 | [^third]: This is the third note, defined out of order. 9 | [^second]: This is the second note. 10 | [^fourth]: This is the fourth note. 11 | 12 | # Header[^fourth] 13 | 14 | Some paragraph with a footnote[^1], and another[^2]. 15 | 16 | [^1]: Content for fifth footnote. 17 | [^2]: Content for sixth footnote spaning on 18 | three lines, with some span-level markup like 19 | _emphasis_, a [link][]. 20 | 21 | [link]: http://www.michelf.com/ 22 | 23 | Another paragraph with a named footnote[^fn-name]. 24 | 25 | [^fn-name]: 26 | Footnote beginning on the line next to the marker. 27 | 28 | This paragraph should not have a footnote marker since 29 | the footnote is undefined.[^3] 30 | 31 | This paragraph should not have a footnote marker since 32 | the footnote has already been used before.[^1] 33 | 34 | This paragraph links to a footnote with plenty of 35 | block-level content.[^block] 36 | 37 | [^block]: 38 | Paragraph. 39 | 40 | * List item 41 | 42 | > Blockquote 43 | 44 | Code block 45 | 46 | This paragraph host the footnote reference within a 47 | footnote test[^reference]. 48 | 49 | [^reference]: 50 | This footnote attemps to refer to another footnote. This 51 | should be impossible.[^impossible] 52 | 53 | [^impossible]: 54 | This footnote should not appear, as it is refered from 55 | another footnote, which is not allowed. 56 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Inline_HTML_with_Markdown_content.html: -------------------------------------------------------------------------------- 1 |

Markdown inside code blocks

2 | 3 |
4 | 5 |

foo

6 | 7 |
8 | 9 |
10 | 11 |

foo

12 | 13 |
14 | 15 |
16 | 17 |

foo

18 | 19 |
20 | 21 | 22 | 23 |
test emphasis (span)
24 | 25 | 26 | 27 |
test emphasis (span)
28 | 29 | 30 | 35 |
31 | 32 |

test emphasis (block)

33 | 34 |
36 | 37 |

More complicated

38 | 39 | 40 | 42 | 44 | 51 |
41 | * this is not a list item
43 | * this is not a list item
45 | 46 |
    47 |
  • this is a list item
  • 48 |
49 | 50 |
52 | 53 |

With indent

54 | 55 |
56 |
57 | 58 |

This text is no code block: if it was, the 59 | closing <div> would be too and the HTML block 60 | would be invalid.

61 | 62 |

Markdown content in HTML blocks is assumed to be 63 | indented the same as the block opening tag.

64 | 65 |

This should be the third paragraph after the header.

66 | 67 |
68 |
69 | 70 |

Code block with rogue </div>s in Markdown code span and block

71 | 72 |
73 |
74 | 75 |

This is a code block however:

76 | 77 |
</div>
 78 | 
79 | 80 |

Funny isn't it? Here is a code span: </div>.

81 | 82 |
83 |
84 | 85 |
86 |
87 | 88 |
    89 |
  • List item, not a code block
  • 90 |
91 | 92 |

Some text

93 | 94 |
This is a code block.
 95 | 
96 | 97 |
98 |
99 | 100 |

No code block in markdown span mode

101 | 102 |

103 | This is not a code block since Markdown parse paragraph 104 | content as span. Code spans like </p> are allowed though. 105 |

106 | 107 |

Hello world

108 | 109 |

Preserving attributes and tags on more than one line:

110 | 111 |

113 | Some span content. 114 |

115 | 116 |

Header confusion bug

117 | 118 | 119 | 120 | 124 | 125 |
Hello World! 121 | ============ 122 | 123 | Hello World!
-------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Inline_HTML_with_Markdown_content.md: -------------------------------------------------------------------------------- 1 | # Markdown inside code blocks 2 | 3 |
4 | foo 5 |
6 | 7 |
8 | foo 9 |
10 | 11 |
12 | foo 13 |
14 | 15 | 16 | 17 |
test _emphasis_ (span)
18 | 19 | 20 | 21 |
test _emphasis_ (span)
22 | 23 | 24 | 25 |
test _emphasis_ (block)
26 | 27 | ## More complicated 28 | 29 | 30 | 32 | 34 | 37 |
31 | * this is _not_ a list item
33 | * this is _not_ a list item
35 | * this _is_ a list item 36 |
38 | 39 | ## With indent 40 | 41 |
42 |
43 | This text is no code block: if it was, the 44 | closing `
` would be too and the HTML block 45 | would be invalid. 46 | 47 | Markdown content in HTML blocks is assumed to be 48 | indented the same as the block opening tag. 49 | 50 | **This should be the third paragraph after the header.** 51 |
52 |
53 | 54 | ## Code block with rogue `
`s in Markdown code span and block 55 | 56 |
57 |
58 | 59 | This is a code block however: 60 | 61 |
62 | 63 | Funny isn't it? Here is a code span: `
`. 64 | 65 | 66 | 67 | 68 |
69 |
70 | * List item, not a code block 71 | 72 | Some text 73 | 74 | This is a code block. 75 |
76 |
77 | 78 | ## No code block in markdown span mode 79 | 80 |

81 | This is not a code block since Markdown parse paragraph 82 | content as span. Code spans like `

` are allowed though. 83 |

84 | 85 |

_Hello_ _world_

86 | 87 | ## Preserving attributes and tags on more than one line: 88 | 89 |

91 | Some _span_ content. 92 |

93 | 94 | 95 | ## Header confusion bug 96 | 97 | 98 | 99 | 103 | 104 |
Hello World! 100 | ============ 101 | 102 | Hello World!
105 | -------------------------------------------------------------------------------- /test/unit/data/resources/PhpMarkdownExtra/Tables.md: -------------------------------------------------------------------------------- 1 | # Simple tables 2 | 3 | Header 1 | Header 2 4 | --------- | --------- 5 | Cell 1 | Cell 2 6 | Cell 3 | Cell 4 7 | 8 | With leading pipes: 9 | 10 | | Header 1 | Header 2 11 | | --------- | --------- 12 | | Cell 1 | Cell 2 13 | | Cell 3 | Cell 4 14 | 15 | With tailing pipes: 16 | 17 | Header 1 | Header 2 | 18 | --------- | --------- | 19 | Cell 1 | Cell 2 | 20 | Cell 3 | Cell 4 | 21 | 22 | With leading and tailing pipes: 23 | 24 | | Header 1 | Header 2 | 25 | | --------- | --------- | 26 | | Cell 1 | Cell 2 | 27 | | Cell 3 | Cell 4 | 28 | 29 | * * * 30 | 31 | # One-column one-row table 32 | 33 | With leading pipes: 34 | 35 | | Header 36 | | ------- 37 | | Cell 38 | 39 | With tailing pipes: 40 | 41 | Header | 42 | ------- | 43 | Cell | 44 | 45 | With leading and tailing pipes: 46 | 47 | | Header | 48 | | ------- | 49 | | Cell | 50 | 51 | * * * 52 | 53 | Table alignement: 54 | 55 | | Default | Right | Center | Left | 56 | | --------- |:--------- |:---------:| ---------:| 57 | | Long Cell | Long Cell | Long Cell | Long Cell | 58 | | Cell | Cell | Cell | Cell | 59 | 60 | Table alignement (alternate spacing): 61 | 62 | | Default | Right | Center | Left | 63 | | --------- | :-------- | :-------: | --------: | 64 | | Long Cell | Long Cell | Long Cell | Long Cell | 65 | | Cell | Cell | Cell | Cell | 66 | 67 | * * * 68 | 69 | # Empty cells 70 | 71 | | Header 1 | Header 2 | 72 | | --------- | --------- | 73 | | A | B | 74 | | C | | 75 | 76 | Header 1 | Header 2 77 | --------- | --------- 78 | A | B 79 | | D 80 | 81 | * * * 82 | 83 | # Missing tailing pipe 84 | 85 | Header 1 | Header 2 86 | --------- | --------- | 87 | Cell | Cell | 88 | Cell | Cell | 89 | 90 | Header 1 | Header 2 | 91 | --------- | --------- 92 | Cell | Cell | 93 | Cell | Cell | 94 | 95 | Header 1 | Header 2 | 96 | --------- | --------- | 97 | Cell | Cell 98 | Cell | Cell | 99 | 100 | Header 1 | Header 2 | 101 | --------- | --------- | 102 | Cell | Cell | 103 | Cell | Cell 104 | 105 | -------------------------------------------------------------------------------- /test/unit/data/testfiles/headings.md: -------------------------------------------------------------------------------- 1 | # H1 2 | -------------------------------------------------------------------------------- /test/unit/data/testfiles/nested.md: -------------------------------------------------------------------------------- 1 | a *b __c__ d* e -------------------------------------------------------------------------------- /test/unit/data/testfiles/paragraphs.md: -------------------------------------------------------------------------------- 1 | Die Goldstumpfnase (Rhinopithecus roxellana) ist eine Primatenart aus der Gruppe der Schlankaffen (Presbytini). 2 | -------------------------------------------------------------------------------- /test/unit/data/testfiles/plain.md: -------------------------------------------------------------------------------- 1 | a*b__c__d*e -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/csl/MarkdownTOCBuilderTest.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.csl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Comparator; 6 | import java.util.List; 7 | import org.junit.After; 8 | import org.junit.Assert; 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | import org.netbeans.modules.csl.api.StructureItem; 12 | import org.pegdown.ast.HeaderNode; 13 | import org.pegdown.ast.TextNode; 14 | 15 | public class MarkdownTOCBuilderTest { 16 | 17 | private static final Comparator BY_SORT_KEY = new Comparator() { 18 | 19 | @Override 20 | public int compare(StructureItem o1, StructureItem o2) { 21 | return o1.getSortText().compareTo(o2.getSortText()); 22 | } 23 | 24 | }; 25 | 26 | @Before 27 | public void setUp() { 28 | } 29 | 30 | @After 31 | public void tearDown() { 32 | } 33 | 34 | /** 35 | * Test fix for issue #114. 36 | */ 37 | @Test 38 | public void testSortKeyReflectsDocumentStructure() { 39 | // given 40 | MarkdownTOCBuilder builder = new MarkdownTOCBuilder(null); 41 | final int count = 20; 42 | List nodes = createHeaderNodes(count); 43 | 44 | // when 45 | for (HeaderNode node : nodes) { 46 | builder.add(node); 47 | } 48 | builder.finish(count * 100); 49 | List items = builder.build(); 50 | 51 | // then 52 | List expItems = new ArrayList(items); 53 | Collections.sort(expItems, BY_SORT_KEY); 54 | 55 | Assert.assertEquals("items are sorted by sort key", expItems, items); 56 | } 57 | 58 | private List createHeaderNodes(int count) { 59 | final List headerNodes = new ArrayList(); 60 | for (int index = 0; index < count; ++index) { 61 | headerNodes.add(createHeaderNode(index)); 62 | } 63 | 64 | return headerNodes; 65 | } 66 | 67 | private HeaderNode createHeaderNode(int index) { 68 | TextNode textNode = new TextNode("Heading " + (index + 1)); 69 | 70 | HeaderNode headerNode = new HeaderNode(1, textNode); 71 | 72 | headerNode.setStartIndex(index * 100); 73 | textNode.setStartIndex(headerNode.getStartIndex() + 2); 74 | textNode.setEndIndex(textNode.getStartIndex() + textNode.getText().length()); 75 | headerNode.setEndIndex(textNode.getEndIndex()); 76 | 77 | return headerNode; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/highlighter/MarkdownLexerTest.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.highlighter; 2 | 3 | import org.junit.Test; 4 | import static org.junit.Assert.*; 5 | import org.netbeans.api.lexer.Language; 6 | import org.netbeans.api.lexer.TokenHierarchy; 7 | 8 | public class MarkdownLexerTest extends MarkdownLexerTestBase { 9 | 10 | public MarkdownLexerTest() { 11 | } 12 | 13 | @Test 14 | public void testCreate() { 15 | String content = "\n"; 16 | Language language = MarkdownTokenId.language(); 17 | TokenHierarchy hierarchy = TokenHierarchy.create(content, language); 18 | assertFalse(hierarchy.tokenSequence().isEmpty()); 19 | } 20 | 21 | @Test 22 | public void testParagraphs() throws Exception { 23 | assertEquals(getGoldenFileContent("paragraphs.pass"), getTestResult("paragraphs.md")); 24 | } 25 | 26 | @Test 27 | public void testHeadings() throws Exception { 28 | assertEquals(getGoldenFileContent("headings.pass"), getTestResult("headings.md")); 29 | } 30 | 31 | @Test 32 | public void testNested() throws Exception { 33 | assertEquals(getGoldenFileContent("nested.pass"), getTestResult("nested.md")); 34 | } 35 | 36 | @Test 37 | public void testPlain() throws Exception { 38 | assertEquals(getGoldenFileContent("plain.pass"), getTestResult("plain.md")); 39 | } 40 | } -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/highlighter/MarkdownLexerVisitorBasicsTest.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.highlighter; 3 | 4 | import java.io.IOException; 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit tests for {@link MarkdownLexerVisitor} when used with the PegDown extensions to standard Markdown. 9 | * At the moment only basic properties of the generated token sequence are checked: 10 | *
    11 | *
  • All tokens have non-zero length.
  • 12 | *
  • The total length of all tokens is equal to the length of the input.
  • 13 | *
14 | */ 15 | public class MarkdownLexerVisitorBasicsTest extends MarkdownLexerVisitorTestSupport { 16 | @Test 17 | public void testHeaders() throws IOException { 18 | runTestWithExtensions("basics/header", 0); 19 | } 20 | @Test 21 | public void testQuotes() throws IOException { 22 | runTestWithExtensions("basics/quote", 0); 23 | } 24 | 25 | @Test 26 | public void testOrderedLists() throws IOException { 27 | runTestWithExtensions("basics/list_ordered", 0); 28 | } 29 | 30 | @Test 31 | public void testUnorderedLists() throws IOException { 32 | runTestWithExtensions("basics/list_unordered", 0); 33 | } 34 | 35 | @Test 36 | public void testHorizontalRules() throws IOException { 37 | runTestWithExtensions("basics/horizontal_rule", 0); 38 | } 39 | 40 | @Test 41 | public void testEmphasis() throws IOException { 42 | runTestWithExtensions("basics/emphasis", 0); 43 | } 44 | 45 | @Test 46 | public void testAutoLinks() throws IOException { 47 | runTestWithExtensions("basics/link_auto", 0); 48 | } 49 | 50 | @Test 51 | public void testInlineLinks() throws IOException { 52 | runTestWithExtensions("basics/link_inline", 0); 53 | } 54 | 55 | @Test 56 | public void testReferenceLinks() throws IOException { 57 | runTestWithExtensions("basics/link_reference", 0); 58 | } 59 | 60 | @Test 61 | public void testInlineImages() throws IOException { 62 | runTestWithExtensions("basics/image_inline", 0); 63 | } 64 | 65 | @Test 66 | public void testReferenceImages() throws IOException { 67 | runTestWithExtensions("basics/image_reference", 0); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/highlighter/MarkdownLexerVisitorTestSupport.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.highlighter; 3 | 4 | import static org.junit.Assert.*; 5 | import static org.hamcrest.CoreMatchers.equalTo; 6 | import static org.hamcrest.CoreMatchers.notNullValue; 7 | import static flow.netbeans.markdown.matchers.Matchers.*; 8 | 9 | import java.io.FileNotFoundException; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.io.InputStreamReader; 13 | import java.util.List; 14 | import org.pegdown.PegDownProcessor; 15 | import org.pegdown.ast.RootNode; 16 | 17 | /** 18 | * 19 | * @author Holger 20 | */ 21 | public class MarkdownLexerVisitorTestSupport { 22 | public static final String TEST_RESOURCES = "/flow/netbeans/markdown/testresources/"; 23 | 24 | public MarkdownLexerVisitorTestSupport() { 25 | } 26 | 27 | public void runTestWithExtensions(String baseName, int extensions) throws IOException { 28 | String source = getTestResourceAsString(baseName + ".md"); 29 | PegDownProcessor processor = new PegDownProcessor(extensions); 30 | RootNode rootNode = processor.parseMarkdown(source.toCharArray()); 31 | 32 | assertThat("rootNode", rootNode, notNullValue()); 33 | 34 | final int totalLength = source.length(); 35 | MarkdownTokenListBuilder builder = new MarkdownTokenListBuilder(totalLength); 36 | MarkdownLexerVisitor visitor = new MarkdownLexerVisitor(builder); 37 | rootNode.accept(visitor); 38 | List tokens = builder.build(); 39 | 40 | assertThat(tokens, everyItem(nonZeroLength())); 41 | assertThat(totalLengthOf(tokens), equalTo(totalLength)); 42 | } 43 | 44 | public String getTestResourceAsString(String name) throws IOException { 45 | final String fullName = TEST_RESOURCES + name; 46 | InputStream stream = getClass().getResourceAsStream(fullName); 47 | if (stream == null) { 48 | throw new FileNotFoundException("Test resource not found: " + fullName); 49 | } 50 | try { 51 | InputStreamReader reader = new InputStreamReader(stream, "UTF-8"); 52 | StringBuilder sb = new StringBuilder(); 53 | try { 54 | char[] buffer = new char[4096]; 55 | boolean done = false; 56 | while (!done) { 57 | int count = reader.read(buffer); 58 | if (count < 0) { 59 | done = true; 60 | } else { 61 | sb.append(buffer, 0, count); 62 | } 63 | } 64 | return buffer.toString(); 65 | } 66 | finally { 67 | try { 68 | reader.close(); 69 | } 70 | catch (IOException ex) { 71 | // Ignore. 72 | } 73 | } 74 | } 75 | finally { 76 | try { 77 | stream.close(); 78 | } catch (IOException ex) { 79 | // Ignore. 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/highlighter/MarkdownTokenIdTest.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.highlighter; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.util.ArrayList; 6 | import java.util.Collection; 7 | import java.util.Properties; 8 | import javax.xml.parsers.DocumentBuilder; 9 | import javax.xml.parsers.DocumentBuilderFactory; 10 | import javax.xml.parsers.ParserConfigurationException; 11 | import javax.xml.xpath.XPath; 12 | import javax.xml.xpath.XPathConstants; 13 | import javax.xml.xpath.XPathExpressionException; 14 | import javax.xml.xpath.XPathFactory; 15 | import org.junit.BeforeClass; 16 | import org.junit.Test; 17 | import org.junit.runner.RunWith; 18 | import org.junit.runners.Parameterized; 19 | import org.w3c.dom.Document; 20 | import org.w3c.dom.NodeList; 21 | import org.xml.sax.SAXException; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | import static org.junit.Assert.assertNotNull; 25 | 26 | /** 27 | * The unit tests in this class verify that all token IDs are correctly 28 | * registered in the editor font and color settings. 29 | * 30 | * @author Holger Stenger 31 | */ 32 | @RunWith(Parameterized.class) 33 | public class MarkdownTokenIdTest { 34 | 35 | private static final String FONT_AND_COLORS_PATH = "flow/netbeans/markdown/resources/FontAndColors.xml"; 36 | 37 | private static final String BUNDLE_PATH = "flow/netbeans/markdown/resources/Bundle.properties"; 38 | 39 | private static Document fontAndColorsDoc; 40 | private static Properties props; 41 | 42 | private final MarkdownTokenId tokenId; 43 | 44 | public MarkdownTokenIdTest(final MarkdownTokenId tokenId) { 45 | this.tokenId = tokenId; 46 | } 47 | 48 | @Parameterized.Parameters 49 | public static Collection getParameters() { 50 | Collection parameters = new ArrayList(); 51 | for (MarkdownTokenId tokenId : MarkdownTokenId.values()) { 52 | parameters.add(new Object[]{tokenId}); 53 | } 54 | return parameters; 55 | } 56 | 57 | @BeforeClass 58 | public static void readFontAndColorsXML() throws SAXException, IOException, ParserConfigurationException { 59 | InputStream stream = MarkdownTokenIdTest.class.getClassLoader().getResourceAsStream(FONT_AND_COLORS_PATH); 60 | assertNotNull("input stream for FontAndColors.xml", stream); 61 | try { 62 | DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 63 | DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); 64 | fontAndColorsDoc = docBuilder.parse(stream); 65 | } finally { 66 | try { 67 | stream.close(); 68 | } catch (IOException ex) { 69 | } 70 | } 71 | } 72 | 73 | @BeforeClass 74 | public static void readBundleProperties() throws IOException { 75 | InputStream stream = MarkdownTokenIdTest.class.getClassLoader().getResourceAsStream(BUNDLE_PATH); 76 | assertNotNull("input stream for Bundle.properties", stream); 77 | try { 78 | props = new Properties(); 79 | props.load(stream); 80 | } finally { 81 | try { 82 | stream.close(); 83 | } catch (IOException ex) { 84 | } 85 | } 86 | } 87 | 88 | @Test 89 | public void testFontAndColorsContainsEntryForPrimaryCategory() throws XPathExpressionException { 90 | XPath xpath = XPathFactory.newInstance().newXPath(); 91 | String expression = "/fontscolors/fontcolor[@name='" + tokenId.primaryCategory() + "']"; 92 | NodeList nodes = (NodeList) xpath.evaluate(expression, fontAndColorsDoc.getDocumentElement(), XPathConstants.NODESET); 93 | assertEquals(tokenId.toString(), 1, nodes.getLength()); 94 | } 95 | 96 | @Test 97 | public void testBundleDefinesDisplayNameForPrimaryCategory() { 98 | String displayName = props.getProperty(tokenId.primaryCategory()); 99 | assertNotNull(tokenId.toString(), displayName); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/highlighter/MarkdownTokenListBuilderTest.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.highlighter; 3 | 4 | import java.util.List; 5 | import org.junit.Test; 6 | import static org.junit.Assert.*; 7 | import static org.hamcrest.CoreMatchers.equalTo; 8 | import static flow.netbeans.markdown.matchers.Matchers.*; 9 | import static flow.netbeans.markdown.highlighter.MarkdownTokenId.*; 10 | 11 | import org.junit.Before; 12 | 13 | /** 14 | * Unit tests for {@link MarkdownTokenListBuilder}. 15 | */ 16 | public class MarkdownTokenListBuilderTest { 17 | private static final int DEFAULT_INPUT_LENGTH = 10; 18 | 19 | private MarkdownTokenListBuilder builder; 20 | 21 | @Before 22 | public void createBuilder() { 23 | builder = new MarkdownTokenListBuilder(DEFAULT_INPUT_LENGTH); 24 | } 25 | 26 | @Test 27 | public void testNoToken() { 28 | final List tokens = builder.build(); 29 | 30 | assertThat(tokens, everyItem(nonZeroLength())); 31 | assertThat(totalLengthOf(tokens), equalTo(DEFAULT_INPUT_LENGTH)); 32 | 33 | assertThat(tokens.size(), equalTo(1)); 34 | } 35 | 36 | @Test 37 | public void testSingleTokenWithFullCoverage() { 38 | builder.addLeafTreeToken(CODE, 0, DEFAULT_INPUT_LENGTH); 39 | 40 | final List tokens = builder.build(); 41 | 42 | assertThat(tokens, everyItem(nonZeroLength())); 43 | assertThat(totalLengthOf(tokens), equalTo(DEFAULT_INPUT_LENGTH)); 44 | 45 | assertThat(tokens.size(), equalTo(1)); 46 | assertThat(tokens, containsTokensWithId(CODE)); 47 | } 48 | 49 | @Test 50 | public void testSingleTokenWithoutFullCoverage() { 51 | builder.addLeafTreeToken(CODE, 1, DEFAULT_INPUT_LENGTH - 1); 52 | 53 | final List tokens = builder.build(); 54 | 55 | assertThat(tokens, everyItem(nonZeroLength())); 56 | assertThat(totalLengthOf(tokens), equalTo(DEFAULT_INPUT_LENGTH)); 57 | 58 | assertThat(tokens.size(), equalTo(3)); 59 | assertThat(tokens, containsTokensWithId(PLAIN, CODE, PLAIN)); 60 | assertThat(tokens, containsTokensWithLength(1, DEFAULT_INPUT_LENGTH - 2, 1)); 61 | } 62 | 63 | @Test 64 | public void testNestedTokenWithLargerRangeThanOuterToken() { 65 | builder.beginTreeToken(CODE, 1, DEFAULT_INPUT_LENGTH - 1); 66 | builder.addLeafTreeToken(EMPH, 0, DEFAULT_INPUT_LENGTH); 67 | builder.endTreeToken(); 68 | 69 | final List tokens = builder.build(); 70 | 71 | assertThat(tokens, everyItem(nonZeroLength())); 72 | assertThat(totalLengthOf(tokens), equalTo(DEFAULT_INPUT_LENGTH)); 73 | 74 | assertThat(tokens.size(), equalTo(3)); 75 | assertThat(tokens, containsTokensWithId(PLAIN, EMPH, PLAIN)); 76 | assertThat(tokens, containsTokensWithLength(1, DEFAULT_INPUT_LENGTH - 2, 1)); 77 | } 78 | 79 | @Test 80 | public void testEmptyInput() { 81 | builder = new MarkdownTokenListBuilder(0); 82 | 83 | List tokens = builder.build(); 84 | 85 | assertThat(tokens.size(), equalTo(0)); 86 | } 87 | 88 | @Test(expected = IllegalStateException.class) 89 | public void testUnmatchedEndTokenCall() { 90 | builder.endTreeToken(); 91 | } 92 | 93 | @Test(expected = IllegalStateException.class) 94 | public void testUnmatchedBeginTokenCall() { 95 | builder.beginTreeToken(CODE, 0, DEFAULT_INPUT_LENGTH); 96 | 97 | builder.build(); 98 | } 99 | 100 | @Test(expected = IllegalStateException.class) 101 | public void testBeginTokenCallAfterBuild() { 102 | builder.build(); 103 | 104 | builder.beginTreeToken(CODE, 0, DEFAULT_INPUT_LENGTH); 105 | } 106 | 107 | @Test 108 | public void testBuildTwice() { 109 | builder.build(); 110 | try { 111 | builder.build(); 112 | } catch (IllegalStateException ex) { 113 | fail("Failed to build twice"); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/matchers/ContainsTokensWithId.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.matchers; 3 | 4 | import flow.netbeans.markdown.highlighter.MarkdownToken; 5 | import flow.netbeans.markdown.highlighter.MarkdownTokenId; 6 | import java.util.Iterator; 7 | import org.hamcrest.Description; 8 | import org.junit.internal.matchers.TypeSafeMatcher; 9 | 10 | /** 11 | * 12 | * @author Holger 13 | */ 14 | public class ContainsTokensWithId extends TypeSafeMatcher> { 15 | private final MarkdownTokenId[] ids; 16 | 17 | public ContainsTokensWithId(MarkdownTokenId... ids) { 18 | this.ids = ids.clone(); 19 | } 20 | 21 | @Override 22 | public boolean matchesSafely(Iterable item) { 23 | Iterator iterator = item.iterator(); 24 | boolean result = true; 25 | int index; 26 | for (index = 0; index < ids.length && iterator.hasNext() && result; ++index) { 27 | MarkdownToken token = iterator.next(); 28 | if (!token.getId().equals(ids[index])) { 29 | return false; 30 | } 31 | } 32 | if (index < ids.length || iterator.hasNext()) { 33 | return false; 34 | } 35 | return true; 36 | } 37 | 38 | @Override 39 | public void describeTo(Description description) { 40 | description.appendText("token ids not equal to "); 41 | description.appendValueList("", ", ", "", ids); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/matchers/ContainsTokensWithLength.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.matchers; 3 | 4 | import flow.netbeans.markdown.highlighter.MarkdownToken; 5 | import java.util.Arrays; 6 | import java.util.Iterator; 7 | import org.hamcrest.Description; 8 | import org.junit.internal.matchers.TypeSafeMatcher; 9 | 10 | /** 11 | * 12 | * @author Holger 13 | */ 14 | class ContainsTokensWithLength extends TypeSafeMatcher> { 15 | private final int[] lengths; 16 | 17 | public ContainsTokensWithLength(int... lengths) { 18 | this.lengths = lengths.clone(); 19 | } 20 | 21 | @Override 22 | public boolean matchesSafely(Iterable item) { 23 | Iterator iterator = item.iterator(); 24 | boolean result = true; 25 | int index; 26 | for (index = 0; index < lengths.length && iterator.hasNext() && result; ++index) { 27 | MarkdownToken token = iterator.next(); 28 | if (token.getLength() != lengths[index]) { 29 | return false; 30 | } 31 | } 32 | if (index < lengths.length || iterator.hasNext()) { 33 | return false; 34 | } 35 | return true; 36 | } 37 | 38 | @Override 39 | public void describeTo(Description description) { 40 | description.appendText("token lengths not equal to "); 41 | description.appendValueList("", ", ", "", Arrays.asList(lengths)); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/matchers/Empty.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.matchers; 2 | 3 | import java.util.Collection; 4 | import org.hamcrest.Description; 5 | import org.junit.internal.matchers.TypeSafeMatcher; 6 | 7 | /** 8 | * 9 | * @author Holger 10 | */ 11 | class Empty extends TypeSafeMatcher> { 12 | public Empty() { 13 | } 14 | 15 | @Override 16 | public boolean matchesSafely(Collection item) { 17 | return item.isEmpty(); 18 | } 19 | 20 | @Override 21 | public void describeTo(Description description) { 22 | description.appendText("collection is not empty"); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/matchers/EveryItem.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.matchers; 2 | 3 | import java.util.Iterator; 4 | import org.hamcrest.Description; 5 | import org.hamcrest.Matcher; 6 | import org.junit.internal.matchers.TypeSafeMatcher; 7 | 8 | /** 9 | * 10 | * @author Holger 11 | */ 12 | public class EveryItem extends TypeSafeMatcher> { 13 | private final Matcher itemMatcher; 14 | 15 | public EveryItem(Matcher itemMatcher) { 16 | this.itemMatcher = itemMatcher; 17 | } 18 | 19 | @Override 20 | public boolean matchesSafely(Iterable item) { 21 | boolean result = true; 22 | Iterator iterator = item.iterator(); 23 | while (result && iterator.hasNext()) { 24 | final T element = iterator.next(); 25 | if (!itemMatcher.matches(element)) { 26 | result = false; 27 | } 28 | } 29 | return result; 30 | } 31 | 32 | @Override 33 | public void describeTo(Description description) { 34 | description.appendText("contains an element with "); 35 | description.appendDescriptionOf(itemMatcher); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/matchers/Matchers.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.matchers; 3 | 4 | import flow.netbeans.markdown.highlighter.MarkdownToken; 5 | import flow.netbeans.markdown.highlighter.MarkdownTokenId; 6 | import org.hamcrest.Matcher; 7 | 8 | /** 9 | * 10 | * @author Holger 11 | */ 12 | public class Matchers { 13 | private Matchers() {} 14 | 15 | public static Matcher> everyItem(Matcher itemMatcher) { 16 | return new EveryItem(itemMatcher); 17 | } 18 | 19 | public static Matcher nonZeroLength() { 20 | return new NonZeroLength(); 21 | } 22 | 23 | public static int totalLengthOf(Iterable iterable) { 24 | int totalLength = 0; 25 | for (MarkdownToken token : iterable) { 26 | totalLength += token.getLength(); 27 | } 28 | return totalLength; 29 | } 30 | 31 | public static Matcher> containsTokensWithId(final MarkdownTokenId... ids) { 32 | return new ContainsTokensWithId(ids); 33 | } 34 | 35 | public static Matcher> containsTokensWithLength(final int... lengths) { 36 | return new ContainsTokensWithLength(lengths); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/matchers/NonZeroLength.java: -------------------------------------------------------------------------------- 1 | 2 | package flow.netbeans.markdown.matchers; 3 | 4 | import flow.netbeans.markdown.highlighter.MarkdownToken; 5 | import org.hamcrest.Description; 6 | import org.junit.internal.matchers.TypeSafeMatcher; 7 | 8 | /** 9 | * 10 | * @author Holger 11 | */ 12 | public class NonZeroLength extends TypeSafeMatcher { 13 | 14 | public NonZeroLength() { 15 | } 16 | 17 | @Override 18 | public boolean matchesSafely(MarkdownToken item) { 19 | return item.getLength() > 0; 20 | } 21 | 22 | @Override 23 | public void describeTo(Description description) { 24 | description.appendText("length zero"); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/code_block.md: -------------------------------------------------------------------------------- 1 |
    2 |
  • Code
  • 3 |
  • Block
  • 4 |
-------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/code_inline.md: -------------------------------------------------------------------------------- 1 | `` 2 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/emphasis.md: -------------------------------------------------------------------------------- 1 | Some of these words *are emphasized*. 2 | Some of these words _are emphasized also_. 3 | 4 | Use two asterisks for **strong emphasis**. 5 | Or, if you prefer, __use two underscores instead__. 6 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/header.md: -------------------------------------------------------------------------------- 1 | Header Level 1 2 | ============== 3 | 4 | Header Level 2 5 | -------------- 6 | 7 | # Header Level 1 8 | ## Header Level 2 9 | ### Header Level 3 10 | #### Header Level 4 11 | ##### Header Level 5 12 | ###### Header Level 6 13 | ####### Also Header Level 6 14 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/horizontal_rule.md: -------------------------------------------------------------------------------- 1 | Paragraph 1 2 | 3 | * * * 4 | 5 | Paragraph 2 6 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/image_inline.md: -------------------------------------------------------------------------------- 1 | ![alt text](/path/to/img.jpg "Title") 2 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/image_reference.md: -------------------------------------------------------------------------------- 1 | ![alt text][id] 2 | 3 | [id]: /path/to/img.jpg "Title" 4 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/link_auto.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/link_inline.md: -------------------------------------------------------------------------------- 1 | [link](http://example.com/) 2 | [link](http://example.com/ "Title") 3 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/link_reference.md: -------------------------------------------------------------------------------- 1 | [link][1] 2 | [link][example] 3 | [link][] 4 | 5 | [1]: http://example.com/ 6 | [example]: http://example.com/ "Title" 7 | [link]: http://example.com/ 8 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/list_ordered.md: -------------------------------------------------------------------------------- 1 | 1. Item 1 2 | 1. Item 2 3 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/list_unordered.md: -------------------------------------------------------------------------------- 1 | - Item A 2 | - Item B 3 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/basics/quote.md: -------------------------------------------------------------------------------- 1 | > This is a quote. 2 | > 3 | > It spans multiple lines. 4 | >> This is a nested quote. 5 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/extensions/abbreviations.md: -------------------------------------------------------------------------------- 1 | The HTML specification is maintained by the W3C. 2 | 3 | *[HTML]: Hyper Text Markup Language 4 | *[W3C]: World Wide Web Consortium 5 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/extensions/autolinks.md: -------------------------------------------------------------------------------- 1 | Undelimited http://example.com link 2 | Undelimited user@example.com link -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/extensions/definitions.md: -------------------------------------------------------------------------------- 1 | Apple 2 | : Pomaceous fruit of plants of the genus Malus in 3 | the family Rosaceae. 4 | 5 | Orange 6 | : The fruit of an evergreen tree of the genus Citrus. 7 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/extensions/fenced_code_blocks.md: -------------------------------------------------------------------------------- 1 | ``` 2 | Fenced code block (GitHub Flavored Markdown) 3 | ``` 4 | 5 | ~~~~ 6 | Fenced code block (PHP Markdown Extras) 7 | ~~~~ 8 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/extensions/hardwraps.md: -------------------------------------------------------------------------------- 1 | Roses are red 2 | Violets are blue 3 | 4 | Roses are red 5 | Violets are blue 6 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/extensions/quotes.md: -------------------------------------------------------------------------------- 1 | We have 'single' quotes, "double" quotes and <> quotes. -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/extensions/smarts.md: -------------------------------------------------------------------------------- 1 | Ellipses ... and . . . 2 | En dash -- 3 | Em dash --- 4 | Apostrophe ' -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/extensions/suppress_html_blocks.md: -------------------------------------------------------------------------------- 1 | Paragraph before HTML block. 2 | 3 |

4 | This is an HTML block. 5 |

6 | 7 | Paragraph after HTML block. 8 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/extensions/suppress_inline_html.md: -------------------------------------------------------------------------------- 1 | This is inline HTML. -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/extensions/tables.md: -------------------------------------------------------------------------------- 1 | | | Grouping || 2 | | First Header | Second Header | Third Header | 3 | | ------------ | :-----------: | -----------: | 4 | | Content | *Long Cell* || 5 | | Content | **Cell** | Cell | 6 | | New section | More | Data | 7 | -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/testresources/extensions/wikilinks.md: -------------------------------------------------------------------------------- 1 | Wikilink without title [[http://en.wikipedia.org/wiki/]] 2 | Wikilink with title [[http://en.wikipedia.org/wiki/ "Wikipedia Main Page"]] -------------------------------------------------------------------------------- /test/unit/src/flow/netbeans/markdown/utils/MarkdownDocUtilTest.java: -------------------------------------------------------------------------------- 1 | package flow.netbeans.markdown.utils; 2 | 3 | import flow.netbeans.markdown.highlighter.MarkdownTokenId; 4 | import javax.swing.text.BadLocationException; 5 | import javax.swing.text.DefaultStyledDocument; 6 | import org.junit.Test; 7 | import org.netbeans.api.lexer.Language; 8 | import org.netbeans.junit.NbTestCase; 9 | 10 | /** 11 | * 12 | * @author junichi11 13 | */ 14 | public class MarkdownDocUtilTest extends NbTestCase { 15 | 16 | public MarkdownDocUtilTest(String name) { 17 | super(name); 18 | } 19 | 20 | /** 21 | * Test of getIndentString method, of class MarkdownDocUtil. 22 | * 23 | * @throws javax.swing.text.BadLocationException 24 | */ 25 | @Test 26 | public void testGetIndentString() throws BadLocationException { 27 | DefaultStyledDocument document = new DefaultStyledDocument(); 28 | document.putProperty(Language.class, MarkdownTokenId.language()); 29 | document.insertString(0, " * list\n", null); // white space 30 | String result = MarkdownDocUtil.getIndentString(document, 10); 31 | assertEquals(" ", result); 32 | 33 | document.insertString(0, " * list\n", null); // tab space 34 | result = MarkdownDocUtil.getIndentString(document, 7); 35 | assertEquals(" ", result); 36 | 37 | document.insertString(0, " * list\n", null); // white space and tab space 38 | result = MarkdownDocUtil.getIndentString(document, 11); 39 | assertEquals(" ", result); 40 | 41 | document.insertString(0, "* list\n", null); // no indent 42 | result = MarkdownDocUtil.getIndentString(document, 6); 43 | assertEquals("", result); 44 | } 45 | 46 | } 47 | --------------------------------------------------------------------------------