edit_diff.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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' ) {
  23. let classes = ( attribs.class?.split(' ') || [] );
  24. if ( classes.includes( 'diff-addedline' ) && ins_length <= 1000 ) {
  25. current_tag = 'tda';
  26. last_ins = '';
  27. }
  28. if ( classes.includes( 'diff-deletedline' ) && del_length <= 1000 ) {
  29. current_tag = 'tdd';
  30. last_del = '';
  31. }
  32. if ( classes.includes( 'diff-empty' ) ) empty = true;
  33. }
  34. },
  35. ontext: (htmltext) => {
  36. if ( current_tag === 'ins' && ins_length <= 1000 ) {
  37. ins_length += ( '**' + escapeFormatting(htmltext) + '**' ).length;
  38. if ( ins_length <= 1000 ) last_ins += '**' + escapeFormatting(htmltext) + '**';
  39. }
  40. if ( current_tag === 'del' && del_length <= 1000 ) {
  41. del_length += ( '~~' + escapeFormatting(htmltext) + '~~' ).length;
  42. if ( del_length <= 1000 ) last_del += '~~' + escapeFormatting(htmltext) + '~~';
  43. }
  44. if ( current_tag === 'tda' && ins_length <= 1000 ) {
  45. ins_length += escapeFormatting(htmltext).length;
  46. if ( ins_length <= 1000 ) last_ins += escapeFormatting(htmltext);
  47. }
  48. if ( current_tag === 'tdd' && del_length <= 1000 ) {
  49. del_length += escapeFormatting(htmltext).length;
  50. if ( del_length <= 1000 ) last_del += escapeFormatting(htmltext);
  51. }
  52. },
  53. onclosetag: (tagname) => {
  54. current_tag = '';
  55. if ( tagname === 'ins' ) current_tag = 'tda';
  56. if ( tagname === 'del' ) current_tag = 'tdd';
  57. if ( tagname === 'tr' ) {
  58. if ( last_ins !== null ) {
  59. ins_length++;
  60. if ( empty && last_ins.trim().length && !last_ins.includes( '**' ) ) {
  61. ins_length += 4;
  62. last_ins = '**' + last_ins + '**';
  63. }
  64. small_prev_ins += '\n' + last_ins;
  65. if ( ins_length > 1000 ) small_prev_ins += more;
  66. last_ins = null;
  67. }
  68. if ( last_del !== null ) {
  69. del_length++;
  70. if ( empty && last_del.trim().length && !last_del.includes( '~~' ) ) {
  71. del_length += 4;
  72. last_del = '~~' + last_del + '~~';
  73. }
  74. small_prev_del += '\n' + last_del;
  75. if ( del_length > 1000 ) small_prev_del += more;
  76. last_del = null;
  77. }
  78. empty = false;
  79. }
  80. }
  81. } );
  82. parser.write( html );
  83. parser.end();
  84. var compare = ['', ''];
  85. if ( small_prev_del.length ) {
  86. if ( small_prev_del.replace( /\~\~/g, '' ).trim().length ) {
  87. compare[0] = small_prev_del.replace( /\~\~\~\~/g, '' );
  88. } else compare[0] = whitespace;
  89. }
  90. if ( small_prev_ins.length ) {
  91. if ( small_prev_ins.replace( /\*\*/g, '' ).trim().length ) {
  92. compare[1] = small_prev_ins.replace( /\*\*\*\*/g, '' );
  93. } else compare[1] = whitespace;
  94. }
  95. return compare;
  96. }
  97. module.exports = diffParser;