parse_link_destination.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // Parse link destination
  2. //
  3. 'use strict';
  4. var isSpace = require('../common/utils').isSpace;
  5. var unescapeAll = require('../common/utils').unescapeAll;
  6. module.exports = function parseLinkDestination(str, pos, max) {
  7. var code, level,
  8. lines = 0,
  9. start = pos,
  10. result = {
  11. ok: false,
  12. pos: 0,
  13. lines: 0,
  14. str: ''
  15. };
  16. if (str.charCodeAt(pos) === 0x3C /* < */) {
  17. pos++;
  18. while (pos < max) {
  19. code = str.charCodeAt(pos);
  20. if (code === 0x0A /* \n */ || isSpace(code)) { 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. pos += 2;
  45. continue;
  46. }
  47. if (code === 0x28 /* ( */) {
  48. level++;
  49. }
  50. if (code === 0x29 /* ) */) {
  51. if (level === 0) { break; }
  52. level--;
  53. }
  54. pos++;
  55. }
  56. if (start === pos) { return result; }
  57. if (level !== 0) { return result; }
  58. result.str = unescapeAll(str.slice(start, pos));
  59. result.lines = lines;
  60. result.pos = pos;
  61. result.ok = true;
  62. return result;
  63. };