Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork184
Angular markdown component/directive/pipe/service to parse static, dynamic or remote content to HTML with syntax highlight and more...
License
jfcere/ngx-markdown
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
ngx-markdown is anAngular library that combines...
- Marked to parse markdown to HTML
- Prism.js for language syntax highlight
- Emoji-Toolkit for emoji support
- KaTeX for math expression rendering
- Mermaid for diagrams and charts visualization
- Clipboard.js to copy code blocks to clipboard
Demo available @https://jfcere.github.io/ngx-markdown
StackBlitz available @https://stackblitz.com/edit/ngx-markdown
- Installation
- Configuration
- Usage
- Renderer
- Syntax highlight
- Demo application
- AoT compilation
- Road map
- Contribution
- Support Development
To add ngx-markdown along with the required marked library to yourpackage.json
use the following commands.
npm install ngx-markdown marked@^16.0.0 --save
🔔 Syntax highlight isoptional, skip this step if you are not planning to use it
To addPrism.js library to yourpackage.json
use the following command.
npm install prismjs@^1.30.0 --save
To activatePrism.js syntax highlight you will need to include...
- prism.js core library -
node_modules/prismjs/prism.js
file - a highlight css theme - from
node_modules/prismjs/themes
directory - desired code language syntax files - from
node_modules/prismjs/components
directory
Additional themes can be found by browsing the web such asPrism-Themes orMokokai for example.
If you are usingAngular CLI you can follow theangular.json
example below...
"styles": [ "styles.css",+ "node_modules/prismjs/themes/prism-okaidia.css"],"scripts": [+ "node_modules/prismjs/prism.js",+ "node_modules/prismjs/components/prism-csharp.min.js", # c-sharp language syntax+ "node_modules/prismjs/components/prism-css.min.js" # css language syntax]
To use theline numbers plugin that shows line numbers in code blocks, in addition to Prism.js configuration files, you will need to include the following files fromprismjs/plugins/line-numbers
directory to your application:
- CSS styling for line numbers -
prism-line-numbers.css
- line numbers plugin script -
prism-line-numbers.js
If you are usingAngular CLI you can follow theangular.json
example below...
"styles": [ "src/styles.css", "node_modules/prismjs/themes/prism-okaidia.css",+ "node_modules/prismjs/plugins/line-numbers/prism-line-numbers.css"],"scripts": [ "node_modules/prismjs/prism.js", "node_modules/prismjs/components/prism-csharp.min.js", "node_modules/prismjs/components/prism-css.min.js",+ "node_modules/prismjs/plugins/line-numbers/prism-line-numbers.js"]
Usingmarkdown
component and/or directive, you will be able to use thelineNumbers
property to activate the plugin. The property can be used in combination with eitherdata
for variable binding,src
for remote content or using transclusion for static markdown.
Additionally, you can usestart
input property to specify the offset number for the first display line.
<markdownlineNumbers[start]="5"[src]="path/to/file.js"></markdown>
To use theline highlight plugin that highlights specific lines and/or line ranges in code blocks, in addition to Prism.js configuration files, you will need to include the following files fromprismjs/plugins/line-highlight
directory to your application:
- CSS styling for line highlight -
prism-line-highlight.css
- line highlight plugin script -
prism-line-highlight.js
If you are usingAngular CLI you can follow theangular.json
example below...
"styles": [ "src/styles.css", "node_modules/prismjs/themes/prism-okaidia.css",+ "node_modules/prismjs/plugins/line-highlight/prism-line-highlight.css"],"scripts": [ "node_modules/prismjs/prism.js", "node_modules/prismjs/components/prism-csharp.min.js", "node_modules/prismjs/components/prism-css.min.js",+ "node_modules/prismjs/plugins/line-highlight/prism-line-highlight.js"]
Usingmarkdown
component and/or directive, you will be able to use thelineHighlight
property to activate the plugin. The property can be used in combination with eitherdata
for variable binding,src
for remote content or using transclusion for static markdown.
Useline
input property to specify the line(s) to highlight and optionally there is alineOffset
property to specify the starting line of code your snippet represents.
<markdownlineHighlight[line]="'6, 10-16'"[lineOffset]="5"[src]="path/to/file.js"></markdown>
To use thecommand line plugin that displays a command line with a prompt and, optionally, the output/response from the commands, you will need to include the following files fromprismjs/plugins/command-line
directory to your application:
- CSS styling for command line -
prism-command-line.css
- command line plugin script -
prism-command-line.js
If you are usingAngular CLI you can follow theangular.json
example below...
"styles": [ "src/styles.css", "node_modules/prismjs/themes/prism-okaidia.css",+ "node_modules/prismjs/plugins/command-line/prism-command-line.css"],"scripts": [ "node_modules/prismjs/prism.js", "node_modules/prismjs/components/prism-csharp.min.js", "node_modules/prismjs/components/prism-css.min.js",+ "node_modules/prismjs/plugins/command-line/prism-command-line.js"]
Usingmarkdown
component and/or directive, you will be able to use thecommandLine
property to activate the plugin. The property can be used in combination with eitherdata
for variable binding,src
for remote content or using transclusion for static markdown.
For a server command line, specify the user and host names using theuser
andhost
input properties. The resulting prompt displays a#
for the root user and$
for all other users. For any other command line, such as a Windows prompt, you may specify the entire prompt using theprompt
input property.
You may also specify the lines to be presented as output (no prompt and no highlighting) through theoutput
property in the following simple format:
- A single number refers to the line with that number
- Ranges are denoted by two numbers, separated with a hyphen (-)
- Multiple line numbers or ranges are separated by commas
- Whitespace is allowed anywhere and will be stripped off
<markdowncommandLine[user]="'chris'"[host]="'remotehost'"[output]="'2, 4-8'"[src]="'path/to/file.bash'"></markdown>
Optionally, to automatically present some lines as output without providing the line numbers, you can prefix those lines with any string and specify the prefix using thefilterOutput
input property. For example,[filterOutput]="'(out)'"
will treat lines beginning with(out)
as output and remove the prefix.
<markdowncommandLine[prompt]="'PS C:\Users\Chris>'"[filterOutput]="'(out)'"> ```powershell Get-Date (out) (out)Sunday, November 7, 2021 8:19:21 PM (out) ```</markdown>
🔔 Emoji support isoptional, skip this step if you are not planning to use it
To addEmoji-Toolkit library to yourpackage.json
use the following command.
npm install emoji-toolkit@^9.0.0 --save
To activateEmoji-Toolkit for emoji suppport you will need to include...
- Emoji-Toolkit library -
node_modules/emoji-toolkit/lib/js/joypixels.min.js
If you are usingAngular CLI you can follow theangular.json
example below...
"scripts": [+ "node_modules/emoji-toolkit/lib/js/joypixels.min.js",]
Usingmarkdown
component and/or directive, you will be able to use theemoji
property to activateEmoji-Toolkit plugin that converts emoji shortnames such as:heart:
to native unicode emojis.
<markdownemoji> I :heart: ngx-markdown</markdown>
📘 You can refer to thisEmoji Cheat Sheet for a complete list ofshortnames.
🔔 Math rendering isoptional, skip this step if you are not planning to use it
To addKaTeX library to yourpackage.json
use the following command.
npm install katex@^0.16.0 --save
To activateKaTeX math rendering you will need to include...
- KaTex JavaScript library -
node_modules/katex/dist/katex.min.js
file - KaTex Auto-Render extension -
node_modules/katex/dist/contrib/auto-render.min.js,
file - KaTex CSS customization -
node_modules/katex/dist/katex.min.css
file
If you are usingAngular CLI you can follow theangular.json
example below...
"styles": [ "styles.css",+ "node_modules/katex/dist/katex.min.css"],"scripts": [+ "node_modules/katex/dist/katex.min.js",+ "node_modules/katex/dist/contrib/auto-render.min.js",]
Usingmarkdown
component and/or directive, you will be able to use thekatex
property to activateKaTeX plugin that renders mathematical expression to HTML.
<markdownkatex[src]="path/to/file.md"></markdown>
Optionally, you can usekatexOptions
property to specify both theKaTeX options and theKaTeX Auto-Render options.
import{KatexOptions}from'ngx-markdown';public options:KatexOptions={displayMode:true,throwOnError:false,errorColor:'#cc0000',delimiters:[...], ...};
<markdownkatex[katexOptions]="options"[src]="path/to/file.md"></markdown>
📘 Follow officialKaTeX options andKaTeX Auto-Render options documentation for more details on the available options.
🔔 Diagram support isoptional, skip this step if you are not planning to use it
To addMermaid library to yourpackage.json
use the following command.
npm install mermaid@^11.0.0 --save
To activateMermaid diagramming and charting tool you will need to include...
- Mermaid JavaScript library -
node_modules/mermaid/dist/mermaid.min.js
file
If you are usingAngular CLI you can follow theangular.json
example below...
"scripts": [+ "node_modules/mermaid/dist/mermaid.min.js",]
Usingmarkdown
component and/or directive, you will be able to use themermaid
property to activateMermaid plugin that renders Markdown-inspired text definitions to create and modify diagrams dynamically.
<markdownmermaid[src]="path/to/file.md"></markdown>
You can provide a global configuration for mermaidconfiguration options to use across your application with themermaidOptions
in theMarkdownModuleConfig
either withprovideMarkdown
provide-function for standalone components orMarkdownModule.forRoot()
for module configuration.
provideMarkdown({mermaidOptions:{provide:MERMAID_OPTIONS,useValue:{darkMode:true,look:'handDrawn', ...},},}),
MarkdownModule.forRoot({mermaidOptions:{provide:MERMAID_OPTIONS,useValue:{darkMode:true,look:'handDrawn', ...},},}),
Additionally, you can specify mermaidconfiguration options on component directly usingmermaidOptions
property.
import{MermaidAPI}from'ngx-markdown';public options:MermaidAPI.MermaidConfig={darkMode:true,look:'handDrawn', ...};
<markdownmermaid[mermaidOptions]="options"[src]="'path/to/file.md'"></markdown>
📘 Follow officialMermaid documentation for more details on diagrams and charts syntax.
🔔 Copy-to-clipboard support isoptional, skip this step if you are not planning to use it
To addClipboard library to yourpackage.json
use the following command.
npm install clipboard@^2.0.11 --save
To activateClipboard allowing copy-to-clipboard you will need to include...
- Clipboard JavaScript library -
node_modules/clipboard/dist/clipboard.min.js
file
If you are usingAngular CLI you can follow theangular.json
example below...
"scripts": [+ "node_modules/clipboard/dist/clipboard.min.js",]
Usingmarkdown
component and/or directive, you will be able to use theclipboard
property to activateClipboard plugin that enable copy-to-clipboard for code block from a single click.
<markdownclipboard[src]="path/to/file.md"></markdown>
Theclipboard
plugin provide an unstyled default button with a default behavior out of the box if no alternative is used.
The clipboard button is placed inside a wrapper element that can be customize using the.markdown-clipboard-toolbar
CSS selector in your globalstyles.css/scss
file.
This allows to override the default positionning of the clipboard button and play with the visibility of the button using the.hover
CSS selector that is applied on the toolbar when the mouse cursor enters and leaves the code block element.
To customize the default button styling, use the.markdown-clipboard-button
CSS selector in your globalstyles.css/scss
file. You can also customized the "copied" state happening after the button is clicked using the.copied
CSS selector.
You can provide a custom component to use globaly across your application with theclipboardOptions
in theMarkdownModuleConfig
either withprovideMarkdown
provide-function for standalone components orMarkdownModule.forRoot()
for module configuration.
provideMarkdown({clipboardOptions:{provide:CLIPBOARD_OPTIONS,useValue:{buttonComponent:ClipboardButtonComponent,},},})
MarkdownModule.forRoot({clipboardOptions:{provide:CLIPBOARD_OPTIONS,useValue:{buttonComponent:ClipboardButtonComponent,},},}),
You can also provide your custom component using theclipboardButtonComponent
input property when using theclipboard
directive.
import{Component}from'@angular/core';@Component({selector:'app-clipboard-button',template:`<button (click)="onClick()">Copy</button>`,})exportclassClipboardButtonComponent{onClick(){alert('Copied to clipboard!');}}
import{ClipboardButtonComponent}from'./clipboard-button-component';@Component({ ...})exportclassExampleComponent{readonlyclipboardButton=ClipboardButtonComponent;}
<markdownclipboard[clipboardButtonComponent]="clipboardButton"></markdown>
Alternatively, theclipboard
directive can be used in conjonction withng-template
to provide a custom button implementation via theclipboardButtonTemplate
input property on themarkdown
component.
<ng-template#buttonTemplate><button(click)="onCopyToClipboard()">...</button></ng-template><markdownclipboard[clipboardButtonTemplate]="buttonTemplate"></markdown>
📘 Refer to the ngx-markdownclipboard plugin demo for live examples.
The ngx-markdown library can be used either with the standalone components or with modules configuration. Please follow the configuration section that matches your application.
Use theprovideMarkdown
provide-function in your application configurationApplicationConfig
to be able to provide theMarkdownComponent
andMarkdownPipe
to your standalone components and/or inject theMarkdownService
.
import { NgModule } from '@angular/core';+ import { provideMarkdown } from 'ngx-markdown';export const appConfig: ApplicationConfig = { providers: [+ provideMarkdown(), ],};
You must importMarkdownModule
inside your main application module (usually named AppModule) withforRoot
to be able to use themarkdown
component, directive, pipe and/orMarkdownService
.
import { NgModule } from '@angular/core';+ import { MarkdownModule } from 'ngx-markdown';import { AppComponent } from './app.component';@NgModule({ imports: [+ MarkdownModule.forRoot(), ], declarations: [AppComponent], bootstrap: [AppComponent],})export class AppModule { }
UseforChild
when importingMarkdownModule
into other application modules to allow you to use the same parser configuration across your application.
import { NgModule } from '@angular/core';+ import { MarkdownModule } from 'ngx-markdown';import { HomeComponent } from './home.component';@NgModule({ imports: [+ MarkdownModule.forChild(), ], declarations: [HomeComponent],})export class HomeModule { }
If you want to use the[src]
attribute to directly load a remote file, in order to keep only one instance ofHttpClient
and avoid issues with interceptors, you also have to provideHttpClient
:
providers: [+ provideHttpClient(),+ provideMarkdown({ loader: HttpClient }),],
imports: [+ HttpClientModule,+ MarkdownModule.forRoot({ loader: HttpClient }),],
Sanitization is enabled by default and uses Angular’sDomSanitizer
withSecurityContext.HTML
to prevent XSS vulnerabilities. It can be disabled by changing theSecurityContext
level using thesanitize
property when configuring theMarkdownModule
.
import{SecurityContext}from'@angular/core';import{SANITIZE}from'ngx-markdown';// enable default sanitizationprovideMarkdown()// disable sanitizationprovideMarkdown({sanitize:{provide:SANITIZE,useValue:SecurityContext.NONE},})
import{SecurityContext}from'@angular/core';import{SANITIZE}from'ngx-markdown';// enable default sanitizationMarkdownModule.forRoot()// disable sanitizationMarkdownModule.forRoot({sanitize:{provide:SANITIZE,useValue:SecurityContext.NONE},})
Because Angular's sanitizer offers limited flexibility, you can use any external library for sanitization such asDOMPurify by providing a custom sanitizer function using theSANITIZE
provider token.
importDOMPurifyfrom'dompurify';import{SANITIZE}from'ngx-markdown';// sanitize function using an external libraryfunctionsanitizeHtml(html:string):string{DOMPurify.setConfig({ ...});returnDOMPurify.sanitize(html);}// provide a sanitize functionprovideMarkdown({sanitize:{provide:SANITIZE,useValue:sanitizeHtml,},})
importDOMPurifyfrom'dompurify';import{SANITIZE}from'ngx-markdown';// sanitize function using an external libraryfunctionsanitizeHtml(html:string):string{DOMPurify.setConfig({ ...});returnDOMPurify.sanitize(html);}// provide a sanitize functionMarkdownModule.forRoot({sanitize:{provide:SANITIZE,useValue:sanitizeHtml,},})
📘 FollowAngular DomSanitizer documentation for more information on sanitization and security contexts.
You can bypass sanitization using the markdown component, directive or pipe using thedisableSanitizer
option as follow:
<!-- disable sanitizer using markdown component --><markdown[data]="markdown"[disableSanitizer]="true"></markdown><!-- disable sanitizer using markdown directive --><divmarkdown[data]="markdown"[disableSanitizer]="true"></div><!-- disable sanitizer using markdown pipe --><div[innerHTML]="markdown | markdown : { disableSanitizer: true } | async"></div>
Optionally, markdown parsing can be configured usingMarkedOptions that can be provided with theMARKED_OPTIONS
injection token via themarkedOptions
property of theforRoot
method ofMarkdownModule
.
// importsimport{MARKED_OPTIONS,provideMarkdown}from'ngx-markdown';// using default optionsprovideMarkdown(),// using specific options with ValueProvider and passing HttpClientprovideMarkdown({markedOptions:{provide:MARKED_OPTIONS,useValue:{gfm:true,breaks:false,pedantic:false,},},}),
// importsimport{MarkdownModule,MARKED_OPTIONS}from'ngx-markdown';// using default optionsMarkdownModule.forRoot(),// using specific options with ValueProvider and passing HttpClientMarkdownModule.forRoot({loader:HttpClient,// optional, only if you use [src] attributemarkedOptions:{provide:MARKED_OPTIONS,useValue:{gfm:true,breaks:false,pedantic:false,},},}),
MarkedOptions
also exposes therenderer
property which allows you to override token rendering for your whole application.
The example uses a factory function and override the default blockquote token rendering by adding a CSS class for custom styling when using Bootstrap CSS:
import{Parser}from'marked';import{MARKED_OPTIONS,MarkedOptions,MarkedRenderer}from'ngx-markdown';// function that returns `MarkedOptions` with renderer overrideexportfunctionmarkedOptionsFactory():MarkedOptions{constrenderer=newMarkedRenderer();renderer.blockquote=({ tokens})=>{return'<blockquote><p>'+Parser.parse(tokens)+'</p></blockquote>';};return{renderer:renderer,gfm:true,breaks:false,pedantic:false,};}
// using specific option with FactoryProviderprovideMarkdown({markedOptions:{provide:MARKED_OPTIONS,useFactory:markedOptionsFactory,},}),
// using specific option with FactoryProviderMarkdownModule.forRoot({markedOptions:{provide:MARKED_OPTIONS,useFactory:markedOptionsFactory,},}),
When configuring theMarkdownModule
, you can providemarked extensions using theMARKED_EXTENSION
injection token via themarkedExtensions
property, which accepts an array of providers and supports Angular dependency injection.
import{gfmHeadingId}from'marked-gfm-heading-id';providemarkdown({markedExtensions:[{provide:MARKED_EXTENSIONS,useFactory:gfmHeadingId,multi:true,},{provide:MARKED_EXTENSIONS,useFactory:myExtensionFactory,deps:[SomeService],multi:true,},],}),
import{gfmHeadingId}from'marked-gfm-heading-id';MarkdownModule.forRoot({markedExtensions:[{provide:MARKED_EXTENSIONS,useFactory:gfmHeadingId,multi:true,},{provide:MARKED_EXTENSIONS,useFactory:myExtensionFactory,deps:[SomeService],multi:true,},],}),
ngx-markdown
provides different approaches to help you parse markdown to your application depending on your needs.
💡 As of Angular 6, the template compiler strips whitespace by default. Use
ngPreserveWhitespaces
directive to preserve whitespaces such as newlines in order for the markdown-formatted content to render as intended.
https://angular.io/api/core/Component#preserveWhitespaces
You can usemarkdown
component to either parse static markdown directly from your HTML markup, load the content from a remote URL usingsrc
property or bind a variable to your component usingdata
property. You can get a hook on load complete usingload
output event property, on loading error usingerror
output event property or when parsing is completed usingready
output event property.
<!-- static markdown --><markdownngPreserveWhitespaces> # Markdown</markdown><!-- loaded from remote url --><markdown[src]="'path/to/file.md'"(load)="onLoad($event)"(error)="onError($event)"></markdown><!-- variable binding --><markdown[data]="markdown"(ready)="onReady()"></markdown><!-- inline parser, omitting rendering top-level paragraph --><markdown[data]="markdown"[inline]="true"></markdown>
The same way the component works, you can usemarkdown
directive to accomplish the same thing.
<!-- static markdown --><divmarkdownngPreserveWhitespaces> # Markdown</div><!-- loaded from remote url --><divmarkdown[src]="'path/to/file.md'"(load)="onLoad($event)"(error)="onError($event)"></div><!-- variable binding --><divmarkdown[data]="markdown"(ready)="onReady()"></div><!-- inline parser, omitting rendering top-level paragraph --><divmarkdown[data]="markdown"[inline]="true"></div>
Usingmarkdown
pipe to transform markdown to HTML allow you to chain pipe transformations and will update the DOM when value changes. It is important to note that, because themarked
parsing method returns aPromise
, it requires the use of theasync
pipe.
<!-- chain `language` pipe with `markdown` pipe to convert typescriptMarkdown variable content --><div[innerHTML]="typescriptMarkdown | language : 'typescript' | markdown | async"></div>
Themarkdown
pipe allow you to use all the same plugins as the component by providing the options parameters.
<!-- provide options parameters to activate plugins or for configuration --><div[innerHTML]="typescriptMarkdown | language : 'typescript' | markdown : { emoji: true, inline: true } | async"></div>
This is theMarkdownPipeOptions
parameters interface, those options are the same as the ones available for themarkdown
component:
exportinterfaceMarkdownPipeOptions{decodeHtml?:boolean;inline?:boolean;emoji?:boolean;katex?:boolean;katexOptions?:KatexOptions;mermaid?:boolean;mermaidOptions?:MermaidAPI.MermaidConfig;markedOptions?:MarkedOptions;disableSanitizer?:boolean;}
You can useMarkdownService
to have access to markdown parsing, rendering and syntax highlight methods.
import{Component,OnInit}from'@angular/core';import{MarkdownService}from'ngx-markdown';@Component({ ...})exportclassExampleComponentimplementsOnInit{constructor(privatemarkdownService:MarkdownService){}ngOnInit(){// outputs: <p>I am using <strong>markdown</strong>.</p>console.log(this.markdownService.parse('I am using __markdown__.'));}}
Tokens can be rendered in a custom manner by either...
- providing the
renderer
property with theMarkedOptions
when importingMarkdownModule.forRoot()
into your main application module (seeConfiguration section) - using
MarkdownService
exposedrenderer
Here is an example of overriding the default heading token rendering throughMarkdownService
by adding an embedded anchor tag like on GitHub:
import{Component,OnInit}from'@angular/core';import{Parser}from'marked';import{MarkdownService}from'ngx-markdown';@Component({selector:'app-example',template:'<markdown># Heading</markdown>',})exportclassExampleComponentimplementsOnInit{constructor(privatemarkdownService:MarkdownService){}ngOnInit(){this.markdownService.renderer.heading=({ tokens, depth})=>{consttext=Parser.parseInline(tokens);constescapedText=text.toLowerCase().replace(/[^\w]+/g,'-');return'<h'+depth+'>'+'<a name="'+escapedText+'" href="#'+escapedText+'">'+'<span></span>'+'</a>'+text+'</h'+depth+'>';};}}
This code will output the following HTML:
<h1><aname="heading"class="anchor"href="#heading"><spanclass="header-link"></span></a> Heading</h1>
📘 Follow officialmarked.renderer documentation for the list of tokens that can be overriden.
In some situations, you might need to re-render markdown after making changes. If you've updated the text this would be done automatically, however if the changes are internal to the library such as rendering options, you will need to inform theMarkdownService
that it needs to update.
To do so, inject theMarkdownService
and call thereload()
function as shown below.
import{MarkdownService}from'ngx-markdown';constructor(privatemarkdownService:MarkdownService,){}update(){this.markdownService.reload();}
📘 Refer to the ngx-markdownre-render demo for a live example.
When using static markdown you are responsible to provide the code block with related language.
<markdown ngPreserveWhitespaces>+ ```typescript const myProp: string = 'value';+ ```</markdown>
When using remote URL ngx-markdown will use the file extension to automatically resolve the code language.
<!-- will use html highlights --><markdown[src]="'path/to/file.html'"></markdown><!-- will use php highlights --><markdown[src]="'path/to/file.php'"></markdown>
When using variable binding you can optionally uselanguage
pipe to specify the language of the variable content (default value is markdown when pipe is not used).
<markdown[data]="markdown | language : 'typescript'"></markdown>
A demo is available @https://jfcere.github.io/ngx-markdown and its source code can be found inside thedemo
directory.
The following commands will clone the repository, install npm dependencies and serve the application @http://localhost:4200
git clone https://github.com/jfcere/ngx-markdown.gitnpm installnpm start
Building with AoT is part of the CI and is tested every time a commit occurs so you don't have to worry at all.
Here is the list of tasks that will be done on this library in the near future ...
- Add a FAQ section to the README.md
- Improve flexibily for some options
Contributions are always welcome, just make sure that ...
- Your code style matches with the rest of the project
- Unit tests pass
- Linter passes
The use of this library is totally free and no donation is required.
As the owner and primary maintainer of this project, I am putting a lot of time and effort beside my job, my family and my private time to bring the best support I can by answering questions, addressing issues and improving the library to provide more and more features over time.
If this project has been useful, that it helped you or your business to save precious time, don't hesitate to give it a star and to consider a donation to support its maintenance and future development.
Licensed underMIT.
About
Angular markdown component/directive/pipe/service to parse static, dynamic or remote content to HTML with syntax highlight and more...
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.