Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. const diff = require('fast-diff');
  2. const LINE_ENDING_RE = /\r\n|[\r\n\u2028\u2029]/;
  3. /**
  4. * Converts invisible characters to a commonly recognizable visible form.
  5. * @param {string} str - The string with invisibles to convert.
  6. * @returns {string} The converted string.
  7. */
  8. function showInvisibles(str) {
  9. let ret = '';
  10. for (let i = 0; i < str.length; i++) {
  11. switch (str[i]) {
  12. case ' ':
  13. ret += '·'; // Middle Dot, \u00B7
  14. break;
  15. case '\n':
  16. ret += '⏎'; // Return Symbol, \u23ce
  17. break;
  18. case '\t':
  19. ret += '↹'; // Left Arrow To Bar Over Right Arrow To Bar, \u21b9
  20. break;
  21. case '\r':
  22. ret += '␍'; // Carriage Return Symbol, \u240D
  23. break;
  24. default:
  25. ret += str[i];
  26. break;
  27. }
  28. }
  29. return ret;
  30. }
  31. /**
  32. * Generate results for differences between source code and formatted version.
  33. *
  34. * @param {string} source - The original source.
  35. * @param {string} prettierSource - The Prettier formatted source.
  36. * @returns {Array} - An array containing { operation, offset, insertText, deleteText }
  37. */
  38. function generateDifferences(source, prettierSource) {
  39. // fast-diff returns the differences between two texts as a series of
  40. // INSERT, DELETE or EQUAL operations. The results occur only in these
  41. // sequences:
  42. // /-> INSERT -> EQUAL
  43. // EQUAL | /-> EQUAL
  44. // \-> DELETE |
  45. // \-> INSERT -> EQUAL
  46. // Instead of reporting issues at each INSERT or DELETE, certain sequences
  47. // are batched together and are reported as a friendlier "replace" operation:
  48. // - A DELETE immediately followed by an INSERT.
  49. // - Any number of INSERTs and DELETEs where the joining EQUAL of one's end
  50. // and another's beginning does not have line endings (i.e. issues that occur
  51. // on contiguous lines).
  52. const results = diff(source, prettierSource);
  53. const differences = [];
  54. const batch = [];
  55. let offset = 0; // NOTE: INSERT never advances the offset.
  56. while (results.length) {
  57. const result = results.shift();
  58. const op = result[0];
  59. const text = result[1];
  60. switch (op) {
  61. case diff.INSERT:
  62. case diff.DELETE:
  63. batch.push(result);
  64. break;
  65. case diff.EQUAL:
  66. if (results.length) {
  67. if (batch.length) {
  68. if (LINE_ENDING_RE.test(text)) {
  69. flush();
  70. offset += text.length;
  71. } else {
  72. batch.push(result);
  73. }
  74. } else {
  75. offset += text.length;
  76. }
  77. }
  78. break;
  79. default:
  80. throw new Error(`Unexpected fast-diff operation "${op}"`);
  81. }
  82. if (batch.length && !results.length) {
  83. flush();
  84. }
  85. }
  86. return differences;
  87. function flush() {
  88. let aheadDeleteText = '';
  89. let aheadInsertText = '';
  90. while (batch.length) {
  91. const next = batch.shift();
  92. const op = next[0];
  93. const text = next[1];
  94. switch (op) {
  95. case diff.INSERT:
  96. aheadInsertText += text;
  97. break;
  98. case diff.DELETE:
  99. aheadDeleteText += text;
  100. break;
  101. case diff.EQUAL:
  102. aheadDeleteText += text;
  103. aheadInsertText += text;
  104. break;
  105. }
  106. }
  107. if (aheadDeleteText && aheadInsertText) {
  108. differences.push({
  109. offset,
  110. operation: generateDifferences.REPLACE,
  111. insertText: aheadInsertText,
  112. deleteText: aheadDeleteText,
  113. });
  114. } else if (!aheadDeleteText && aheadInsertText) {
  115. differences.push({
  116. offset,
  117. operation: generateDifferences.INSERT,
  118. insertText: aheadInsertText,
  119. });
  120. } else if (aheadDeleteText && !aheadInsertText) {
  121. differences.push({
  122. offset,
  123. operation: generateDifferences.DELETE,
  124. deleteText: aheadDeleteText,
  125. });
  126. }
  127. offset += aheadDeleteText.length;
  128. }
  129. }
  130. generateDifferences.INSERT = 'insert';
  131. generateDifferences.DELETE = 'delete';
  132. generateDifferences.REPLACE = 'replace';
  133. module.exports = {
  134. showInvisibles,
  135. generateDifferences,
  136. };