template-tokenize.js 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. 'use strict';
  2. const tokenize = require('postcss/lib/tokenize');
  3. function templateTokenize(input, options = {}) {
  4. let pos = input.quasis[0].start;
  5. const quasis = input.quasis.filter((quasi) => quasi.start !== quasi.end);
  6. const tokenizer = tokenize(input, options);
  7. function tokenInExpressions(token, returned) {
  8. const start = pos;
  9. pos += token[1].length;
  10. if (
  11. !quasis.some((quasi) => start >= quasi.start && pos <= quasi.end) ||
  12. (returned.length && token[0] === returned[0][0])
  13. ) {
  14. return true;
  15. }
  16. if (returned.length) {
  17. back(token);
  18. }
  19. }
  20. function back(token) {
  21. pos -= token[1].length;
  22. return tokenizer.back(token);
  23. }
  24. function nextToken(opts) {
  25. const returned = [];
  26. let token;
  27. let line;
  28. let column;
  29. while ((token = tokenizer.nextToken(opts)) && tokenInExpressions(token, returned)) {
  30. line = token[4] || token[2] || line;
  31. column = token[5] || token[3] || column;
  32. returned.push(token);
  33. }
  34. if (returned.length) {
  35. token = [
  36. returned[0][0],
  37. returned.map((parentToken) => parentToken[1]).join(''),
  38. returned[0][2],
  39. returned[0][3],
  40. line,
  41. column,
  42. ];
  43. }
  44. return token;
  45. }
  46. return { ...tokenizer, back, nextToken };
  47. }
  48. module.exports = templateTokenize;