cst-stringify.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /**
  2. * Stringify a CST document, token, or collection item
  3. *
  4. * Fair warning: This applies no validation whatsoever, and
  5. * simply concatenates the sources in their logical order.
  6. */
  7. const stringify = (cst) => 'type' in cst ? stringifyToken(cst) : stringifyItem(cst);
  8. function stringifyToken(token) {
  9. switch (token.type) {
  10. case 'block-scalar': {
  11. let res = '';
  12. for (const tok of token.props)
  13. res += stringifyToken(tok);
  14. return res + token.source;
  15. }
  16. case 'block-map':
  17. case 'block-seq': {
  18. let res = '';
  19. for (const item of token.items)
  20. res += stringifyItem(item);
  21. return res;
  22. }
  23. case 'flow-collection': {
  24. let res = token.start.source;
  25. for (const item of token.items)
  26. res += stringifyItem(item);
  27. for (const st of token.end)
  28. res += st.source;
  29. return res;
  30. }
  31. case 'document': {
  32. let res = stringifyItem(token);
  33. if (token.end)
  34. for (const st of token.end)
  35. res += st.source;
  36. return res;
  37. }
  38. default: {
  39. let res = token.source;
  40. if ('end' in token && token.end)
  41. for (const st of token.end)
  42. res += st.source;
  43. return res;
  44. }
  45. }
  46. }
  47. function stringifyItem({ start, key, sep, value }) {
  48. let res = '';
  49. for (const st of start)
  50. res += st.source;
  51. if (key)
  52. res += stringifyToken(key);
  53. if (sep)
  54. for (const st of sep)
  55. res += st.source;
  56. if (value)
  57. res += stringifyToken(value);
  58. return res;
  59. }
  60. export { stringify };