Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/yisraelx/ngx-showdown
Angular (>=2) integration for Showdown
https://github.com/yisraelx/ngx-showdown
angular javascript markdown md showdown typescript
Last synced: about 1 month ago
JSON representation
Angular (>=2) integration for Showdown
- Host: GitHub
- URL: https://github.com/yisraelx/ngx-showdown
- Owner: yisraelx
- License: mit
- Created: 2017-01-01T21:53:58.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2023-08-25T12:13:48.000Z (over 1 year ago)
- Last Synced: 2024-10-31T10:43:21.822Z (about 1 month ago)
- Topics: angular, javascript, markdown, md, showdown, typescript
- Language: TypeScript
- Homepage: http://yisraelx.github.io/ngx-showdown
- Size: 18.2 MB
- Stars: 16
- Watchers: 5
- Forks: 13
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-angular - ngx-showdown - Angular X Showdown Module. (Uncategorized / Uncategorized)
- awesome-angular-components - yisraelx/ngx-showdown - Angular (>=2) integration for Showdown (UI Components / Markdown)
README
Angular Showdown
[![Travis build](https://travis-ci.org/yisraelx/ngx-showdown.svg?branch=master)](https://travis-ci.org/yisraelx/ngx-showdown)
[![Codecov coverage](https://codecov.io/github/yisraelx/ngx-showdown/coverage.svg?branch=master)](https://codecov.io/github/yisraelx/ngx-showdown)
[![Version](https://img.shields.io/npm/v/ngx-showdown.svg)](https://www.npmjs.com/package/ngx-showdown)
[![MIT License](https://img.shields.io/npm/l/ngx-showdown.svg)](https://github.com/yisraelx/ngx-showdown/blob/master/LICENSE)
[![Documentation](https://img.shields.io/badge/%F0%9F%93%9A-documentation-informational.svg)](https://yisraelx.github.io/ngx-showdown/docs/index.html)
[![Bundle Size](https://img.shields.io/bundlephobia/min/ngx-showdown.svg?color=green)](https://bundlephobia.com/result?p=ngx-showdown)
[![TypeScript](https://img.shields.io/badge/100%25-TypeScript-blue.svg)](https://www.typescriptlang.org)
[![Semantic release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)**ngx-showdown is an [Angular](https://angular.io) (>=2) integration for [Showdown](https://github.com/showdownjs/showdown), A `Markdown` to `HTML` converter.**
___## Demo
* Demo app in [source code](https://github.com/yisraelx/ngx-showdown/blob/master/demo) ([live](http://yisraelx.github.io/ngx-showdown)).
* You can play with it in [Stackblitz](https://stackblitz.com/edit/ngx-showdown) and [Plunker](https://plnkr.co/edit/0j8d9w).## Install
```bash
$ npm install ngx-showdown --save
```
and install peer dependencies (`@angular/common/http` for `SourceDirective`)
```bash
$ npm install showdown @angular/common @angular/platform-browser --save
```
and install type package of `Showdown` for `TypeScript`
```bash
$ npm install @types/showdown --save-dev
```## Usage
*For more information and explanations, see the [full documentation](https://yisraelx.github.io/ngx-showdown/docs/index.html).*### Setup `ShowdownModule` in your app.
Add `ShowdownModule` to `imports` of App.
```typescript
import { NgModule } from '@angular/core';
import { ShowdownModule } from 'ngx-showdown';@NgModule({
imports: [ ShowdownModule ]
})
export class AppModule {}
```
Or with config (it will init `ShowdownConfig` provider)
```typescript
import { NgModule } from '@angular/core';
import { ShowdownModule } from 'ngx-showdown';@NgModule({
imports: [ ShowdownModule.forRoot({emoji: true, noHeaderId: true, flavor: 'github'}) ]
})
export class AppModule {}
```Add `showdown` to [`allowedCommonJsDependencies`](https://angular.io/guide/build#configuring-commonjs-dependencies) in the build config of the `angular.json` file (From angular >= 10).
```json
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"allowedCommonJsDependencies": [
"showdown"
]
...
}
...
},```
### Use `ShowdownComponent` in the template
#### Binding to `[value]` property
Bind markdown value to `value` property of showdown component.
```html```
Bind value and options.
```typescript
import { Component } from '@angular/core';
import * as Showdown from 'showdown';@Component({
selector: 'some',
template: ''
})
export class SomeComponent {
text: string = `
# h1
## h2
`;
options: Showdown.ShowdownOptions = {...};
// ...
}
```As directive on anther element
```html
```#### Markdown in component content
A markdown value in the component content.
```html# H1
## H2```
With options
```html* a
* b
* c```
As directive on anther element
```html
:showdown:**howdown**
```#### Load .md content (by `SourceDirective`)
Load markdown content of url source.
```html```
Bind input url to `src` directive.
```html**No Url..**
```
*Note: Loading markdown content requires [`HttpClient`](https://angular.io/api/common/http/HttpClient) of [`@angular/common/http`](https://angular.io/api/common/http)*#### Mixing sources
When both `Content` and `[value]`, It will render `[value]`.
```html
# Content
```When both `Content` and `[src]`, It will render `Content` and when `src` loads then results will be `src` content.
```html
# Content
```When both `[value]` and `[src]`, It will render `[value]` and when `src` loads then results will be `src` content.
```html```
#### Binding options
Bind options object (it init root `ShowdownConfig` and then set the bind `options`)
```typescript
import { Component } from '@angular/core';
import * as Showdown from 'showdown';@Component({
selector: `some`,
template: ``
})
export class SomeComponent {
text: string = '# Some';
options: Showdown.ShowdownOptions = {noHeaderId: true};
// ...
}
```
Or
```html
# abc
```
Bind single option (it have input properties for all showdown options).
```html
# abc
```#### Sanitize the convert html output
Sanitize the convert html output by [`DomSanitizer`](https://angular.io/api/platform-browser/DomSanitizer#sanitize).
```html# Some
Click
__Foo__```
Also sanitize content of `src` url.
```html```
### Use `ShowdownPipe` in the template
Transform markdown value of `text` property to html.
```html
{{ text | showdown }}
```Transform value with options (it init root `ShowdownConfig` and then set the pipe `options`)
```typescript
import { Component } from '@angular/core';
import * as Showdown from 'showdown';@Component({
selector: 'some',
template: '{{ text | showdown:options }}'
})
export class SomeComponent {
text: string = `
# h1
## h2
`;
options: Showdown.ShowdownOptions = {smartIndentationFix: true};
// ...
}
```### Use `ShowdownConverter` service
```typescript
import { Injectable } from '@angular/core';
import { ShowdownConverter } from 'ngx-showdown';@Injectable()
export class SomeService {
constructor(showdownConverter: ShowdownConverter){
console.log(showdownConverter.makeHtml('# Showdown'));
}
}
```### Set config provider (`ShowdownConfig`)
Set root config that will be injected to [ShowdownComponent](#ShowdownComponent), [ShowdownPipe](#ShowdownPipe), [ShowdownConverter](#ShowdownConverter) when they are created.
```typescript
import { NgModel } from '@angular/core';
import { ShowdownModule, ShowdownConverter } from 'ngx-showdown';
import * as Showdown from 'showdown';let colorExtension: Showdown.FilterExtension = {
type: 'output',
filter(text: string, converter: ShowdownConverter){
return text.replace('$color', converter.getOption('color') || 'green')
}
};@NgModel({
imports:[
ShowdownModule.forRoot({
flavor: 'original',
emoji: true,
color: 'red',
extensions: [ colorExtension ]
})
]
})
export class AppModule {}
```Override the root config provider value.
```typescript
import { Component } from '@angular/core';
import { ShowdownConfig } from 'ngx-showdown';@Component({
selector: 'some',
template: '# Header',
providers: [ {provide: ShowdownConfig, useValue: {underline: true, emoji: false}} ]
})
export class SomeComponent {}
```Set the config manually by the converter methods.
```typescript
import { Component } from '@angular/core';
import { ShowdownComponent } from 'ngx-showdown';
import highlightExtension from 'showdown-highlight';
import 'highlight.js/styles/default.css';@Component({
selector: 'some',
template: '# Header'
})
export class SomeComponent {
constructor(showdownComponent: ShowdownComponent) {
showdownComponent.addExtension(highlightExtension);
showdownComponent.setFlavor('ghost');
showdownComponent.setOptions({emoji: true});
}
}
```#### Flavor
Set root flavor ([Showdown flavors](https://github.com/showdownjs/showdown/blob/master/README.md#flavors)).
```typescript
import { NgModel } from '@angular/core';
import { ShowdownModule } from 'ngx-showdown';@NgModel({
imports:[
ShowdownModule.forRoot({flavor: 'github'})
]
})
export class AppModule {}
```
*Note: If `flavor` is not set then the default value is 'vanilla' flavor.*#### ConverterOptions
Set root ConverterOptions ([Showdown options](https://github.com/showdownjs/showdown/blob/master/README.md#valid-options)).
```typescript
import { NgModel } from '@angular/core';
import { ShowdownModule } from 'ngx-showdown';@NgModel({
imports:[
ShowdownModule.forRoot({underline: true, emoji: false})
]
})
export class AppModule {}
```#### Extensions
Set root Extensions ([Showdown extensions](https://github.com/showdownjs/showdown#extensions)).
With extension can be made changes to the `Markdown` input ('lang') and the `Html` output also listen to parse event, you can [make extension](https://github.com/showdownjs/showdown/wiki/Extensions) or [search in npm](https://www.npmjs.com/search?q=keywords:showdown%20extension) for existing extension.
```typescript
import { NgModel } from '@angular/core';
import { ShowdownModule } from 'ngx-showdown';
import * as Showdown from 'showdown';
import highlightExtension from 'showdown-highlight';
import 'highlight.js/styles/default.css';let someExtension: Showdown.ShowdownExtension = {
type: 'lang',
regex: new RegExp('markdown', 'g'),
replace: 'showdown'
};@NgModel({
imports: [
ShowdownModule.forRoot({extensions: [ someExtension, highlightExtension ]})
]
})
export class AppModule {}
```## Troubleshoot
#### Interpolation
Using unescaped `{}` (`{}`) in template causes an template parse error ([@angular/angular/#11859](https://github.com/angular/angular/issues/11859)),
The solution is to use escape chars (html char code etc.),
Anther solution is to override the default [interpolation](https://angular.io/api/core/Component#interpolation).#### Whitespaces
Angular aot compiler remove whitespaces by default, use [ngPreserveWhitespaces](https://angular.io/api/core/Component#preserving-whitespace) to preserve whitespaces.
```html* a
* 1
* 2
* b```
With `ngPreserveWhitespaces`
```
* a
* 1
* 2
* b
```
Without `ngPreserveWhitespaces`
```
* a * 1 * 2
* b
```#### Indentation
Showdown converter [smartIndentationFix](https://github.com/showdownjs/showdown/wiki/Showdown-options#smartindentationfix) option can fix string indentation problems of es6 template and html.
```typescript
text = `
# A
## B
`;
```
```html```
With `smartIndentationFix`
```
# A
## B
```
Without `smartIndentationFix`
```
# A
## B
```## Contribute
**Pull requests are welcome!**## Development
This project built with [`Angular Cli`](https://angular.io/cli).Install dependencies
```bash
$ yarn install
```
Run test
```bash
$ yarn test
```
Build for release
```bash
$ yarn build
```## Credits
This project use [Showdown library](https://github.com/showdownjs/showdown) to convert `Markdown` to `Html`.## License
Copyright © [Yisrael Eliav](https://github.com/yisraelx),
Licensed under the [MIT license](https://github.com/yisraelx/ngx-showdown/blob/master/LICENSE).