Skip to content

Commit

Permalink
Merge pull request #13 from daguej/indent
Browse files Browse the repository at this point in the history
Add indent option
  • Loading branch information
trabus committed May 8, 2020
2 parents 23fe691 + fc7f464 commit 6b63cae
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 37 deletions.
10 changes: 9 additions & 1 deletion README.md
Expand Up @@ -41,7 +41,8 @@ markdown.use(terminal, options);
var options = {
styleOptions:{},
highlight: require('cardinal').highlight,
unescape: true
unescape: true,
indent: ' '
}
```

Expand Down Expand Up @@ -94,6 +95,13 @@ Highlight function to parse code blocks. Should be a function that takes a strin
### unescape
Unescape content, `true` by default.

### indent
Indent all content under a heading (`h1`..`h6`) using this string. With `indent: ' '` (two spaces):

| Markdown | Rendered |
| -------------------------- | ----------------------------- |
| <pre># Heading 1<br>## Heading 2<br>Some stuff indented twice<br>#<br>Only indented once</pre> | <pre>Heading 1<br> Heading 2<br> Some stuff indented twice<br><br> Only indented once</pre> |

## Highlighting
`markdown-it-terminal` uses the [cardinal](https://github.com/thlorenz/cardinal) library
for code highlight support by default.
Expand Down
2 changes: 1 addition & 1 deletion index.js
Expand Up @@ -25,7 +25,7 @@ module.exports = function terminal_plugin(md,options) {
unescape: true
};

var opts = merge(defaultOptions, options);
var opts = merge({}, defaultOptions, options);
terminal(md,opts);
// console.log(styles)
};
95 changes: 66 additions & 29 deletions lib/markdown-it-terminal.js
Expand Up @@ -19,18 +19,20 @@ module.exports = function(md, options) {
var styleOptions = options.styleOptions;
var unescape = options.unescape;
var highlight = options.highlight || cardinal.highlight;

var indent = options.indent;
var headingLevel;

md.renderer.rules.blockquote_open = function () {
return '\n' + styleOptions.blockquote.open;
return newline(1, tokens, idx) + styleOptions.blockquote.open;
};
md.renderer.rules.blockquote_close = function () {
return styleOptions.blockquote.close + '\n\n';
return styleOptions.blockquote.close + newline(2, tokens, idx);
};


md.renderer.rules.code_block = function (tokens, idx /*, options, env */) {
var e = unescape ? unescapeEntities : escapeHtml;
return '\n' + styleOptions.code.open + e(tokens[idx].content) + styleOptions.code.close + '\n\n';
return newline(1, tokens, idx) + styleOptions.code.open + indentText(e(tokens[idx].content)) + styleOptions.code.close + newline(2, tokens, idx);
};
md.renderer.rules.code_inline = function (tokens, idx /*, options, env */) {
var e = unescape ? unescapeEntities : escapeHtml;
Expand All @@ -47,34 +49,48 @@ module.exports = function(md, options) {
langName = e(token.info.trim().split(/\s+/g)[0]);
}
if (langName === 'javascript' || langName === 'js') {
highlighted = highlight(token.content, langName) || e(token.content);
highlighted = highlight(token.content, langName) || indentText(e(token.content));
} else {
highlighted = e(token.content);
highlighted = indentText(e(token.content));
}
return '\n' + styleOptions.code.open + highlighted + styleOptions.code.close + '\n\n';
return newline(1, tokens, idx-1) + styleOptions.code.open + highlighted + styleOptions.code.close + newline(2, tokens, idx);
};

md.renderer.rules.heading_open = function (tokens, idx, options, env) {
if (tokens[idx+1] && tokens[idx+1].content == '') return '';
if (tokens[idx].tag === 'h1') {
return styleOptions.firstHeading.open + '\n';
return styleOptions.firstHeading.open + newline(1, tokens, idx);
}
return styleOptions.heading.open + '\n';
return styleOptions.heading.open + newline(1, tokens, idx);
};
md.renderer.rules.heading_close = function (tokens, idx, options, env) {
headingLevel = tokens[idx].tag.substr(1);
if (tokens[idx-1] && tokens[idx-1].content == '') {
// This allows you to un-indent without a new header. eg:
// # H1 |H1
// ## H2 | H2
// Some stuff indented twice | Some stuff indented twice
// # |
// Only indented once | Only indented once

if (indent) return indent;
else return '';
}

if (tokens[idx].tag === 'h1') {
return styleOptions.firstHeading.close + '\n';
return styleOptions.firstHeading.close + newline(1, tokens, idx);
}
return styleOptions.heading.close + '\n';
return styleOptions.heading.close + newline(1, tokens, idx);
};


md.renderer.rules.hr = function (tokens, idx, options /*, env */) {
return styleOptions.hr.open + hr('-') + styleOptions.hr.close + '\n';
return styleOptions.hr.open + hr('-') + styleOptions.hr.close + newline(1, tokens, idx);
};


md.renderer.rules.bullet_list_open = function () { return ''; };
md.renderer.rules.bullet_list_close = function () { return '\n'; };
md.renderer.rules.bullet_list_close = function (tokens, idx) { return newline(1, tokens, idx); };
md.renderer.rules.list_item_open = function (tokens, idx /*, options, env */) {
var next = tokens[idx + 1];
var bullet = '* ';
Expand All @@ -87,14 +103,14 @@ module.exports = function(md, options) {
}
};
md.renderer.rules.list_item_close = function (tokens, idx) {
return styleOptions.listitem.close + '\n';
return styleOptions.listitem.close + newline(1, tokens, idx);
};

md.renderer.rules.ordered_list_open = function (tokens, idx /*, options, env */) {
var count = 0;
var item = 1;
if (tokens[idx].order > 1) {
return styleOptions.listItem.open + tokens[idx].order + '\n';
return styleOptions.listItem.open + tokens[idx].order + newline(1, tokens, idx);
} else {
while(tokens[idx + count].type !== 'ordered_list_close') {
if(tokens[idx + count].type === 'list_item_open') {
Expand All @@ -106,18 +122,18 @@ module.exports = function(md, options) {
}
return '';
};
md.renderer.rules.ordered_list_close = function () {
return styleOptions.listitem.close + '\n';
md.renderer.rules.ordered_list_close = function (tokens, idx) {
return styleOptions.listitem.close + newline(1, tokens, idx);
};

md.renderer.rules.paragraph_open = function (tokens, idx, options, env ) {
return tokens[idx].hidden ? '' : styleOptions.paragraph.open;
};
md.renderer.rules.paragraph_close = function (tokens, idx, options, env ) {
if (tokens[idx].hidden === true) {
return tokens[idx + 1].type.slice(-5) === 'close' ? '' : '\n';
return tokens[idx + 1].type.slice(-5) === 'close' ? '' : newline(1, tokens, idx);
}
return styleOptions.paragraph.close + '\n\n';
return styleOptions.paragraph.close + newline(2, tokens, idx);
};


Expand All @@ -134,7 +150,7 @@ module.exports = function(md, options) {
var e = unescape ? unescapeEntities : escapeHtml;
var src = e(token.attrs[token.attrIndex('src')][1]);
var title = token.title ? ' – ' + e(token.title) : '';
return styleOptions.link.open + '![' + src + title + '](' + src + ') '+ styleOptions.link.close + '\n';
return styleOptions.link.open + '![' + src + title + '](' + src + ') '+ styleOptions.link.close + newline(1, tokens, idx);
};

md.renderer.rules.strong_open = function () { return styleOptions.strong.open; };
Expand All @@ -150,10 +166,11 @@ module.exports = function(md, options) {


md.renderer.rules.hardbreak = function (tokens, idx, options /*, env */) {
return '\n';
var nl = newline(1, tokens, idx);
return nl;
};
md.renderer.rules.softbreak = function (tokens, idx, options /*, env */) {
return '\n';
return newline(1, tokens, idx);
};


Expand All @@ -172,14 +189,14 @@ module.exports = function(md, options) {

//TODO: replace with cli-table

md.renderer.rules.table_open = function () { return '<table>\n'; };
md.renderer.rules.table_close = function () { return '</table>\n'; };
md.renderer.rules.thead_open = function () { return '<thead>\n'; };
md.renderer.rules.thead_close = function () { return '</thead>\n'; };
md.renderer.rules.tbody_open = function () { return '<tbody>\n'; };
md.renderer.rules.tbody_close = function () { return '</tbody>\n'; };
md.renderer.rules.table_open = function () { return '<table>' + newline(1, tokens, idx); };
md.renderer.rules.table_close = function () { return '</table>' + newline(1, tokens, idx); };
md.renderer.rules.thead_open = function () { return '<thead>' + newline(1, tokens, idx); };
md.renderer.rules.thead_close = function () { return '</thead>' + newline(1, tokens, idx); };
md.renderer.rules.tbody_open = function () { return '<tbody>' + newline(1, tokens, idx); };
md.renderer.rules.tbody_close = function () { return '</tbody>' + newline(1, tokens, idx); };
md.renderer.rules.tr_open = function () { return '<tr>'; };
md.renderer.rules.tr_close = function () { return '</tr>\n'; };
md.renderer.rules.tr_close = function () { return '</tr>' + newline(1, tokens, idx); };
md.renderer.rules.th_open = function (tokens, idx /*, options, env */) {
if (tokens[idx].align) {
return '<th style="text-align:' + tokens[idx].align + '">';
Expand Down Expand Up @@ -226,6 +243,26 @@ module.exports = function(md, options) {
// });

// console.log(styles.red.open + 'red text ' + styles.blue.open + 'blue text' + styles.blue.close + 'more red' + styles.red.close)

var doRender = md.renderer.render;
md.renderer.render = function(tokens, options, env) {
headingLevel = null;
return doRender.apply(this, arguments);
};

function newline(lines, tokens, idx) {
var nl = '\n'.repeat(lines);
if (indent && headingLevel) {
var next = tokens && tokens[idx+1];
if (next && next.type == 'heading_open') headingLevel = next.tag.substr(1) - 1;
nl += indent.repeat(headingLevel);
}
return nl;
}

function indentText(txt) {
return txt.split('\n').join(newline(1));
}
};

module.exports.compoundStyle = compoundStyle;
Expand Down
32 changes: 26 additions & 6 deletions tests/test.js
@@ -1,15 +1,17 @@
'use strict';

var styles = require('ansi-styles');
var path = require('path');
var expect = require('chai').expect;
var styles = require('ansi-styles');
var MarkdownIt = require('markdown-it');
var terminal = require('../');
var path = require('path');
var expect = require('chai').expect;

/*eslint-env mocha*/

describe('markdown-it-terminal', function () {
var md;
beforeEach(function () {
md = require('markdown-it')().use(require('../'));
md = require('markdown-it')().use(terminal);
});

it('renders basic markdown', function() {
Expand Down Expand Up @@ -101,11 +103,29 @@ describe('markdown-it-terminal', function () {
});

it('allows overrides of basic styles', function() {
var markdown = require('markdown-it')().use(require('../'),{styleOptions:{code:styles.green}});
// console.log(markdown.render('`code should be green`'))
var markdown = new MarkdownIt().use(terminal,{styleOptions:{codespan:styles.green}});
expect(markdown.render('`code should be green`'))
.to.equal('\u001b[0m\u001b[32mcode should be green\u001b[39m\u001b[0m\n\n');
});

it('does not clobber default options', function() {
var markdown = new MarkdownIt().use(terminal,{styleOptions:{strong:styles.red}});
expect(markdown.render('**should be red**'))
.to.equal('\u001b[0m\u001b[31mshould be red\u001b[39m\u001b[0m\n\n');


var markdown2 = new MarkdownIt().use(terminal);
expect(markdown2.render('**should be default style**'))
.to.equal('\u001b[0m\u001b[1mshould be default style\u001b[22m\u001b[0m\n\n');
});

it('renders indents', function() {
var markdown = new MarkdownIt().use(terminal, { indent: ' ' });

expect(markdown.render('# h1\nfoo\n## h2\nbar\n#\nbaz'))
.to.equal('\u001b[35m\u001b[4m\u001b[1m\nh1\u001b[22m\u001b[24m\u001b[39m\n \u001b[0mfoo\u001b[0m\n\n' +
' \u001b[32m\u001b[1m\n h2\u001b[22m\u001b[39m\n \u001b[0mbar\u001b[0m\n\n \u001b[0mbaz\u001b[0m\n\n ');
});

it.skip('renders blue', function(){
console.log(md.render('<blue>content is blue and <red>this should be red</red> but this is blue</blue>'))
Expand Down

0 comments on commit 6b63cae

Please sign in to comment.