parse_link_destination.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Parse link destination
  2. //
  3. 'use strict';
  4. var unescapeAll = require('../common/utils').unescapeAll;
  5. module.exports = function parseLinkDestination(str, pos, max) {
  6. var code, level,
  7. lines = 0,
  8. start = pos,
  9. result = {
  10. ok: false,
  11. pos: 0,
  12. lines: 0,
  13. str: ''
  14. };
  15. if (str.charCodeAt(pos) === 0x3C /* < */) {
  16. pos++;
  17. while (pos < max) {
  18. code = str.charCodeAt(pos);
  19. if (code === 0x0A /* \n */) { return result; }
  20. if (code === 0x3C /* < */) { return result; }
  21. if (code === 0x3E /* > */) {
  22. result.pos = pos + 1;
  23. result.str = unescapeAll(str.slice(start + 1, pos));
  24. result.ok = true;
  25. return result;
  26. }
  27. if (code === 0x5C /* \ */ && pos + 1 < max) {
  28. pos += 2;
  29. continue;
  30. }
  31. pos++;
  32. }
  33. // no closing '>'
  34. return result;
  35. }
  36. // this should be ... } else { ... branch
  37. level = 0;
  38. while (pos < max) {
  39. code = str.charCodeAt(pos);
  40. if (code === 0x20) { break; }
  41. // ascii control characters
  42. if (code < 0x20 || code === 0x7F) { break; }
  43. if (code === 0x5C /* \ */ && pos + 1 < max) {
  44. if (str.charCodeAt(pos + 1) === 0x20) { break; }
  45. pos += 2;
  46. continue;
  47. }
  48. if (code === 0x28 /* ( */) {
  49. level++;
  50. if (level > 32) { return result; }
  51. }
  52. if (code === 0x29 /* ) */) {
  53. if (level === 0) { break; }
  54. level--;
  55. }
  56. pos++;
  57. }
  58. if (start === pos) { return result; }
  59. if (level !== 0) { return result; }
  60. result.str = unescapeAll(str.slice(start, pos));
  61. result.lines = lines;
  62. result.pos = pos;
  63. result.ok = true;
  64. return result;
  65. };