--- /dev/null
+'use strict';
+
+var entityPrefixLength = require('./entity-prefix-length');
+
+module.exports = copy;
+
+var PUNCTUATION = /[-!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~_]/;
+
+/* For shortcut and collapsed reference links, the contents
+ * is also an identifier, so we need to restore the original
+ * encoding and escaping that were present in the source
+ * string.
+ *
+ * This function takes the unescaped & unencoded value from
+ * shortcut's child nodes and the identifier and encodes
+ * the former according to the latter. */
+function copy(value, identifier) {
+ var length = value.length;
+ var count = identifier.length;
+ var result = [];
+ var position = 0;
+ var index = 0;
+ var start;
+
+ while (index < length) {
+ /* Take next non-punctuation characters from `value`. */
+ start = index;
+
+ while (index < length && !PUNCTUATION.test(value.charAt(index))) {
+ index += 1;
+ }
+
+ result.push(value.slice(start, index));
+
+ /* Advance `position` to the next punctuation character. */
+ while (position < count && !PUNCTUATION.test(identifier.charAt(position))) {
+ position += 1;
+ }
+
+ /* Take next punctuation characters from `identifier`. */
+ start = position;
+
+ while (position < count && PUNCTUATION.test(identifier.charAt(position))) {
+ if (identifier.charAt(position) === '&') {
+ position += entityPrefixLength(identifier.slice(position));
+ }
+
+ position += 1;
+ }
+
+ result.push(identifier.slice(start, position));
+
+ /* Advance `index` to the next non-punctuation character. */
+ while (index < length && PUNCTUATION.test(value.charAt(index))) {
+ index += 1;
+ }
+ }
+
+ return result.join('');
+}