UNPKG

markdown-it-tasks

Version:

Create Task lists with Markdown

122 lines (121 loc) 4.93 kB
"use strict"; // Markdown-it plugin to render GitHub-style task lists; see // // https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments // https://github.com/blog/1825-task-lists-in-all-markdown-documents var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); var options = { enabled: false, label: false, labelAfter: false, labelBefore: false, containerClass: "task-list", itemClass: "task-list__item", labelClass: "task-list__label", inputClass: "task-list__input", }; var MarkdownItTasks = function (md, opts) { options = __assign(__assign({}, options), opts); md.core.ruler.after("inline", "github-task-lists", function (state) { var tokens = state.tokens; for (var i = 2; i < tokens.length; i++) { if (isTodoItem(tokens, i)) { createTodo(tokens[i], state.Token); attrSet(tokens[i - 2], "class", options.itemClass + (options.enabled ? " " + options.itemClass + "--enabled" : "")); attrSet(tokens[parentToken(tokens, i - 2)], "class", options.containerClass || ""); } } }); }; var attrSet = function (token, name, value) { var index = token.attrIndex(name); var attr = [name, value]; if (index < 0) token.attrPush(attr); else token.attrs[index] = attr; }; var parentToken = function (tokens, index) { var targetLevel = tokens[index].level - 1; for (var i = index - 1; i >= 0; i--) { if (tokens[i].level === targetLevel) { return i; } } return -1; }; var isTodoItem = function (tokens, index) { return (isInline(tokens[index]) && isParagraph(tokens[index - 1]) && isListItem(tokens[index - 2]) && startsWithTodoMarkdown(tokens[index])); }; var createTodo = function (token, TokenConstructor) { token.children.unshift(makeCheckbox(token, TokenConstructor)); token.children[1].content = token.children[1].content.slice(3); token.content = token.content.slice(3); if (options.label) { if (options.labelAfter || options.labelBefore) { token.children.pop(); // Use large random number as id property of the checkbox. var id = options.itemClass + "--" + Math.ceil(Math.random() * (10000 * 1000) - 1000); token.children[0].content = token.children[0].content.slice(0, -1) + " id=\"" + id + "\">"; if (options.labelAfter) token.children.push(singleLabel(token.content, id, TokenConstructor)); else if (options.labelBefore) token.children.unshift(singleLabel(token.content, id, TokenConstructor)); } else { token.children.unshift(beginLabel(TokenConstructor)); token.children.push(endLabel(TokenConstructor)); } } }; var makeCheckbox = function (token, TokenConstructor) { var checkbox = new TokenConstructor("html_inline", "", 0); var disabledAttr = options.enabled ? "" : " disabled"; var checked = token.content.indexOf("[x] ") === 0 || token.content.indexOf("[X] ") === 0 ? " checked" : ""; checkbox.content = "<input class=\"" + options.inputClass + "\" type=\"checkbox\"" + checked + disabledAttr + ">"; return checkbox; }; // these next two functions are kind of hacky; probably should really be a // true block-level token with .tag=='label' var beginLabel = function (TokenConstructor) { var token = new TokenConstructor("html_inline", "", 0); token.content = "<label class=\"" + options.labelClass + "\">"; return token; }; var endLabel = function (TokenConstructor) { var token = new TokenConstructor("html_inline", "", 0); token.content = "</label>"; return token; }; var singleLabel = function (content, id, TokenConstructor) { var token = new TokenConstructor("html_inline", "", 0); token.content = "<label class=\"" + options.labelClass + "\" for=\"" + id + "\">" + content.trim() + "</label>"; token.attrs = [{ for: id }]; return token; }; var isInline = function (token) { return token.type === "inline"; }; var isParagraph = function (token) { return token.type === "paragraph_open"; }; var isListItem = function (token) { return token.type === "list_item_open"; }; var startsWithTodoMarkdown = function (token) { return token.content.indexOf("[ ] ") === 0 || token.content.indexOf("[x] ") === 0 || token.content.indexOf("[X] ") === 0; }; exports.default = MarkdownItTasks;