Markdown If Needed

在需要的地方启用MarkDown语法,添加格式帮助链接及 Markdown 工具栏

目前為 2017-04-23 提交的版本,檢視 最新版本

// ==UserScript==
// @name        Markdown If Needed
// @namespace   wdssmq
// @description 在需要的地方启用MarkDown语法,添加格式帮助链接及 Markdown 工具栏
// @author      沉冰浮水
// @contributor JixunMoe
// @contributor wOxxOm
// @license     MIT License
// @include     https://*
// @include     http://*
// @version     1.0.0
// @grant       GM_addStyle
// ==/UserScript==

/* jshint multistr:true */
function $n(e) {
  return document.querySelector(e);
}
function $na(e) {
  return document.querySelectorAll(e);
}

function xml2md(xml) {
  var md = xml;
  if (xml.indexOf("isXML") > -1) {
    // 移除isXML
    md = md.replace(/\n?<!--isXML-->/g, "");
    //行内

    //链接
    md = md.replace(/<a href="([^"]+)" title="([^"]+)"\s*([^>]*)>(.+)<\/a>/g,'[$4]($1 "$2"){$3}');
    //图片
    md = md.replace(/<img src="([^"]+)" alt="([^"]+)"[^>]*>/g,'![$2]($1)');
    // 段落
    md = md.replace(/<p>/g, "");
    md = md.replace(/<\/p>/g, "\n\n");
    // h1-h6
    md = md.replace(/<h6>(.+?)<\/h6>/g, "###### $1\n\n");
    md = md.replace(/<h5>(.+?)<\/h5>/g, "##### $1\n\n");
    md = md.replace(/<h4>(.+?)<\/h4>/g, "#### $1\n\n");
    md = md.replace(/<h3>(.+?)<\/h3>/g, "### $1\n\n");
    md = md.replace(/<h2>(.+?)<\/h2>/g, "## $1\n\n");
    md = md.replace(/<h1>(.+?)<\/h1>/g, "# $1\n\n");
    // 格式化换行
    md = md.replace(/\n\n+/g, "\n\n");
    md = md.replace(/\n+$/g, "");
    //修正
    md = md.replace(/\){}/g, ")");
  }
  return md;
}

