Skip to content

Instantly share code, notes, and snippets.

@auser
Created January 15, 2018 17:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save auser/1ee9f4294fce3035be5c5fa6f7fcf6b4 to your computer and use it in GitHub Desktop.
Save auser/1ee9f4294fce3035be5c5fa6f7fcf6b4 to your computer and use it in GitHub Desktop.
module.exports = function container_plugin(md, name, options) {
function validateDefault(params) {
return true;
// return params.trim().split(' ', 2)[0] === name;
}
function renderDefault(tokens, idx, _options, env, self) {
// add a class to the opening tag
if (tokens[idx].nesting === 1) {
tokens[idx].attrPush(['class', `${name} ignore-me`]);
}
// if (idx + 1 < tokens.length) {
// }
return `${tokens[idx].markers[0]}
${tokens[idx].content}
${tokens[idx].markers[1]}`;
// return self.renderToken(tokens, idx, _options, env, self);
}
options = options || {};
var min_markers = 3,
auto_closed = false,
marker_str_start = options.marker_start || '\\begin{equation}',
marker_str_end = options.marker_end || '\\end{equation}',
marker_char_start = marker_str_start.charCodeAt(0),
marker_char_end = marker_str_end.charCodeAt(0),
marker_len = marker_str_start.length,
marker_end_len = marker_str_end.length,
len,
mem,
validate = options.validate || validateDefault,
render = options.render || renderDefault;
function container(state, startLine, endLine, silent) {
var all_chars = '';
var pos,
nextLine,
start = state.bMarks[startLine] + state.tShift[startLine],
max = state.eMarks[startLine];
if (marker_char_start !== state.src.charCodeAt(start)) {
return false;
}
for (pos = start + 1; pos <= max; pos++) {
// First, let's make sure this position is exactly the beginning
// marker
if (marker_str_start[(pos - start) % marker_len] !== state.src[pos]) {
break;
}
}
// Make sure the position actually represents the beginning
// and ending of the latex
marker_count = Math.floor((pos - start) / marker_len);
if (marker_count < 1) {
return false;
}
pos -= (pos - start) % marker_len;
markup = state.src.slice(start, pos);
params = state.src.slice(pos, max);
if (!validate(params)) {
return false;
}
// Since start is found, we can report success here in validation mode
//
if (silent) {
return true;
}
// Search for the end of the block
//
nextLine = startLine;
for (;;) {
nextLine++;
if (nextLine >= endLine) {
// unclosed block should be autoclosed by end of document.
// also block seems to be autoclosed by end of parent
break;
}
start = state.bMarks[nextLine] + state.tShift[nextLine];
max = state.eMarks[nextLine];
if (marker_char_end !== state.src.charCodeAt(start)) {
continue;
}
// Search through the next positions and make sure that we're
// actually looking at the end marker
for (pos = start + 1; pos <= max; pos++) {
// if (marker_str_end[(pos - start) % marker_end_len])
if (marker_str_end[(pos - start) % marker_end_len] !== state.src[pos]) {
break;
}
}
// make sure tail has spaces only
// pos -= (pos - start) % marker_len;
mem = pos;
pos = state.skipSpaces(pos);
len = pos - mem;
if (pos < max) {
continue;
}
// found!
auto_closed = true;
break;
}
// var curr_pos = start;
// while (curr_pos < pos) {
// markup = `${markup}${state.src[curr_pos++]}`;
// }
old_parent = state.parentType;
old_line_max = state.lineMax;
state.parentType = 'container';
// this will prevent lazy continuations from ever going past our end marker
state.lineMax = nextLine;
token = state.push('container_' + name + '_open', 'div', 1);
token.markup = markup;
token.block = true;
token.info = params;
token.map = [startLine, nextLine];
// token.markers = [marker_str_start, marker_str_end];
token.marker = marker_str_start;
token.content = state.getLines(startLine + 1, nextLine, len, true);
// Tokenize the first token
state.md.block.tokenize(state, startLine + 1, nextLine);
// Setup the second token
// token = state.push('container_' + name + '_close', 'div', -1);
// token.markup = state.src.slice(start, pos);
// token.block = true;
// state.marker = marker_str_end;
// Forward the state
state.parentType = old_parent;
state.lineMax = old_line_max;
state.line = nextLine + (auto_closed ? 1 : 0);
return true;
}
md.block.ruler.before('paragraph', 'container_' + name + '_open', container, {
alt: ['paragraph', 'reference', 'blockquote', 'list']
});
md.renderer.rules['container_' + name + '_open'] = render;
// md.renderer.rules['container_' + name + '_close'] = render;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment