docxmlater 1.14.0 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -860,58 +860,92 @@ class DocumentParser {
860
860
  return null;
861
861
  }
862
862
  }
863
- mergeConsecutiveHyperlinks(paragraph) {
863
+ mergeConsecutiveHyperlinks(paragraph, resetFormatting = false) {
864
864
  const content = paragraph.getContent();
865
865
  if (!content || content.length < 2)
866
866
  return;
867
+ const hyperlinkGroups = new Map();
868
+ const nonHyperlinkItems = [];
869
+ const hyperlinkIndices = new Map();
870
+ for (let i = 0; i < content.length; i++) {
871
+ const item = content[i];
872
+ if (item.constructor.name === 'Hyperlink') {
873
+ const hyperlink = item;
874
+ const url = hyperlink.getUrl() || '';
875
+ const anchor = hyperlink.getAnchor() || '';
876
+ const key = `${url}|${anchor}`;
877
+ if (!hyperlinkGroups.has(key)) {
878
+ hyperlinkGroups.set(key, []);
879
+ }
880
+ hyperlinkGroups.get(key).push(hyperlink);
881
+ hyperlinkIndices.set(hyperlink, i);
882
+ }
883
+ else {
884
+ nonHyperlinkItems.push({ item, index: i });
885
+ }
886
+ }
887
+ let needsMerge = false;
888
+ for (const group of hyperlinkGroups.values()) {
889
+ if (group.length > 1) {
890
+ needsMerge = true;
891
+ break;
892
+ }
893
+ }
894
+ if (!needsMerge && !resetFormatting) {
895
+ return;
896
+ }
867
897
  const mergedContent = [];
868
- let i = 0;
869
- while (i < content.length) {
870
- const currentItem = content[i];
871
- if (currentItem.constructor.name === 'Hyperlink') {
872
- const currentHyperlink = currentItem;
873
- const currentUrl = currentHyperlink.getUrl();
874
- const currentAnchor = currentHyperlink.getAnchor();
875
- const consecutiveHyperlinks = [currentHyperlink];
876
- let j = i + 1;
877
- while (j < content.length) {
878
- const nextItem = content[j];
879
- if (nextItem.constructor.name !== 'Hyperlink')
880
- break;
881
- const nextHyperlink = nextItem;
882
- const nextUrl = nextHyperlink.getUrl();
883
- const nextAnchor = nextHyperlink.getAnchor();
884
- if (nextUrl !== currentUrl || nextAnchor !== currentAnchor)
885
- break;
886
- consecutiveHyperlinks.push(nextHyperlink);
887
- j++;
888
- }
889
- if (consecutiveHyperlinks.length > 1) {
890
- const mergedText = consecutiveHyperlinks
891
- .map(h => h.getText())
892
- .join('');
893
- const mergedHyperlink = new currentHyperlink.constructor({
894
- url: currentUrl,
895
- anchor: currentAnchor,
898
+ const processedIndices = new Set();
899
+ for (let i = 0; i < content.length; i++) {
900
+ if (processedIndices.has(i)) {
901
+ continue;
902
+ }
903
+ const item = content[i];
904
+ if (item.constructor.name === 'Hyperlink') {
905
+ const hyperlink = item;
906
+ const url = hyperlink.getUrl() || '';
907
+ const anchor = hyperlink.getAnchor() || '';
908
+ const key = `${url}|${anchor}`;
909
+ const group = hyperlinkGroups.get(key);
910
+ if (group.length > 1 && group[0] === hyperlink) {
911
+ const mergedText = group.map(h => h.getText()).join('');
912
+ const mergedHyperlink = new hyperlink.constructor({
913
+ url: hyperlink.getUrl(),
914
+ anchor: hyperlink.getAnchor(),
896
915
  text: mergedText,
897
- formatting: currentHyperlink.getFormatting(),
898
- tooltip: currentHyperlink.getTooltip(),
899
- relationshipId: currentHyperlink.getRelationshipId(),
916
+ formatting: resetFormatting ? this.getStandardHyperlinkFormatting() : hyperlink.getFormatting(),
917
+ tooltip: hyperlink.getTooltip(),
918
+ relationshipId: hyperlink.getRelationshipId(),
900
919
  });
920
+ for (const h of group) {
921
+ processedIndices.add(hyperlinkIndices.get(h));
922
+ }
901
923
  mergedContent.push(mergedHyperlink);
902
- i = j;
903
924
  }
904
- else {
905
- mergedContent.push(currentHyperlink);
906
- i++;
925
+ else if (group.length === 1) {
926
+ if (resetFormatting) {
927
+ const resetHyperlink = new hyperlink.constructor({
928
+ url: hyperlink.getUrl(),
929
+ anchor: hyperlink.getAnchor(),
930
+ text: hyperlink.getText(),
931
+ formatting: this.getStandardHyperlinkFormatting(),
932
+ tooltip: hyperlink.getTooltip(),
933
+ relationshipId: hyperlink.getRelationshipId(),
934
+ });
935
+ mergedContent.push(resetHyperlink);
936
+ }
937
+ else {
938
+ mergedContent.push(hyperlink);
939
+ }
940
+ processedIndices.add(i);
907
941
  }
908
942
  }
909
943
  else {
910
- mergedContent.push(currentItem);
911
- i++;
944
+ mergedContent.push(item);
945
+ processedIndices.add(i);
912
946
  }
913
947
  }
914
- if (mergedContent.length !== content.length) {
948
+ if (needsMerge || resetFormatting) {
915
949
  paragraph.clearContent();
916
950
  for (const item of mergedContent) {
917
951
  if (item.constructor.name === 'Hyperlink') {
@@ -926,6 +960,13 @@ class DocumentParser {
926
960
  }
927
961
  }
928
962
  }
963
+ getStandardHyperlinkFormatting() {
964
+ return {
965
+ font: 'Calibri',
966
+ color: '0563C1',
967
+ underline: 'single'
968
+ };
969
+ }
929
970
  parseSimpleFieldFromObject(fieldObj) {
930
971
  try {
931
972
  const instruction = fieldObj["@_w:instr"];