parse_link_destination.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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 === 0x3E /* > */) {
  21. result.pos = pos + 1;
  22. result.str = unescapeAll(str.slice(start + 1, pos));
  23. result.ok = true;
  24. return result;
  25. }
  26. if (code === 0x5C /* \ */ && pos + 1 < max) {
  27. pos += 2;
  28. continue;
  29. }
  30. pos++;
  31. }
  32. // no closing '>'
  33. return result;
  34. }
  35. // this should be ... } else { ... branch
  36. level = 0;
  37. while (pos < max) {
  38. code = str.charCodeAt(pos);
  39. if (code === 0x20) { break; }
  40. // ascii control characters
  41. if (code < 0x20 || code === 0x7F) { break; }
  42. if (code === 0x5C /* \ */ && pos + 1 < max) {
  43. pos += 2;
  44. continue;
  45. }
  46. if (code === 0x28 /* ( */) {
  47. level++;
  48. }
  49. if (code === 0x29 /* ) */) {
  50. if (level === 0) { break; }
  51. level--;
  52. }
  53. pos++;
  54. }
  55. if (start === pos) { return result; }
  56. if (level !== 0) { return result; }
  57. result.str = unescapeAll(str.slice(start, pos));
  58. result.lines = lines;
  59. result.pos = pos;
  60. result.ok = true;
  61. return result;
  62. };