copy-identifier-encoding.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. 'use strict';
  2. var entityPrefixLength = require('./entity-prefix-length');
  3. module.exports = copy;
  4. var PUNCTUATION = /[-!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~_]/;
  5. /* For shortcut and collapsed reference links, the contents
  6. * is also an identifier, so we need to restore the original
  7. * encoding and escaping that were present in the source
  8. * string.
  9. *
  10. * This function takes the unescaped & unencoded value from
  11. * shortcut's child nodes and the identifier and encodes
  12. * the former according to the latter. */
  13. function copy(value, identifier) {
  14. var length = value.length;
  15. var count = identifier.length;
  16. var result = [];
  17. var position = 0;
  18. var index = 0;
  19. var start;
  20. while (index < length) {
  21. /* Take next non-punctuation characters from `value`. */
  22. start = index;
  23. while (index < length && !PUNCTUATION.test(value.charAt(index))) {
  24. index += 1;
  25. }
  26. result.push(value.slice(start, index));
  27. /* Advance `position` to the next punctuation character. */
  28. while (position < count && !PUNCTUATION.test(identifier.charAt(position))) {
  29. position += 1;
  30. }
  31. /* Take next punctuation characters from `identifier`. */
  32. start = position;
  33. while (position < count && PUNCTUATION.test(identifier.charAt(position))) {
  34. if (identifier.charAt(position) === '&') {
  35. position += entityPrefixLength(identifier.slice(position));
  36. }
  37. position += 1;
  38. }
  39. result.push(identifier.slice(start, position));
  40. /* Advance `index` to the next non-punctuation character. */
  41. while (index < length && PUNCTUATION.test(value.charAt(index))) {
  42. index += 1;
  43. }
  44. }
  45. return result.join('');
  46. }