edit_diff.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. const htmlparser = require('htmlparser2');
  2. const {escapeFormatting} = require('./functions.js');
  3. /**
  4. * Change edit diffs to markdown text.
  5. * @param {String} html - The edit diff in HTML.
  6. * @param {String} more - The localized string for more content.
  7. * @param {String} whitespace - The localized string for only whitespace.
  8. * @returns {String[]}
  9. */
  10. function diffParser(html, more, whitespace) {
  11. var current_tag = '';
  12. var last_ins = null;
  13. var last_del = null;
  14. var empty = false;
  15. var small_prev_ins = '';
  16. var small_prev_del = '';
  17. var ins_length = more.length;
  18. var del_length = more.length;
  19. var parser = new htmlparser.Parser( {
  20. onopentag: (tagname, attribs) => {
  21. if ( tagname === 'ins' || tagname == 'del' ) current_tag = tagname;
  22. if ( tagname === 'td' && attribs.class === 'diff-addedline' && ins_length <= 1000 ) {
  23. current_tag = 'tda';
  24. last_ins = '';
  25. }
  26. if ( tagname === 'td' && attribs.class === 'diff-deletedline' && del_length <= 1000 ) {
  27. current_tag = 'tdd';
  28. last_del = '';
  29. }
  30. if ( tagname === 'td' && attribs.class === 'diff-empty' ) empty = true;
  31. },
  32. ontext: (htmltext) => {
  33. if ( current_tag === 'ins' && ins_length <= 1000 ) {
  34. ins_length += ( '**' + escapeFormatting(htmltext) + '**' ).length;
  35. if ( ins_length <= 1000 ) last_ins += '**' + escapeFormatting(htmltext) + '**';
  36. }
  37. if ( current_tag === 'del' && del_length <= 1000 ) {
  38. del_length += ( '~~' + escapeFormatting(htmltext) + '~~' ).length;
  39. if ( del_length <= 1000 ) last_del += '~~' + escapeFormatting(htmltext) + '~~';
  40. }
  41. if ( current_tag === 'tda' && ins_length <= 1000 ) {
  42. ins_length += escapeFormatting(htmltext).length;
  43. if ( ins_length <= 1000 ) last_ins += escapeFormatting(htmltext);
  44. }
  45. if ( current_tag === 'tdd' && del_length <= 1000 ) {
  46. del_length += escapeFormatting(htmltext).length;
  47. if ( del_length <= 1000 ) last_del += escapeFormatting(htmltext);
  48. }
  49. },
  50. onclosetag: (tagname) => {
  51. current_tag = '';
  52. if ( tagname === 'ins' ) current_tag = 'tda';
  53. if ( tagname === 'del' ) current_tag = 'tdd';
  54. if ( tagname === 'tr' ) {
  55. if ( last_ins !== null ) {
  56. ins_length++;
  57. if ( empty && last_ins.trim().length && !last_ins.includes( '**' ) ) {
  58. ins_length += 4;
  59. last_ins = '**' + last_ins + '**';
  60. }
  61. small_prev_ins += '\n' + last_ins;
  62. if ( ins_length > 1000 ) small_prev_ins += more;
  63. last_ins = null;
  64. }
  65. if ( last_del !== null ) {
  66. del_length++;
  67. if ( empty && last_del.trim().length && !last_del.includes( '~~' ) ) {
  68. del_length += 4;
  69. last_del = '~~' + last_del + '~~';
  70. }
  71. small_prev_del += '\n' + last_del;
  72. if ( del_length > 1000 ) small_prev_del += more;
  73. last_del = null;
  74. }
  75. empty = false;
  76. }
  77. }
  78. } );
  79. parser.write( html );
  80. parser.end();
  81. var compare = ['', ''];
  82. if ( small_prev_del.length ) {
  83. if ( small_prev_del.replace( /\~\~/g, '' ).trim().length ) {
  84. compare[0] = small_prev_del.replace( /\~\~\~\~/g, '' );
  85. } else compare[0] = whitespace;
  86. }
  87. if ( small_prev_ins.length ) {
  88. if ( small_prev_ins.replace( /\*\*/g, '' ).trim().length ) {
  89. compare[1] = small_prev_ins.replace( /\*\*\*\*/g, '' );
  90. } else compare[1] = whitespace;
  91. }
  92. return compare;
  93. }
  94. module.exports = diffParser;