code-indented.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. 'use strict';
  2. var repeat = require('repeat-string');
  3. var trim = require('trim-trailing-lines');
  4. module.exports = indentedCode;
  5. var C_NEWLINE = '\n';
  6. var C_TAB = '\t';
  7. var C_SPACE = ' ';
  8. var CODE_INDENT_COUNT = 4;
  9. var CODE_INDENT = repeat(C_SPACE, CODE_INDENT_COUNT);
  10. /* Tokenise indented code. */
  11. function indentedCode(eat, value, silent) {
  12. var index = -1;
  13. var length = value.length;
  14. var subvalue = '';
  15. var content = '';
  16. var subvalueQueue = '';
  17. var contentQueue = '';
  18. var character;
  19. var blankQueue;
  20. var indent;
  21. while (++index < length) {
  22. character = value.charAt(index);
  23. if (indent) {
  24. indent = false;
  25. subvalue += subvalueQueue;
  26. content += contentQueue;
  27. subvalueQueue = '';
  28. contentQueue = '';
  29. if (character === C_NEWLINE) {
  30. subvalueQueue = character;
  31. contentQueue = character;
  32. } else {
  33. subvalue += character;
  34. content += character;
  35. while (++index < length) {
  36. character = value.charAt(index);
  37. if (!character || character === C_NEWLINE) {
  38. contentQueue = character;
  39. subvalueQueue = character;
  40. break;
  41. }
  42. subvalue += character;
  43. content += character;
  44. }
  45. }
  46. } else if (
  47. character === C_SPACE &&
  48. value.charAt(index + 1) === character &&
  49. value.charAt(index + 2) === character &&
  50. value.charAt(index + 3) === character
  51. ) {
  52. subvalueQueue += CODE_INDENT;
  53. index += 3;
  54. indent = true;
  55. } else if (character === C_TAB) {
  56. subvalueQueue += character;
  57. indent = true;
  58. } else {
  59. blankQueue = '';
  60. while (character === C_TAB || character === C_SPACE) {
  61. blankQueue += character;
  62. character = value.charAt(++index);
  63. }
  64. if (character !== C_NEWLINE) {
  65. break;
  66. }
  67. subvalueQueue += blankQueue + character;
  68. contentQueue += character;
  69. }
  70. }
  71. if (content) {
  72. if (silent) {
  73. return true;
  74. }
  75. return eat(subvalue)({
  76. type: 'code',
  77. lang: null,
  78. value: trim(content)
  79. });
  80. }
  81. }