Table to Markdown Copier

Convert html table to markdown format

当前为 2017-02-03 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Table to Markdown Copier
  3. // @namespace https://github.com/hotmit/table-markdown-userscript
  4. // @version 1.0.0
  5. // @description Convert html table to markdown format
  6. // @author Du Dang
  7. // @include http://*/*
  8. // @include https://*/*
  9. // @grant none
  10. // @require https://code.jquery.com/jquery-3.1.1.min.js
  11. // @require https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.16/clipboard.min.js
  12. // ==/UserScript==
  13. (function($) {
  14. 'use strict';
  15.  
  16. // max cell with in chars count
  17. var MAX_COL_SIZE = 80;
  18.  
  19. var Str = {};
  20.  
  21. $(function(){
  22. var lastThreeKeys = [], combinationLength = 3;
  23.  
  24. // region [ Display Control ]
  25. /**
  26. * Insert the "MD" button to all the last cell in the header of
  27. * all the tables in the current page.
  28. * @private
  29. */
  30. function displayTableControl(){
  31. $('table').each(function(i, e){
  32. var id = 'btn-copy-md-' + i, $tb = $(e),
  33. $btnMd = $('<button type="button" class="convert-to-markdown btn btn-primary" />'),
  34. $lastCell = $tb.find('tr:first').find('td:last, th:last').first();
  35.  
  36. $btnMd.css({
  37. height: '20px',
  38. width: '30px',
  39. 'background-color': '#81358c',
  40. color: '#fff',
  41. padding: '0'
  42. }).text('MD').attr('id', id);
  43.  
  44. // copy markdown content to the clipboard
  45. new Clipboard('#' + id, {
  46. text: function() {
  47. return convertTableToMd($btnMd);
  48. }
  49. });
  50.  
  51. $lastCell.append($btnMd);
  52. });
  53.  
  54. //$('.convert-to-markdown').click(convertTableToMd);
  55. }
  56. // endregion
  57.  
  58. // region [ Code ]
  59. /**
  60. * Extract the data from the table. Return array of row of data along with
  61. * the maximum length for each column.
  62. *
  63. * @param $table
  64. * @returns {{maxLengths: Array, tableData: Array}}
  65. * @private
  66. */
  67. function getData($table){
  68. var maxLengths = [], tableData = [];
  69.  
  70. function setMax(index, length){
  71. // create new column if does not exist
  72. while(index >= maxLengths.length){
  73. maxLengths.push(0);
  74. }
  75. maxLengths[index] = Math.max(maxLengths[index], length);
  76. }
  77.  
  78. $table.find('tr').each(function(trIndex, tr){
  79. var $tr = $(tr), row = [], offset = 0;
  80.  
  81. $tr.find('td, th').each(function(i, td){
  82. var $td = $(td), text = getText($td, trIndex), tl = text.length,
  83. index = i + offset, colspan = $td.attr('colspan');
  84.  
  85. setMax(index, tl);
  86. row.push(text);
  87.  
  88. if (colspan && $.isNumeric(colspan) && Number(colspan) > 1){
  89. colspan = Number(colspan);
  90. offset += colspan - 1;
  91. for (var k=0; k<colspan; k++){
  92. row.push('');
  93. }
  94. }
  95. });
  96.  
  97. tableData.push(row);
  98. });
  99.  
  100. return {
  101. maxLengths: maxLengths,
  102. tableData: tableData
  103. };
  104. }
  105.  
  106. /**
  107. * Convert the data from getData to actual markdown content.
  108. *
  109. * @param $btn - The "MD" button housed inside the table.
  110. * @returns {string} - The markdown table content
  111. * @private
  112. */
  113. function convertTableToMd($btn){
  114. var md = '', $table = $btn.parents('table'), data = getData($table), i, k,
  115. maxLengths = data.maxLengths;
  116.  
  117. for (i=0; i<data.tableData.length; i++){
  118. var row = data.tableData[i], rowMd = '| ', sepMd = '| ';
  119.  
  120. for(k=0; k<row.length; k++){
  121. var rowWidth = Math.min(maxLengths[k], MAX_COL_SIZE),
  122. text = Str.padRight(row[k], ' ', rowWidth);
  123. rowMd += text + ' | ';
  124.  
  125. // add header separator
  126. if (i === 0){
  127. sepMd += Str.repeat(' ', rowWidth) + ' | ';
  128. }
  129. }
  130.  
  131. if (rowMd.length > 2){
  132. md += Str.trim(rowMd) + "\n";
  133. if (sepMd.length > 2){
  134. md += Str.trim(sepMd).replace(/ /g, '-') + "\n";
  135. }
  136. }
  137. }
  138.  
  139. md += getReferenceLink($table);
  140.  
  141. // copied indicator
  142. $btn.css('background-color', '#6AB714');
  143. setTimeout(function(){
  144. $btn.css('background-color', '#81358c');
  145. }, 3000);
  146.  
  147. return md;
  148. }
  149.  
  150. /**
  151. * Generate markdown link to the table for future reference.
  152. *
  153. * @param $table
  154. * @returns {*}
  155. */
  156. function getReferenceLink($table) {
  157. var refLink, $anchor, refId = $table.attr('id'), href = location.href;
  158.  
  159. if(!refId) {
  160. $anchor = $table.parents('[id]').first();
  161. if ($anchor.length){
  162. refId = $anchor.attr('id');
  163. }
  164. }
  165.  
  166. if (refId) {
  167. if (href.indexOf('#') != -1) {
  168. refLink = href.replace(/#.+/, '#' + refId);
  169. }
  170. else {
  171. refLink = href + '#' + refId;
  172. }
  173. }
  174. // if no id link, then just use the main link as reference
  175. refLink = refLink || href;
  176. return '[Table Source](' + refLink + ')';
  177. }
  178.  
  179. /**
  180. * Clean up the text for the cell content. Like remove new line so it doesn't break the table.
  181. *
  182. * @param $td
  183. * @param trIndex
  184. * @returns {string|*}
  185. */
  186. function getText($td, trIndex) {
  187. var text = $td.text();
  188. if (trIndex === 0){
  189. // remove the MD link from the text
  190. text = text.replace(/MD$/, '');
  191. }
  192. text = text.replace("\n", '');
  193. text = text.replace(/\s/g, ' ');
  194. return Str.trim(text);
  195. }
  196. // endregion
  197.  
  198. // region [ Capture shortcut keys ]
  199. // Activate Markdown Converter Interface
  200. // => Shift, Shift, T (3 key strokes as a sequence, NOT press all together)
  201. $(document).on('keydown', function(e) {
  202. lastThreeKeys.push(e.which);
  203. lastThreeKeys = lastThreeKeys.slice(-combinationLength);
  204. if (lastThreeKeys.toString() == '16,16,84') {
  205. displayTableControl();
  206. e.preventDefault();
  207. return false;
  208. }
  209. });
  210. // endregion
  211.  
  212. // uncomment for dev
  213. // displayTableControl();
  214.  
  215. }); //end jqReady
  216.  
  217. // region [ Str Lib ]
  218. Str.trim = function (s) {
  219. return s.replace(/^\s+/, '').replace(/\s+$/, '');
  220. };
  221.  
  222. Str.padRight = function(s, padStr, totalLength){
  223. return s.length >= totalLength ? s : s + Str.repeat(padStr, (totalLength-s.length)/padStr.length);
  224. };
  225.  
  226. Str.repeat = function(s, count) {
  227. var newS = "", i;
  228. for (i=0; i<count; i++) {
  229. newS += s;
  230. }
  231. return newS;
  232. };
  233. // endregion
  234.  
  235. })(jQuery.noConflict(true));

QingJ © 2025

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