parsers.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. function skipws (str) {
  2. var i = 0
  3. do {
  4. if (str[i] !== ' ' && str[i] !== '\t') { return i }
  5. } while (++i < str.length)
  6. return i
  7. }
  8. /* ------- default parsers ------- */
  9. var PARSERS = {}
  10. PARSERS.parse_tag = function parse_tag (str) {
  11. var result = str.match(/^\s*@(\S+)/)
  12. if (!result) { throw new Error('Invalid `@tag`, missing @ symbol') }
  13. return {
  14. source: result[0],
  15. data: {tag: result[1]}
  16. }
  17. }
  18. PARSERS.parse_type = function parse_type (str, data) {
  19. if (data.errors && data.errors.length) { return null }
  20. var pos = skipws(str)
  21. var res = ''
  22. var curlies = 0
  23. if (str[pos] !== '{') { return null }
  24. while (pos < str.length) {
  25. curlies += (str[pos] === '{' ? 1 : (str[pos] === '}' ? -1 : 0))
  26. res += str[pos]
  27. pos++
  28. if (curlies === 0) { break }
  29. }
  30. if (curlies !== 0) { throw new Error('Invalid `{type}`, unpaired curlies') }
  31. return {
  32. source: str.slice(0, pos),
  33. data: {type: res.slice(1, -1)}
  34. }
  35. }
  36. PARSERS.parse_name = function parse_name (str, data) {
  37. if (data.errors && data.errors.length) { return null }
  38. var pos = skipws(str)
  39. var name = ''
  40. var brackets = 0
  41. var res = {optional: false}
  42. // if it starts with quoted group assume it is a literal
  43. var quotedGroups = str.slice(pos).split('"')
  44. if (quotedGroups.length > 1 && quotedGroups[0] === '' && quotedGroups.length % 2 === 1) {
  45. name = quotedGroups[1]
  46. pos += name.length + 2
  47. // assume name is non-space string or anything wrapped into brackets
  48. } else {
  49. while (pos < str.length) {
  50. brackets += (str[pos] === '[' ? 1 : (str[pos] === ']' ? -1 : 0))
  51. name += str[pos]
  52. pos++
  53. if (brackets === 0 && /\s/.test(str[pos])) { break }
  54. }
  55. if (brackets !== 0) { throw new Error('Invalid `name`, unpaired brackets') }
  56. res = {name: name, optional: false}
  57. if (name[0] === '[' && name[name.length - 1] === ']') {
  58. res.optional = true
  59. name = name.slice(1, -1)
  60. if (name.indexOf('=') !== -1) {
  61. var parts = name.split('=')
  62. name = parts[0]
  63. res.default = parts[1].replace(/^(["'])(.+)(\1)$/, '$2')
  64. }
  65. }
  66. }
  67. res.name = name
  68. return {
  69. source: str.slice(0, pos),
  70. data: res
  71. }
  72. }
  73. PARSERS.parse_description = function parse_description (str, data) {
  74. if (data.errors && data.errors.length) { return null }
  75. var result = str.match(/^\s+((.|\s)+)?/)
  76. if (result) {
  77. return {
  78. source: result[0],
  79. data: {description: result[1] === undefined ? '' : result[1]}
  80. }
  81. }
  82. return null
  83. }
  84. module.exports = PARSERS