function md2xml(md) {
  var xml = md;
  if (md.indexOf("isXML") == -1) {
    // 格式化换行
    xml = xml.replace(/\n\n+/g, "\n\n");
    xml = xml.replace(/\n+$/g, "");
    // h1-h6
    xml = xml.replace(/(^|\n)######\s*([^\n]+)/g, "$1<h6>$2</h6>");
    xml = xml.replace(/(^|\n)#####\s*([^\n]+)/g, "$1<h5>$2</h5>");
    xml = xml.replace(/(^|\n)####\s*([^\n]+)/g, "$1<h4>$2</h4>");
    xml = xml.replace(/(^|\n)###\s*([^\n]+)/g, "$1<h3>$2</h3>");
    xml = xml.replace(/(^|\n)##\s*([^\n]+)/g, "$1<h2>$2</h2>");
    xml = xml.replace(/(^|\n)#\s*([^\n]+)/g, "$1<h1>$2</h1>");
    // 段落
    xml = xml.replace(/^(?!(<h|<p|<div))/g, "<p>");
    xml = xml.replace(/\n+(<h|<p|<div)/g, "</p>\n$1");
    xml = xml.replace(/\n\n/g, "</p>\n<p>");
    xml = xml.replace(/(p>|h\d>|div>)<\/p>/g, "$1");
    xml = xml.replace(/<p>$/g, "");
    xml = xml.replace(/<p>(?!<\/p>)(.+)$/g, "<p>$1</p>");
    // 行内标记
    xml = xml.replace(/([^\*]*)\*\*(.*)\*\*/g, "$1<b>$2</b>");
    xml = xml.replace(/([^\*]*)\*(.*)\*/g, "$1<i>$2</i>");
    //图片
    xml = xml.replace(/!\[([^\]]+)\]\(([^\s\)]+)[^\)]*\)/g, '<img src="$2" alt="$1" title="$1">');
    console.log(xml);
    //链接
    xml = xml.replace(/\[(.+)\]\(([^\s\)]+)\s*"?([^"]+)*"?\)(?:{([^}]+)})?/g, '<a href="$2" title="$3" $4>$1</a>');
    xml = xml.replace(/title=""/g,'title="点击链接查看"');
    // xml = xml.replace(/\[(.+)\]\(([^\s\)]+)\)/g, '<a href="$2">$1</a>');

    //修正
    xml = xml.replace(/\s>/g,'>');
    xml = xml.replace(/2xml/g,"");
    // 添加 isXML
    xml += "\n<!--isXML-->";
  }
  return xml;
}

window.addEventListener('DOMContentLoaded', function (e) {
  var domTxa = $n("textarea.md-needed");

  if (!domTxa)
    return;
  domTxa.addEventListener('keyup', function () {
    if(domTxa.value.indexOf("2xml") > -1)
      domTxa.value = md2xml(domTxa.value);
  });
  $n("input[type=submit]").addEventListener('mouseenter', function () {
    domTxa.value = md2xml(domTxa.value);
  });
  $n("input[type=submit]").addEventListener('mouseout', function () {
    domTxa.value = xml2md(domTxa.value);
  });

  //添加工具栏
  addFeatures(domTxa);

  GM_addStyle('\
    .md-button {\
    display: inline-block;\
    cursor: pointer;\
    margin: 0px;\
    font-size: 12px;\
    line-height: 1;\
    font-weight: bold;\
    padding: 4px 6px;\
    background: -moz-linear-gradient(center bottom , #CCC 0%, #FAFAFA 100%) repeat scroll 0% 0% #F8F8F8;\
    border: 1px solid #999;\
    border-radius: 2px;\
    white-space: nowrap;\
    text-shadow: 0px 1px 0px #FFF;\
    box-shadow: 0px 1px 0px #FFF inset, 0px -1px 2px #BBB inset;\
    color: #333;}');
});

function addFeatures(n) {
  if (!n)
    return;
  // add buttons
  // btnMake(n, '<b>Test</b>', "test", function (e) {
  // n.value = md2xml(n.value)
  // });
  btnMake(n, '<b>' + __('B') + '</b>', __('Bold'), '**');
  btnMake(n, '<i>' + __('I') + '</i>', __('Italic'), '*');
  btnMake(n, '<u>' + __('U') + '</u>', __('Underline'), '<u>', '</u>');
  btnMake(n, '<s>' + __('S') + '</s>', __('Strikethrough'), '<s>', '</s>');
  btnMake(n, '&lt;br&gt;', __('Force line break'), '<br>', '', true);
  btnMake(n, '---', __('Horizontal line'), '\n\n---\n\n', '', true);
  btnMake(n, __('URL'), __('Add URL to selected text'),
    function (e) {
    try {
      edWrapInTag('[', '](' + prompt(__('URL') + ':') + ')', edInit(e.target));
    } catch (ex) {}
  });
  btnMake(n, __('Image (https)'), __('Convert selected https://url to inline image'), '![' + __('image') + '](', ')');
  btnMake(n, __('Table'), __('Insert table template'), __('\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n'), '', true);
  btnMake(n, __('Code'), __('Apply CODE markdown to selected text'),
    function (e) {
    var ed = edInit(e.target);
    if (ed.sel.indexOf('\n') < 0)
      edWrapInTag('`', '`', ed);
    else
      edWrapInTag(((ed.sel1 === 0) || (ed.text.charAt(ed.sel1 - 1) == '\n') ? '' : '\n') + '```' + (ed.sel.charAt(0) == '\n' ? '' : '\n'),
        (ed.sel.substr(-1) == '\n' ? '' : '\n') + '```' + (ed.text.substr(ed.sel2, 1) == '\n' ? '' : '\n'),
        ed);
  });
}

function btnMake(elTxa, label, title, tag1_or_cb, tag2, noWrap) {
  var a = document.createElement('a');
  a.className = 'md-button';
  a.innerHTML = label;
  a.title = title;
  a.style.setProperty('float', 'right');
  a.addEventListener('click',
    typeof(tag1_or_cb) == 'function' ? tag1_or_cb
     : noWrap ? function (e) {
    edInsertText(tag1_or_cb, edInit(e.target));
  }
     : function (e) {
    edWrapInTag(tag1_or_cb, tag2, edInit(e.target));
  });
  var elToolbar = elTxa.parentNode.querySelector('.md-toolbar');
  // console.log(elToolbar);
  a.textAreaNode = elTxa;
  elToolbar.insertBefore(a, elToolbar.firstElementChild);
}

function edInit(btn) {
  var ed = {
    node: btn.textAreaNode
  };
  ed.sel1 = ed.node.selectionStart;
  ed.sel2 = ed.node.selectionEnd,
  ed.text = ed.node.value;
  ed.sel = ed.text.substring(ed.sel1, ed.sel2);
  return ed;
}

function edWrapInTag(tag1, tag2, ed) {
  ed.node.value = ed.text.substr(0, ed.sel1) + tag1 + ed.sel + (tag2 ? tag2 : tag1) + ed.text.substr(ed.sel2);
  ed.node.setSelectionRange(ed.sel1 + tag1.length, ed.sel1 + tag1.length + ed.sel.length);
  ed.node.focus();
}

function edInsertText(text, ed) {
  ed.node.value = ed.text.substr(0, ed.sel2) + text + ed.text.substr(ed.sel2);
  ed.node.setSelectionRange(ed.sel2 + text.length, ed.sel2 + text.length);
  ed.node.focus();
}

var __ = (function (l, langs) {
  var lang = langs[l] || langs[l.replace(/-.+/, '')];
  return lang ? function (text) {
    return lang[text] || text;
  }
   : function (text) {
    return text;
  }; // No matching language, fallback to english
})("zh-CN", {
  // Can be full name, or just the beginning part.
  'zh-CN': {
    'Bold': '粗体',
    'Italic': '斜体',
    'Underline': '下划线',
    'Strikethrough': '删除线',
    'Force line break': '强制换行',
    'Horizontal line': '水平分割线',
    'URL': '链接',
    'Add URL to selected text': '为所选文字添加链接',
    'Image (https)': '图片 (https)',
    'Convert selected https://url to inline image': '将所选地址转换为行内图片',
    'image': '图片描述', // Default image alt value
    'Table': '表格',
    'Insert table template': '插入表格模板',
    'Code': '代码',
    'Apply CODE markdown to selected text': '将选中代码围起来',

    '\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n':
    '\n| 表头 1 | 表头 2 |\n|-------|-------|\n| 表格 1 | 表格 2 |\n| 表格 3 | 表格 4 |\n'
  },
  'ru': {
    'B': 'Ж',
    'I': 'К',
    'U': 'Ч',
    'S': 'П',
    'Bold': 'Жирный',
    'Italic': 'Курсив',
    'Underline': 'Подчеркнутый',
    'Strikethrough': 'Перечеркнутый',
    'Force line break': 'Новая строка',
    'Horizontal line': 'Горизонтальная линия',
    'URL': 'ссылка',
    'Add URL to selected text': 'Добавить ссылку к выделенному тексту',
    'Image (https)': 'Картинка (https)',
    'Convert selected https://url to inline image': 'Преобразовать выделенный https:// адрес в картинку',
    'image': 'картинка', // Default image alt value
    'Table': 'Таблица',
    'Insert table template': 'Вставить шаблон таблицы',
    'Code': 'Код',
    'Apply CODE markdown to selected text': 'Пометить выделенный фрагмент как программный код',

    '\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n':
    '\n| заголовок1 | заголовок2 |\n|-------|-------|\n| ячейка1 | ячейка2 |\n| ячейка3 | ячейка4 |\n'
  },
  'fr': {
    'B': 'G',
    'I': 'I',
    'U': 'S',
    'S': 'B',
    'Bold': 'Gras',
    'Italic': 'Italique',
    'Underline': 'Souligné',
    'Strikethrough': 'Barré',
    'Force line break': 'Forcer le saut de ligne',
    'Horizontal line': 'Ligne horizontale',
    'URL': 'URL',
    'Add URL to selected text': 'Ajouter URL au texte sélectionné',
    'Image (https)': 'Image (https)',
    'Convert selected https://url to inline image': 'Convertir https://url sélectionnés en images',
    'image': 'image', // Default image alt value
    'Table': 'Tableau',
    'Insert table template': 'Insérer un modèle de table',
    'Code': 'Code',
    'Apply CODE markdown to selected text': 'Appliquer CODE markdown au texte sélectionné',

    '\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n':
    '\n| En-tête 1 | En-tête 2 |\n|-------|-------|\n| cellule 1 | cellule 2 |\n| cellule 3 | cellule 4 |\n'
  }
});

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址