Table to Markdown Copier

Convert html table to markdown format

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

QingJ © 2025

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