true if this is a reference to a {@link MBookmark}, false if it's a {@link MBookmark}
- * declaration
- */
- boolean isReference();
-
- /**
- * Tells if this reference can be omitted when the bookmark declaration doesn't exists.
- *
- * @return true if this reference can be omitted when the bookmark declaration doesn't exists, false if an
- * error
- * should be raised.
- */
- boolean isOptional();
-
- /**
- * Sets if this reference can be omitted when the bookmark declaration doesn't exists.
- *
- * @param optional
- * true if this reference can be omitted when the bookmark declaration doesn't exists, false if an
- * error
- */
- void setOptional(boolean optional);
-
}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkCustomTextRef.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkCustomTextRef.java
new file mode 100644
index 000000000..69b8ef4b3
--- /dev/null
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkCustomTextRef.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ *******************************************************************************/
+package org.obeonetwork.m2doc.element;
+
+/**
+ * A bookmark with a custom text reference (insert the custom text and reference the bookmark).
+ *
+ * @author Yvan Lussaud
+ */
+public interface MBookmarkCustomTextRef extends MBookmarkRef {
+
+ /**
+ * Gets the text to display.
+ *
+ * @return the text to display
+ */
+ String getText();
+
+ /**
+ * Sets the text to display.
+ *
+ * @param text
+ * the new text to display
+ */
+ void setText(String text);
+
+}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkPageRef.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkPageRef.java
new file mode 100644
index 000000000..9081400d0
--- /dev/null
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkPageRef.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ *******************************************************************************/
+package org.obeonetwork.m2doc.element;
+
+/**
+ * A bookmark page reference (insert the page number of the referenced bookmark).
+ *
+ * @author Yvan Lussaud
+ */
+public interface MBookmarkPageRef extends MBookmarkRef {
+
+}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkRef.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkRef.java
new file mode 100644
index 000000000..422069925
--- /dev/null
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkRef.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ *******************************************************************************/
+package org.obeonetwork.m2doc.element;
+
+/**
+ * A bookmark reference.
+ *
+ * @author Yvan Lussaud
+ */
+public interface MBookmarkRef extends MIdentifiable {
+
+ /**
+ * Tells if this reference can be omitted when the bookmark declaration doesn't exists.
+ *
+ * @return true if this reference can be omitted when the bookmark declaration doesn't exists, false if an
+ * error
+ * should be raised.
+ */
+ boolean isOptional();
+
+ /**
+ * Sets if this reference can be omitted when the bookmark declaration doesn't exists.
+ *
+ * @param optional
+ * true if this reference can be omitted when the bookmark declaration doesn't exists, false if an
+ * error
+ */
+ void setOptional(boolean optional);
+
+}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkSectionRef.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkSectionRef.java
new file mode 100644
index 000000000..2172c0e57
--- /dev/null
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkSectionRef.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ *******************************************************************************/
+package org.obeonetwork.m2doc.element;
+
+/**
+ * A bookmark section reference (insert the section name of the referenced bookmark).
+ *
+ * @author Yvan Lussaud
+ */
+public interface MBookmarkSectionRef extends MBookmarkRef {
+
+}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkTextRef.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkTextRef.java
new file mode 100644
index 000000000..199794ee2
--- /dev/null
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MBookmarkTextRef.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ *******************************************************************************/
+package org.obeonetwork.m2doc.element;
+
+/**
+ * A bookmark text reference (insert the text of the referenced bookmark).
+ *
+ * @author Yvan Lussaud
+ */
+public interface MBookmarkTextRef extends MBookmarkRef {
+
+}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MIdentifiable.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MIdentifiable.java
new file mode 100644
index 000000000..a4f1a6b08
--- /dev/null
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/MIdentifiable.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ *******************************************************************************/
+package org.obeonetwork.m2doc.element;
+
+/**
+ * Identifiable {@link MElement}.
+ *
+ * @author Yvan Lussaud
+ */
+public interface MIdentifiable extends MElement {
+
+ /**
+ * Gets the ID.
+ *
+ * @return the ID
+ */
+ String getId();
+
+ /**
+ * Sets the ID.
+ *
+ * @param id
+ * the new ID
+ */
+ void setId(String id);
+
+}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/AbstractMBookmarkRef.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/AbstractMBookmarkRef.java
new file mode 100644
index 000000000..cb835712d
--- /dev/null
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/AbstractMBookmarkRef.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ *******************************************************************************/
+package org.obeonetwork.m2doc.element.impl;
+
+import org.obeonetwork.m2doc.element.MBookmarkRef;
+
+/**
+ * Abstract implementation of {@link MBookmarkRef}.
+ *
+ * @author Yvan Lussaud
+ */
+public class AbstractMBookmarkRef implements MBookmarkRef {
+
+ /**
+ * The bookmark ID.
+ */
+ private String id;
+
+ /**
+ * Tells if this reference can be omitted when the bookmark declaration doesn't exists.
+ */
+ private boolean optional;
+
+ /**
+ * Constructor.
+ *
+ * @param id
+ * the bookmark id
+ * @param optional
+ * true if this reference can be omitted when the bookmark declaration doesn't exists, false
+ * otherwise
+ */
+ public AbstractMBookmarkRef(String id, boolean optional) {
+ this.id = id;
+ this.optional = optional;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public boolean isOptional() {
+ return optional;
+ }
+
+ @Override
+ public void setOptional(boolean optional) {
+ this.optional = optional;
+ }
+}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkCustomTextRefImpl.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkCustomTextRefImpl.java
new file mode 100644
index 000000000..58c2cc12e
--- /dev/null
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkCustomTextRefImpl.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ *******************************************************************************/
+package org.obeonetwork.m2doc.element.impl;
+
+import org.obeonetwork.m2doc.element.MBookmarkCustomTextRef;
+
+/**
+ * A bookmark text reference (insert the text of the referenced bookmark).
+ *
+ * @author Yvan Lussaud
+ */
+public class MBookmarkCustomTextRefImpl extends AbstractMBookmarkRef implements MBookmarkCustomTextRef {
+
+ /**
+ * The text to display.
+ */
+ private String text;
+
+ /**
+ * Constructor.
+ *
+ * @param text
+ * the custom text
+ * @param id
+ * the bookmark id
+ * @param optional
+ * true if this reference can be omitted when the bookmark declaration doesn't exists, false
+ * otherwise
+ */
+ public MBookmarkCustomTextRefImpl(String text, String id, boolean optional) {
+ super(id, optional);
+ this.text = text;
+ }
+
+ @Override
+ public String getText() {
+ return text;
+ }
+
+ @Override
+ public void setText(String text) {
+ this.text = text;
+ }
+
+}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkImpl.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkImpl.java
index 361ce8286..7059c9ad8 100644
--- a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkImpl.java
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2017, 2024 Obeo.
+ * Copyright (c) 2017, 2025 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
@@ -30,32 +30,17 @@ public class MBookmarkImpl implements MBookmark {
*/
private String id;
- /**
- * true if this is a reference to a {@link MBookmarkImpl}, false if it's a {@link MBookmarkImpl} declaration.
- */
- private final boolean reference;
-
- /**
- * true if this reference can be omitted when the bookmark declaration doesn't exists, false if an error
- * should be raised.
- */
- private boolean optional;
-
/**
* Constructor.
*
* @param text
* the text to display
* @param id
- * the id
- * @param reference
- * true if this is a reference to a {@link MBookmarkImpl}, false if it's a {@link MBookmarkImpl}
- * declaration
+ * the bookmark id
*/
- public MBookmarkImpl(String text, String id, boolean reference) {
+ public MBookmarkImpl(String text, String id) {
this.text = text;
this.id = id;
- this.reference = reference;
}
@Override
@@ -78,19 +63,4 @@ public void setId(String id) {
this.id = id;
}
- @Override
- public boolean isReference() {
- return reference;
- }
-
- @Override
- public boolean isOptional() {
- return optional;
- }
-
- @Override
- public void setOptional(boolean optional) {
- this.optional = optional;
- }
-
}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkPageRefImpl.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkPageRefImpl.java
new file mode 100644
index 000000000..6670a3964
--- /dev/null
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkPageRefImpl.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ *******************************************************************************/
+package org.obeonetwork.m2doc.element.impl;
+
+import org.obeonetwork.m2doc.element.MBookmarkPageRef;
+
+/**
+ * A bookmark page reference (insert the page number of the referenced bookmark).
+ *
+ * @author Yvan Lussaud
+ */
+public class MBookmarkPageRefImpl extends AbstractMBookmarkRef implements MBookmarkPageRef {
+
+ /**
+ * Constructor.
+ *
+ * @param id
+ * the bookmark id
+ * @param optional
+ * true if this reference can be omitted when the bookmark declaration doesn't exists, false
+ * otherwise
+ */
+ public MBookmarkPageRefImpl(String id, boolean optional) {
+ super(id, optional);
+ }
+
+}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkSectionRefImpl.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkSectionRefImpl.java
new file mode 100644
index 000000000..8538d4d97
--- /dev/null
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkSectionRefImpl.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ *******************************************************************************/
+package org.obeonetwork.m2doc.element.impl;
+
+import org.obeonetwork.m2doc.element.MBookmarkSectionRef;
+
+/**
+ * A bookmark section reference (insert the section name of the referenced bookmark).
+ *
+ * @author Yvan Lussaud
+ */
+public class MBookmarkSectionRefImpl extends AbstractMBookmarkRef implements MBookmarkSectionRef {
+
+ /**
+ * Constructor.
+ *
+ * @param id
+ * the bookmark id
+ * @param optional
+ * true if this reference can be omitted when the bookmark declaration doesn't exists, false
+ * otherwise
+ */
+ public MBookmarkSectionRefImpl(String id, boolean optional) {
+ super(id, optional);
+ }
+
+}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkTextRefImpl.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkTextRefImpl.java
new file mode 100644
index 000000000..a37596bdd
--- /dev/null
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/element/impl/MBookmarkTextRefImpl.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *
+ *******************************************************************************/
+package org.obeonetwork.m2doc.element.impl;
+
+import org.obeonetwork.m2doc.element.MBookmarkTextRef;
+
+/**
+ * A bookmark text reference (insert the text of the referenced bookmark).
+ *
+ * @author Yvan Lussaud
+ */
+public class MBookmarkTextRefImpl extends AbstractMBookmarkRef implements MBookmarkTextRef {
+
+ /**
+ * Constructor.
+ *
+ * @param id
+ * the bookmark id
+ * @param optional
+ * true if this reference can be omitted when the bookmark declaration doesn't exists, false
+ * otherwise
+ */
+ public MBookmarkTextRefImpl(String id, boolean optional) {
+ super(id, optional);
+ }
+
+}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/generator/BookmarkManager.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/generator/BookmarkManager.java
index fc6b8b611..72ea16e0c 100755
--- a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/generator/BookmarkManager.java
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/generator/BookmarkManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016, 2024 Obeo.
+ * Copyright (c) 2016, 2025 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
@@ -16,6 +16,8 @@
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -25,14 +27,19 @@
import org.apache.poi.xwpf.usermodel.IRunBody;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
+import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute.Space;
import org.obeonetwork.m2doc.parser.ValidationMessageLevel;
import org.obeonetwork.m2doc.util.M2DocUtils;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTMarkupRange;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType;
+import org.w3c.dom.Node;
/**
* Manage bookmarks.
@@ -41,6 +48,10 @@
*/
public class BookmarkManager {
+ /** WordprocessingML namespace. */
+ private static final String WORDPROCESSINGML_NAMESPACE =
+ "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
+
/**
* The buffer size.
*/
@@ -51,6 +62,16 @@ public class BookmarkManager {
*/
private static final String REF_TAG = " REF %s \\h ";
+ /**
+ * The reference section.
+ */
+ private static final String SECTION_REF_TAG = " REF %s \\n \\h ";
+
+ /**
+ * The reference page.
+ */
+ private static final String PAGE_REF_TAG = " PAGEREF %s \\h ";
+
/**
* Known bookmarks so far.
*/
@@ -86,6 +107,386 @@ public class BookmarkManager {
*/
private final Maptrue if this reference can be omitted when the bookmark declaration doesn't exists, false if an
+ * error should be inserted
+ */
+ public void insertPageReference(XWPFParagraph paragraph, String name, boolean optional) {
+ insertReference(paragraph, name, null, PAGE_REF_TAG, optional);
+ }
+
+ /**
+ * Inserts a reference with the bookmark section to the given name in the given {@link XWPFParagraph}.
+ *
+ * @param paragraph
+ * the {@link XWPFParagraph}
+ * @param name
+ * the bookmark name
+ * @param optional
+ * true if this reference can be omitted when the bookmark declaration doesn't exists, false if an
+ * error should be inserted
+ */
+ public void insertSectionReference(XWPFParagraph paragraph, String name, boolean optional) {
+ insertReference(paragraph, name, null, SECTION_REF_TAG, optional);
+ }
+
+ /**
+ * Inserts a reference with the bookmark text to the given name in the given {@link XWPFParagraph}.
+ *
+ * @param paragraph
+ * the {@link XWPFParagraph}
+ * @param name
+ * the bookmark name
+ * @param optional
+ * true if this reference can be omitted when the bookmark declaration doesn't exists, false if an
+ * error should be inserted
+ */
+ public void insertTextReference(XWPFParagraph paragraph, String name, boolean optional) {
+ insertReference(paragraph, name, null, REF_TAG, optional);
+ }
+
+ /**
+ * Inserts a reference with a custom text to the given name in the given {@link XWPFParagraph}.
+ *
+ * @param paragraph
+ * the {@link XWPFParagraph}
+ * @param name
+ * the bookmark name
+ * @param text
+ * the text
+ * @param optional
+ * true if this reference can be omitted when the bookmark declaration doesn't exists, false if an
+ * error should be inserted
+ */
+ public void insertCustomTextReference(XWPFParagraph paragraph, String name, String text, boolean optional) {
+ insertReference(paragraph, name, text, REF_TAG, optional);
+ }
+
/**
* Inserts a pending reference to the given name in the given {@link XWPFParagraph}.
*
@@ -184,21 +646,23 @@ private BigInteger getRandomID() {
* the bookmark name
* @param text
* the text
+ * @param format
+ * the instruction text format
* @param optional
* true if this reference can be omitted when the bookmark declaration doesn't exists, false if an
* error
*/
- public void insertReference(XWPFParagraph paragraph, String name, String text, boolean optional) {
+ public void insertReference(XWPFParagraph paragraph, String name, String text, String format, boolean optional) {
final CTBookmark bookmark = bookmarks.get(name);
if (bookmark != null) {
- insertReference(paragraph, bookmark, text);
+ insertReference(paragraph, bookmark, text, format);
} else {
final XWPFRun messageRun = paragraph.createRun();
final CTText ref = insertPendingReference(paragraph, name, text);
if (optional) {
optionalReferences.put(ref, text);
}
- ref.setStringValue(String.format(REF_TAG, name));
+ ref.setStringValue(String.format(format, name));
messagePositions.put(ref, messageRun);
SetM2Doc stores template metadata such as {@code m:M2DocVersion} and + * {@code m:uri:...} in {@code docProps/custom.xml}. These properties are + * useful while processing the template, but they must not leak into the + * generated deliverable.
+ * + * @param document + * the generated document + */ + private void removeM2DocCustomProperties(XWPFDocument document) { + final CustomProperties customProperties = document.getProperties().getCustomProperties(); + final CTProperties properties = customProperties.getUnderlyingProperties(); + + // Iterate backwards because XMLBeans exposes the properties as an + // indexed live array. Removing an item shifts every following item. + for (int i = properties.sizeOfPropertyArray() - 1; i >= 0; i--) { + final CTProperty property = properties.getPropertyArray(i); + final String name = property.getName(); + if (name != null && name.startsWith("m:")) { + properties.removeProperty(i); + } + } + } + /** * Updates sequences (SEQ) numbers in the given {@link XWPFDocument}.
*
@@ -476,6 +512,8 @@ private XWPFRun insertRun(XWPFParagraph paragraph, XWPFRun srcRun) {
newParagraph = paragraph;
}
+ bookmarkManager.copyNativeBookmarksBefore(srcRun, newParagraph);
+
if (srcRun instanceof XWPFHyperlinkRun) {
// Hyperlinks meta information is saved in the paragraph and not in the run. So we have to update the paragrapah with a copy of
// the hyperlink to insert.
@@ -493,6 +531,8 @@ private XWPFRun insertRun(XWPFParagraph paragraph, XWPFRun srcRun) {
newRun.getCTR().set(srcRun.getCTR());
}
+ bookmarkManager.copyNativeBookmarksAfter(srcRun, newParagraph);
+
return newRun;
}
@@ -515,7 +555,11 @@ private XWPFRun insertFieldRunReplacement(XWPFParagraph paragraph, XWPFRun srcRu
newParagraph = paragraph;
}
- return insertString(newParagraph, srcRun, replacement);
+ bookmarkManager.copyNativeBookmarksBefore(srcRun, newParagraph);
+ final XWPFRun res = insertString(newParagraph, srcRun, replacement);
+ bookmarkManager.copyNativeBookmarksAfter(srcRun, newParagraph);
+
+ return res;
}
/**
@@ -603,6 +647,11 @@ private XWPFParagraph createNewParagraph(IBody body, XWPFParagraph srcParagraph)
ctp.getRList().clear();
ctp.getFldSimpleList().clear();
ctp.getHyperlinkList().clear();
+ // Bookmark start/end elements are paragraph-level siblings of runs.
+ // Keeping them while rebuilding the runs places both boundaries before
+ // the generated text and turns the bookmark into an empty range.
+ ctp.getBookmarkStartList().clear();
+ ctp.getBookmarkEndList().clear();
res.getCTP().set(ctp);
int runNb = res.getRuns().size();
for (int i = 0; i < runNb; i++) {
@@ -612,6 +661,10 @@ private XWPFParagraph createNewParagraph(IBody body, XWPFParagraph srcParagraph)
currentGeneratedParagraph = res;
forceNewParagraph = false;
+ // Empty paragraphs have no run on which the normal before/after
+ // bookmark reconstruction can be triggered.
+ bookmarkManager.copyNativeBookmarksFromEmptyParagraph(srcParagraph, res);
+
return res;
}
@@ -704,6 +757,14 @@ private XWPFParagraph insertObject(XWPFParagraph paragraph, Object object, XWPFR
res = insertMHyperLink(paragraph, run, (MHyperLink) object);
} else if (object instanceof MBookmark) {
res = insertMBookmark(paragraph, run, (MBookmark) object);
+ } else if (object instanceof MBookmarkPageRef) {
+ res = insertMBookmarkPageRef(paragraph, run, (MBookmarkPageRef) object);
+ } else if (object instanceof MBookmarkSectionRef) {
+ res = insertMBookmarkSectionRef(paragraph, run, (MBookmarkSectionRef) object);
+ } else if (object instanceof MBookmarkTextRef) {
+ res = insertMBookmarkTextRef(paragraph, run, (MBookmarkTextRef) object);
+ } else if (object instanceof MBookmarkCustomTextRef) {
+ res = insertMBookmarkCustomTextRef(paragraph, run, (MBookmarkCustomTextRef) object);
} else if (object instanceof MImage) {
if (object != MImage.EMPTY) {
final XWPFRun imageRun = insertFieldRunReplacement(paragraph, run, "");
@@ -860,13 +921,87 @@ public XWPFParagraph caseComment(Comment comment) {
private XWPFParagraph insertMBookmark(XWPFParagraph paragraph, XWPFRun run, MBookmark bookmark) {
final XWPFParagraph res = (XWPFParagraph) insertFieldRunReplacement(paragraph, run, "").getParent();
- if (bookmark.isReference()) {
- bookmarkManager.insertReference(res, bookmark.getId(), bookmark.getText(), bookmark.isOptional());
- } else {
- bookmarkManager.startBookmark(result, res, bookmark.getId());
- insertFieldRunReplacement(res, run, bookmark.getText());
- bookmarkManager.endBookmark(result, res, bookmark.getId());
- }
+ bookmarkManager.startBookmark(result, res, bookmark.getId());
+ insertFieldRunReplacement(res, run, bookmark.getText());
+ bookmarkManager.endBookmark(result, res, bookmark.getId());
+
+ return res;
+ }
+
+ /**
+ * Inserts a {@link MBookmarkPageRef} in the given {@link XWPFRun}.
+ *
+ * @param paragraph
+ * the {@link XWPFParagraph} to modify
+ * @param run
+ * the {@link XWPFRun}
+ * @param reference
+ * the {@link MBookmarkPageRef}
+ * @return the {@link XWPFParagraph} where the bookmark page reference was inserted
+ */
+ private XWPFParagraph insertMBookmarkPageRef(XWPFParagraph paragraph, XWPFRun run, MBookmarkPageRef reference) {
+ final XWPFParagraph res = (XWPFParagraph) insertFieldRunReplacement(paragraph, run, "").getParent();
+
+ bookmarkManager.insertPageReference(res, reference.getId(), reference.isOptional());
+
+ return res;
+ }
+
+ /**
+ * Inserts a {@link MBookmarkSectionRef} in the given {@link XWPFRun}.
+ *
+ * @param paragraph
+ * the {@link XWPFParagraph} to modify
+ * @param run
+ * the {@link XWPFRun}
+ * @param reference
+ * the {@link MBookmarkSectionRef}
+ * @return the {@link XWPFParagraph} where the bookmark section reference was inserted
+ */
+ private XWPFParagraph insertMBookmarkSectionRef(XWPFParagraph paragraph, XWPFRun run,
+ MBookmarkSectionRef reference) {
+ final XWPFParagraph res = (XWPFParagraph) insertFieldRunReplacement(paragraph, run, "").getParent();
+
+ bookmarkManager.insertSectionReference(res, reference.getId(), reference.isOptional());
+
+ return res;
+ }
+
+ /**
+ * Inserts a {@link MBookmarkTextRef} in the given {@link XWPFRun}.
+ *
+ * @param paragraph
+ * the {@link XWPFParagraph} to modify
+ * @param run
+ * the {@link XWPFRun}
+ * @param reference
+ * the {@link MBookmarkTextRef}
+ * @return the {@link XWPFParagraph} where the bookmark section reference was inserted
+ */
+ private XWPFParagraph insertMBookmarkTextRef(XWPFParagraph paragraph, XWPFRun run, MBookmarkTextRef reference) {
+ final XWPFParagraph res = (XWPFParagraph) insertFieldRunReplacement(paragraph, run, "").getParent();
+
+ bookmarkManager.insertTextReference(res, reference.getId(), reference.isOptional());
+
+ return res;
+ }
+
+ /**
+ * Inserts a {@link MBookmarkCustomTextRef} in the given {@link XWPFRun}.
+ *
+ * @param paragraph
+ * the {@link XWPFParagraph} to modify
+ * @param run
+ * the {@link XWPFRun}
+ * @param reference
+ * the {@link MBookmarkCustomTextRef}
+ * @return the {@link XWPFParagraph} where the bookmark section reference was inserted
+ */
+ private XWPFParagraph insertMBookmarkCustomTextRef(XWPFParagraph paragraph, XWPFRun run,
+ MBookmarkCustomTextRef reference) {
+ final XWPFParagraph res = (XWPFParagraph) insertFieldRunReplacement(paragraph, run, "").getParent();
+
+ bookmarkManager.insertCustomTextReference(res, reference.getId(), reference.getText(), reference.isOptional());
return res;
}
@@ -983,7 +1118,7 @@ private int getAbsoluteImageWidth(XWPFParagraph paragraph, MImage image) {
final CTSectPr section = paragraph.getCTP().getPPr().getSectPr();
res = getAbsoluteWidthFromSection(image, section);
} else {
- // no section attached to the paragraph try the containing body
+ // no section attached to the paragraph try the containing boby
final IBody body = paragraph.getBody();
if (body instanceof XWPFDocument) {
final CTSectPr section = ((XWPFDocument) body).getDocument().getBody().getSectPr();
@@ -993,20 +1128,8 @@ private int getAbsoluteImageWidth(XWPFParagraph paragraph, MImage image) {
.getSectPr();
res = getAbsoluteWidthFromSection(image, section);
} else if (body instanceof XWPFTableCell) {
- final XWPFTableCell cell = (XWPFTableCell) body;
- final int cellWidth;
- // avoid an NPE from POI
- if (cell.getCTTc() != null && cell.getCTTc().getTcPr() != null
- && cell.getCTTc().getTcPr().getTcW() != null && cell.getCTTc().getTcPr().getTcW().getW() != null) {
- cellWidth = cell.getWidth();
- } else {
- cellWidth = 0;
- }
- if (cellWidth > 0) {
- res = (int) (cellWidth * image.getRelativeWidth() / 100.0d / UNIT_CONVERSION);
- } else {
- res = image.getWidth();
- }
+ final int cellWidth = ((XWPFTableCell) body).getWidth();
+ res = (int) (cellWidth * image.getRelativeWidth() / 100.0d / UNIT_CONVERSION);
} else {
throw new UnsupportedOperationException("unknown type of IBody : " + body.getClass());
}
@@ -1060,7 +1183,7 @@ private int getAbsoluteImageHeight(XWPFParagraph paragraph, MImage image) {
final CTSectPr section = paragraph.getCTP().getPPr().getSectPr();
res = getAbsoluteHeightFromSection(image, section);
} else {
- // no section attached to the paragraph try the containing body
+ // no section attached to the paragraph try the containing boby
final IBody body = paragraph.getBody();
if (body instanceof XWPFDocument) {
final CTSectPr section = ((XWPFDocument) body).getDocument().getBody().getSectPr();
@@ -1070,12 +1193,8 @@ private int getAbsoluteImageHeight(XWPFParagraph paragraph, MImage image) {
.getSectPr();
res = getAbsoluteHeightFromSection(image, section);
} else if (body instanceof XWPFTableCell) {
- final int rowHeight = ((XWPFTableCell) body).getTableRow().getHeight();
- if (rowHeight > 0) {
- res = (int) (rowHeight * image.getRelativeHeight() / 100.0d / UNIT_CONVERSION);
- } else {
- res = image.getHeight();
- }
+ // TODO technically the cell height depend on its content
+ res = image.getHeight();
} else {
throw new UnsupportedOperationException("unknown type of IBody : " + body.getClass());
}
@@ -2361,14 +2480,24 @@ public XWPFParagraph caseRow(Row row) {
currentGeneratedRow = new XWPFTableRow(currentGeneratedTable.getCTTbl().addNewTr(), currentGeneratedTable);
final CTRow ctRow = (CTRow) row.getTableRow().getCtRow().copy();
ctRow.getTcList().clear();
+ ctRow.getBookmarkStartList().clear();
+ ctRow.getBookmarkEndList().clear();
while (!currentGeneratedRow.getTableCells().isEmpty()) {
currentGeneratedRow.removeCell(0);
}
currentGeneratedRow.getCtRow().set(ctRow);
- // iterate on cells.
+ bookmarkManager.copyNativeBookmarksBeforeRow(row.getTableRow().getCtRow(),
+ currentGeneratedRow.getCtRow());
+ // Iterate on cells and preserve row-level markup at its exact
+ // position between the corresponding w:tc elements.
+ int cellIndex = 0;
for (Cell cell : row.getCells()) {
doSwitch(cell);
+ bookmarkManager.copyNativeBookmarksSpanningRow(row.getTableRow(), currentGeneratedRow);
+ bookmarkManager.copyNativeBookmarksAfterCell(row.getTableRow().getCtRow(),
+ currentGeneratedRow.getCtRow(), cellIndex);
+ cellIndex++;
}
} finally {
currentGeneratedRow = savedRow;
@@ -2544,7 +2673,7 @@ public XWPFParagraph caseLink(Link link) {
currentParagraph = insertQueryEvaluationMessages(currentParagraph, link,
textResult.getDiagnostic());
} else {
- bookmarkManager.insertReference(currentParagraph, nameResult.getResult().toString(),
+ bookmarkManager.insertCustomTextReference(currentParagraph, nameResult.getResult().toString(),
textResult.getResult().toString(), false);
}
}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/generator/RawCopier.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/generator/RawCopier.java
index 8b4d4da56..230bd3a3b 100644
--- a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/generator/RawCopier.java
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/generator/RawCopier.java
@@ -985,24 +985,30 @@ private void updateBookmarks(BookmarkManager bookmarkManager, final XWPFTable ou
final XWPFTable inputTable) {
final List inputRows = inputTable.getRows();
final List outputRows = outputTable.getRows();
- if (inputRows.size() == outputRows.size()) {
- for (int rowIndex = 0; rowIndex < inputRows.size(); rowIndex++) {
- final XWPFTableRow inputRow = inputRows.get(rowIndex);
- final XWPFTableRow outputRow = outputRows.get(rowIndex);
- final List inputCells = inputRow.getTableCells();
- final List outputCells = outputRow.getTableCells();
- for (int cellIndex = 0; cellIndex < inputCells.size(); cellIndex++) {
- final XWPFTableCell inputCell = inputCells.get(cellIndex);
- final XWPFTableCell outputCell = outputCells.get(cellIndex);
- final List inputBodyElements = inputCell.getBodyElements();
- final List outputBodyElements = outputCell.getBodyElements();
- for (int bodyElementIndex = 0; bodyElementIndex < inputBodyElements.size(); bodyElementIndex++) {
- final IBodyElement inputBodyElement = inputBodyElements.get(bodyElementIndex);
- if (inputBodyElement instanceof XWPFParagraph) {
- final IBodyElement outputBodyElement = outputBodyElements.get(bodyElementIndex);
- updateBookmarks(bookmarkManager, ((XWPFParagraph) outputBodyElement).getCTP(),
- ((XWPFParagraph) inputBodyElement).getCTP(), outputTable.getBody());
- }
+ final int rowCount = Math.min(inputRows.size(), outputRows.size());
+ for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
+ final XWPFTableRow inputRow = inputRows.get(rowIndex);
+ final XWPFTableRow outputRow = outputRows.get(rowIndex);
+ final List inputCells = inputRow.getTableCells();
+ final List outputCells = outputRow.getTableCells();
+ final int cellCount = Math.min(inputCells.size(), outputCells.size());
+ for (int cellIndex = 0; cellIndex < cellCount; cellIndex++) {
+ final XWPFTableCell inputCell = inputCells.get(cellIndex);
+ final XWPFTableCell outputCell = outputCells.get(cellIndex);
+ final List inputBodyElements = inputCell.getBodyElements();
+ final List outputBodyElements = outputCell.getBodyElements();
+ final int bodyElementCount = Math.min(inputBodyElements.size(), outputBodyElements.size());
+ for (int bodyElementIndex = 0; bodyElementIndex < bodyElementCount; bodyElementIndex++) {
+ final IBodyElement inputBodyElement = inputBodyElements.get(bodyElementIndex);
+ final IBodyElement outputBodyElement = outputBodyElements.get(bodyElementIndex);
+ if (inputBodyElement instanceof XWPFParagraph
+ && outputBodyElement instanceof XWPFParagraph) {
+ updateBookmarks(bookmarkManager, ((XWPFParagraph) outputBodyElement).getCTP(),
+ ((XWPFParagraph) inputBodyElement).getCTP(), outputCell);
+ } else if (inputBodyElement instanceof XWPFTable
+ && outputBodyElement instanceof XWPFTable) {
+ updateBookmarks(bookmarkManager, (XWPFTable) outputBodyElement,
+ (XWPFTable) inputBodyElement);
}
}
}
@@ -1025,18 +1031,21 @@ private void updateBookmarks(BookmarkManager bookmarkManager, CTP outputParagrap
IBody outputBody) {
final List oldBookmarks = inputParagraph.getBookmarkStartList();
final List newBookmarks = outputParagraph.getBookmarkStartList();
- for (int bookmarkIndex = 0; bookmarkIndex < oldBookmarks.size(); bookmarkIndex++) {
+ final int bookmarkCount = Math.min(oldBookmarks.size(), newBookmarks.size());
+ for (int bookmarkIndex = 0; bookmarkIndex < bookmarkCount; bookmarkIndex++) {
bookmarkManager.updateXmlObject(newBookmarks.get(bookmarkIndex), oldBookmarks.get(bookmarkIndex),
outputBody);
}
- List inputRuns = inputParagraph.getRList();
+ final List inputRuns = inputParagraph.getRList();
final List outputRuns = outputParagraph.getRList();
- for (int runIndex = 0; runIndex < inputRuns.size(); runIndex++) {
+ final int runCount = Math.min(inputRuns.size(), outputRuns.size());
+ for (int runIndex = 0; runIndex < runCount; runIndex++) {
final CTR inputRun = inputRuns.get(runIndex);
final CTR outputRun = outputRuns.get(runIndex);
final List inputTexts = inputRun.getInstrTextList();
final List outputTexts = outputRun.getInstrTextList();
- for (int textIndex = 0; textIndex < inputTexts.size(); textIndex++) {
+ final int textCount = Math.min(inputTexts.size(), outputTexts.size());
+ for (int textIndex = 0; textIndex < textCount; textIndex++) {
bookmarkManager.updateXmlObject(outputTexts.get(textIndex), inputTexts.get(textIndex), outputBody);
}
}
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/parser/AbstractBodyParser.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/parser/AbstractBodyParser.java
index e1cf00b11..838c16797 100644
--- a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/parser/AbstractBodyParser.java
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/parser/AbstractBodyParser.java
@@ -38,6 +38,7 @@
import org.obeonetwork.m2doc.template.TemplatePackage;
import org.obeonetwork.m2doc.util.AQL56Compatibility;
import org.obeonetwork.m2doc.util.M2DocUtils;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock;
import static org.obeonetwork.m2doc.util.M2DocUtils.message;
@@ -270,7 +271,18 @@ protected Table parseTable(XWPFTable wtable) throws DocumentParserException {
for (XWPFTableRow tablerow : wtable.getRows()) {
Row row = (Row) EcoreUtil.create(TemplatePackage.Literals.ROW);
table.getRows().add(row);
- row.setTableRow(tablerow);
+
+ /*
+ * Keep a detached snapshot of the complete source row before any
+ * cell is parsed. Parsing a cell uses a TokenIteratorFieldRewriter
+ * that can modify the underlying OOXML. If the live table row is
+ * stored in the AST, paragraph- and row-level bookmark markers can
+ * be lost before generation, in particular Word's _Ref bookmarks
+ * that start inside a cell and end directly under w:tr.
+ */
+ final CTRow sourceRow = (CTRow) tablerow.getCtRow().copy();
+ row.setTableRow(new XWPFTableRow(sourceRow, wtable));
+
for (XWPFTableCell tableCell : tablerow.getTableCells()) {
Cell cell = (Cell) EcoreUtil.create(TemplatePackage.Literals.CELL);
row.getCells().add(cell);
diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/services/LinkServices.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/services/LinkServices.java
index a09616b54..7ec955d19 100644
--- a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/services/LinkServices.java
+++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/services/LinkServices.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016, 2024 Obeo.
+ * Copyright (c) 2016, 2025 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
@@ -16,8 +16,16 @@
import org.eclipse.acceleo.annotations.api.documentation.Param;
import org.eclipse.acceleo.annotations.api.documentation.ServiceProvider;
import org.obeonetwork.m2doc.element.MBookmark;
+import org.obeonetwork.m2doc.element.MBookmarkCustomTextRef;
+import org.obeonetwork.m2doc.element.MBookmarkPageRef;
+import org.obeonetwork.m2doc.element.MBookmarkSectionRef;
+import org.obeonetwork.m2doc.element.MBookmarkTextRef;
import org.obeonetwork.m2doc.element.MHyperLink;
+import org.obeonetwork.m2doc.element.impl.MBookmarkCustomTextRefImpl;
import org.obeonetwork.m2doc.element.impl.MBookmarkImpl;
+import org.obeonetwork.m2doc.element.impl.MBookmarkPageRefImpl;
+import org.obeonetwork.m2doc.element.impl.MBookmarkSectionRefImpl;
+import org.obeonetwork.m2doc.element.impl.MBookmarkTextRefImpl;
import org.obeonetwork.m2doc.element.impl.MHyperLinkImpl;
//@formatter:off
@@ -90,7 +98,7 @@ public MHyperLink asLink(String text, String url, String toolTip) {
)
// @formatter:on
public MBookmark asBookmark(String text, String id) {
- return new MBookmarkImpl(text, id, false);
+ return new MBookmarkImpl(text, id);
}
// @formatter:off
@@ -106,7 +114,7 @@ public MBookmark asBookmark(String text, String id) {
}
)
// @formatter:on
- public MBookmark asBookmarkRef(String text, String id) {
+ public MBookmarkCustomTextRef asBookmarkRef(String text, String id) {
return asBookmarkRef(text, id, false);
}
@@ -124,12 +132,107 @@ public MBookmark asBookmarkRef(String text, String id) {
}
)
// @formatter:on
- public MBookmark asBookmarkRef(String text, String id, boolean optional) {
- final MBookmarkImpl res = new MBookmarkImpl(text, id, true);
+ public MBookmarkCustomTextRef asBookmarkRef(String text, String id, boolean optional) {
+ return new MBookmarkCustomTextRefImpl(text, id, optional);
+ }
+
+ // @formatter:off
+ @Documentation(
+ value = "Inserts a page number bookmark reference",
+ params = {
+ @Param(name = "id", value = "The ID of the bookmark reference"),
+ },
+ result = "A bookmark reference with the page numder.",
+ examples = {
+ @Example(expression = "'Art1'.asBookmarkPageRef()", result = "a bookmark reference with the ID 'Art1' with the page number"),
+ }
+ )
+ // @formatter:on
+ public MBookmarkPageRef asBookmarkPageRef(String id) {
+ return asBookmarkPageRef(id, false);
+ }
+
+ // @formatter:off
+ @Documentation(
+ value = "Inserts a page number bookmark reference",
+ params = {
+ @Param(name = "id", value = "The ID of the bookmark reference"),
+ @Param(name = "optional", value = "If true, the reference is omitted if the corresponding bookmark doesn't exists"),
+ },
+ result = "A bookmark reference with the page numder.",
+ examples = {
+ @Example(expression = "'Art1'.asBookmarkPageRef(true)", result = "a bookmark reference with the ID 'Art1' with the page number only if a bookmark with ID 'Art1' exists"),
+ }
+ )
+ // @formatter:on
+ public MBookmarkPageRef asBookmarkPageRef(String id, boolean optional) {
+ return new MBookmarkPageRefImpl(id, optional);
+ }
+
+ // @formatter:off
+ @Documentation(
+ value = "Inserts a section bookmark reference",
+ params = {
+ @Param(name = "id", value = "The ID of the bookmark reference"),
+ },
+ result = "A bookmark reference with the section.",
+ examples = {
+ @Example(expression = "'Art1'.asBookmarkSectionRef(true)", result = "a bookmark reference with the ID 'Art1' with the section number"),
+ }
+ )
+ // @formatter:on
+ public MBookmarkSectionRef asBookmarkSectionRef(String id) {
+ return asBookmarkSectionRef(id, false);
+ }
+
+ // @formatter:off
+ @Documentation(
+ value = "Inserts a section bookmark reference",
+ params = {
+ @Param(name = "id", value = "The ID of the bookmark reference"),
+ @Param(name = "optional", value = "If true, the reference is omitted if the corresponding bookmark doesn't exists"),
+ },
+ result = "A bookmark reference with the section.",
+ examples = {
+ @Example(expression = "'Art1'.asBookmarkPageRef(true)", result = "a bookmark reference with the ID 'Art1' with the section number"),
+ }
+ )
+ // @formatter:on
+ public MBookmarkSectionRef asBookmarkSectionRef(String id, boolean optional) {
+ return new MBookmarkSectionRefImpl(id, optional);
+ }
- res.setOptional(optional);
+ // @formatter:off
+ @Documentation(
+ value = "Inserts a text bookmark reference",
+ params = {
+ @Param(name = "id", value = "The ID of the bookmark reference"),
+ },
+ result = "A bookmark reference with the bookmark text.",
+ examples = {
+ @Example(expression = "'Art1'.asBookmarkPageRef()", result = "a bookmark reference with the ID 'Art1' with the bookmark text"),
+ }
+ )
+ // @formatter:on
+ public MBookmarkTextRef asBookmarkTextRef(String id) {
+ return asBookmarkTextRef(id, false);
+ }
- return res;
+ // @formatter:off
+ @Documentation(
+ value = "Inserts a text bookmark reference",
+ params = {
+ @Param(name = "id", value = "The ID of the bookmark reference"),
+ @Param(name = "optional", value = "If true, the reference is omitted if the corresponding bookmark doesn't exists"),
+ },
+ result = "A bookmark reference with the bookmark text.",
+ examples = {
+ @Example(expression = "'Art1'.asBookmarkPageRef(true)", result = "a bookmark reference with the ID 'Art1' with the bookmark text only if a bookmark with ID 'Art1' exists"),
+ }
+ )
+ // @formatter:on
+ public MBookmarkTextRef asBookmarkTextRef(String id, boolean optional) {
+ return new MBookmarkTextRefImpl(id, optional);
}
}