From 48d16686f399b17133178cc4de6bdf689e95243c Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Sun, 10 May 2026 19:39:18 +0300 Subject: [PATCH 1/4] [experimental] Fix JavaDoc @return builder --- .../message_markup/element/MarkupElement.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java index adb3b479f1..1d56e30271 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java @@ -96,7 +96,7 @@ private Builder() { * * @param start start index * @param end end index - * @return builder TODO javadoc me please + * @return builder to be used for chaining. */ public Builder setDeleted(int start, int end) { return addSpan(start, end, Collections.singleton(SpanElement.SpanStyle.deleted)); @@ -107,7 +107,7 @@ public Builder setDeleted(int start, int end) { * * @param start start index * @param end end index - * @return builder TODO javadoc me please + * @return builder to be used for chaining. */ public Builder setEmphasis(int start, int end) { return addSpan(start, end, Collections.singleton(SpanElement.SpanStyle.emphasis)); @@ -118,7 +118,7 @@ public Builder setEmphasis(int start, int end) { * * @param start start index * @param end end index - * @return builder TODO javadoc me please + * @return builder to be used for chaining. */ public Builder setCode(int start, int end) { return addSpan(start, end, Collections.singleton(SpanElement.SpanStyle.code)); @@ -130,7 +130,7 @@ public Builder setCode(int start, int end) { * @param start start index * @param end end index * @param styles list of text styles for that span - * @return builder TODO javadoc me please + * @return builder to be used for chaining. */ public Builder addSpan(int start, int end, Set styles) { verifyStartEnd(start, end); @@ -151,7 +151,7 @@ public Builder addSpan(int start, int end, Set styles) { * * @param start start index * @param end end index - * @return builder TODO javadoc me please + * @return builder to be used for chaining. */ public Builder setBlockQuote(int start, int end) { verifyStartEnd(start, end); @@ -178,7 +178,7 @@ public Builder setBlockQuote(int start, int end) { * * @param start start index * @param end end index - * @return builder TODO javadoc me please + * @return builder to be used for chaining. */ public Builder setCodeBlock(int start, int end) { verifyStartEnd(start, end); @@ -231,7 +231,7 @@ public Builder.ListBuilder addEntry(int start, int end) { /** * End the list. * - * @return builder TODO javadoc me please + * @return builder to be used for chaining. */ public Builder endList() { if (entries.size() > 0) { From 72c5f8634081a5ba131587ddcac97d4a1dbae830 Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Sun, 10 May 2026 19:40:13 +0300 Subject: [PATCH 2/4] [experimental] XEP-0394: Add support for emphasis span style --- .../message_markup/element/MarkupElement.java | 11 +++++++++ .../message_markup/element/SpanElement.java | 2 ++ .../message_markup/element/package-info.java | 7 +++--- .../provider/MarkupElementProvider.java | 4 ++++ .../message_markup/MessageMarkupTest.java | 24 +++++++++++++++++++ 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java index 1d56e30271..09cd4b42be 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java @@ -113,6 +113,17 @@ public Builder setEmphasis(int start, int end) { return addSpan(start, end, Collections.singleton(SpanElement.SpanStyle.emphasis)); } + /** + * Mark a section of a message as strongly emphasized (bold font). + * + * @param start start index + * @param end end index + * @return builder to be used for chaining. + */ + public Builder setStrong(int start, int end) { + return addSpan(start, end, Collections.singleton(SpanElement.SpanStyle.strong)); + } + /** * Mark a section of a message as inline code. * diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/SpanElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/SpanElement.java index b6ea185b1b..9fd748270a 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/SpanElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/SpanElement.java @@ -52,11 +52,13 @@ public Set getStyles() { } public static final String emphasis = "emphasis"; + public static final String strong = "strong"; public static final String code = "code"; public static final String deleted = "deleted"; public enum SpanStyle { emphasis, + strong, code, deleted } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/package-info.java index 49dedfd3b8..cf3b051acf 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/package-info.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/package-info.java @@ -36,13 +36,14 @@ *

* Currently there are 3 styles available: *

    - *
  • *emphasis*, which should be rendered by a client as *italic*, or **bold**
  • + *
  • *emphasis*, which should be rendered by a client as *italic*
  • + *
  • *strong*, which should be rendered by a client as **bold**
  • *
  • *code*, which should be rendered in `monospace`
  • *
  • *deleted*, which should be rendered as ~~strikethrough~~.
  • *
*

- * Those styles are available by calling `builder.setEmphasis(int start, int end)`, `builder.setDeleted(int start, int - * end)` and `builder.setCode(int start, int end)`. + * Those styles are available by calling `builder.setEmphasis(int start, int end)`, `builder.setStrong(int start, int + * end)`, `builder.setDeleted(int start, int end)` and `builder.setCode(int start, int end)`. *

*

* If you want to apply multiple inline styles to a section, you can do the following: diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java index 1f56b16762..052708db6f 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java @@ -90,6 +90,10 @@ public MarkupElement parse(XmlPullParser parser, int initialDepth, XmlEnvironmen spanStyles.add(SpanElement.SpanStyle.emphasis); break; + case SpanElement.strong: + spanStyles.add(SpanElement.SpanStyle.strong); + break; + case SpanElement.deleted: spanStyles.add(SpanElement.SpanStyle.deleted); break; diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/message_markup/MessageMarkupTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/message_markup/MessageMarkupTest.java index d5fd770a5a..1cbebf4636 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/message_markup/MessageMarkupTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/message_markup/MessageMarkupTest.java @@ -61,6 +61,30 @@ public void emphasisTest() throws Exception { assertEquals(SpanElement.SpanStyle.emphasis, spanElement.getStyles().iterator().next()); } + @Test + public void strongTest() throws Exception { + String xml = + "" + + "" + + "" + + "" + + ""; + MarkupElement.Builder m = MarkupElement.getBuilder(); + m.setStrong(9, 15); + assertXmlSimilar(xml, m.build().toXML().toString()); + + XmlPullParser parser = TestUtils.getParser(xml); + MarkupElement parsed = new MarkupElementProvider().parse(parser); + List children = parsed.getChildElements(); + assertEquals(1, children.size()); + + SpanElement spanElement = (SpanElement) children.get(0); + assertEquals(9, spanElement.getStart()); + assertEquals(15, spanElement.getEnd()); + assertEquals(1, spanElement.getStyles().size()); + assertEquals(SpanElement.SpanStyle.strong, spanElement.getStyles().iterator().next()); + } + @Test public void codeTest() throws Exception { String xml = From 21e39c65b98361b8da24f18493919dc99c6bdf37 Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Sun, 10 May 2026 20:01:21 +0300 Subject: [PATCH 3/4] [experimental] XEP-0394: Add support for "language" attribute --- .../element/CodeBlockElement.java | 17 ++++++++++++++++- .../message_markup/element/MarkupElement.java | 7 ++++--- .../provider/MarkupElementProvider.java | 3 ++- .../message_markup/MessageMarkupTest.java | 5 +++-- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/CodeBlockElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/CodeBlockElement.java index 9fb828abad..599c5d3744 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/CodeBlockElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/CodeBlockElement.java @@ -18,19 +18,29 @@ import javax.xml.namespace.QName; +import org.jivesoftware.smack.util.XmlStringBuilder; + public class CodeBlockElement extends MarkupElement.BlockLevelMarkupElement { public static final String ELEMENT = "bcode"; public static final QName QNAME = new QName(NAMESPACE, ELEMENT); + private final String codeLanguage; + /** * Create a new Code Block element. * * @param start start index * @param end end index + * @param codeLanguage programming language of the code block (e.g. "java") */ - public CodeBlockElement(int start, int end) { + public CodeBlockElement(int start, int end, String codeLanguage) { super(start, end); + this.codeLanguage = codeLanguage; + } + + public String getCodeLanguage() { + return codeLanguage; } @Override @@ -38,4 +48,9 @@ public String getElementName() { return ELEMENT; } + @Override + protected void afterXmlPrelude(XmlStringBuilder xml) { + xml.attribute("language", codeLanguage); + super.afterXmlPrelude(xml); + } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java index 09cd4b42be..b9e3b0f2d8 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java @@ -189,12 +189,13 @@ public Builder setBlockQuote(int start, int end) { * * @param start start index * @param end end index + * @param codeLanguage programming language of the code block (e.g. "java") * @return builder to be used for chaining. */ - public Builder setCodeBlock(int start, int end) { + public Builder setCodeBlock(int start, int end, String codeLanguage) { verifyStartEnd(start, end); - codes.add(new CodeBlockElement(start, end)); + codes.add(new CodeBlockElement(start, end, codeLanguage)); return this; } @@ -359,7 +360,7 @@ protected BlockLevelMarkupElement(int start, int end) { } @Override - protected final void afterXmlPrelude(XmlStringBuilder xml) { + protected void afterXmlPrelude(XmlStringBuilder xml) { xml.closeEmptyElement(); } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java index 052708db6f..10e42a41c5 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java @@ -71,7 +71,8 @@ public MarkupElement parse(XmlPullParser parser, int initialDepth, XmlEnvironmen "Message Markup CodeBlockElement MUST contain a 'start' attribute."); end = ParserUtils.getIntegerAttributeOrThrow(parser, MarkupChildElement.ATTR_END, "Message Markup CodeBlockElement MUST contain a 'end' attribute."); - markup.setCodeBlock(start, end); + String codeLanguage = parser.getAttributeValue("", "language"); + markup.setCodeBlock(start, end, codeLanguage); break; case SpanElement.ELEMENT: diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/message_markup/MessageMarkupTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/message_markup/MessageMarkupTest.java index 1cbebf4636..cbf1607a5f 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/message_markup/MessageMarkupTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/message_markup/MessageMarkupTest.java @@ -151,10 +151,10 @@ public void overlappingSpansTest() { public void codeBlockTest() throws Exception { String xml = "" + - "" + + "" + ""; MarkupElement.Builder m = MarkupElement.getBuilder(); - m.setCodeBlock(23, 48); + m.setCodeBlock(23, 48, "bash"); assertXmlSimilar(xml, m.build().toXML().toString()); XmlPullParser parser = TestUtils.getParser(xml); @@ -165,6 +165,7 @@ public void codeBlockTest() throws Exception { CodeBlockElement codeBlock = (CodeBlockElement) children.get(0); assertEquals(23, codeBlock.getStart()); assertEquals(48, codeBlock.getEnd()); + assertEquals("bash", codeBlock.getCodeLanguage()); } @Test From e215af4a4d0113acc341c7ba185dc0c948cb3b0c Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Sun, 10 May 2026 20:15:17 +0300 Subject: [PATCH 4/4] [experimental] XEP-0394: Add support for "ordered" attribute --- .../message_markup/element/ListElement.java | 15 ++++++++++++++- .../message_markup/element/MarkupElement.java | 10 ++++++++-- .../provider/MarkupElementProvider.java | 5 ++++- .../smackx/message_markup/MessageMarkupTest.java | 5 ++++- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/ListElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/ListElement.java index 85cc1eba6d..11fa2f8af4 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/ListElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/ListElement.java @@ -30,6 +30,7 @@ public class ListElement extends MarkupElement.NonEmptyChildElement { public static final QName QNAME = new QName(NAMESPACE, ELEMENT); private final List entries; + private final boolean ordered; /** * Create a new List element. @@ -37,10 +38,12 @@ public class ListElement extends MarkupElement.NonEmptyChildElement { * @param start start index of the list * @param end end index of the list * @param entries list entries + * @param ordered the list is ordered and displaying it with numerical or alphabetical ordering instead of bullets */ - public ListElement(int start, int end, List entries) { + public ListElement(int start, int end, List entries, boolean ordered) { super(start, end); this.entries = Collections.unmodifiableList(entries); + this.ordered = ordered; } /** @@ -52,11 +55,21 @@ public List getEntries() { return entries; } + public boolean isOrdered() { + return ordered; + } + @Override public String getElementName() { return QNAME.getLocalPart(); } + @Override + protected void afterXmlPrelude(XmlStringBuilder xml) { + xml.attribute("ordered", isOrdered()); + super.afterXmlPrelude(xml); + } + @Override public void appendInnerXml(XmlStringBuilder xml) { xml.append(getEntries()); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java index b9e3b0f2d8..82bee93c26 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/element/MarkupElement.java @@ -211,6 +211,7 @@ public Builder.ListBuilder beginList() { public static final class ListBuilder { private final Builder markup; private final ArrayList entries = new ArrayList<>(); + private boolean ordered; private int end = -1; private ListBuilder(Builder markup) { @@ -240,6 +241,11 @@ public Builder.ListBuilder addEntry(int start, int end) { return this; } + public Builder.ListBuilder setOrdered(boolean ordered) { + this.ordered = ordered; + return this; + } + /** * End the list. * @@ -248,7 +254,7 @@ public Builder.ListBuilder addEntry(int start, int end) { public Builder endList() { if (entries.size() > 0) { ListElement.ListEntryElement first = entries.get(0); - ListElement list = new ListElement(first.getStart(), end, entries); + ListElement list = new ListElement(first.getStart(), end, entries, ordered); markup.lists.add(list); } @@ -338,7 +344,7 @@ protected NonEmptyChildElement(int start, int end) { } @Override - protected final void afterXmlPrelude(XmlStringBuilder xml) { + protected void afterXmlPrelude(XmlStringBuilder xml) { xml.rightAngleBracket(); appendInnerXml(xml); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java index 10e42a41c5..0187ac7890 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/message_markup/provider/MarkupElementProvider.java @@ -49,6 +49,7 @@ public MarkupElement parse(XmlPullParser parser, int initialDepth, XmlEnvironmen int listStart = -1, listEnd = -1; List lis = new ArrayList<>(); + boolean listOrdered = false; while (true) { XmlPullParser.Event tag = parser.next(); @@ -105,6 +106,7 @@ public MarkupElement parse(XmlPullParser parser, int initialDepth, XmlEnvironmen "Message Markup ListElement MUST contain a 'start' attribute."); listEnd = ParserUtils.getIntegerAttributeOrThrow(parser, MarkupChildElement.ATTR_END, "Message Markup ListElement MUST contain a 'end' attribute."); + listOrdered = ParserUtils.getBooleanAttribute(parser, "ordered", false); break; case ListElement.ListEntryElement.ELEMENT: @@ -128,7 +130,8 @@ public MarkupElement parse(XmlPullParser parser, int initialDepth, XmlEnvironmen break; case ListElement.ELEMENT: - MarkupElement.Builder.ListBuilder listBuilder = markup.beginList(); + MarkupElement.Builder.ListBuilder listBuilder = markup.beginList() + .setOrdered(listOrdered); if (lis.size() > 0 && lis.get(0).getStart() != listStart) { // TODO: Should be SmackParseException. throw new IOException("Error while parsing incoming MessageMarkup ListElement: " + diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/message_markup/MessageMarkupTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/message_markup/MessageMarkupTest.java index cbf1607a5f..f1b8715c36 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/message_markup/MessageMarkupTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/message_markup/MessageMarkupTest.java @@ -19,6 +19,7 @@ import static org.jivesoftware.smack.test.util.XmlAssertUtil.assertXmlSimilar; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; @@ -172,7 +173,7 @@ public void codeBlockTest() throws Exception { public void listTest() throws Exception { String xml = "" + - "" + + "" + "

  • " + "
  • " + "
  • " + @@ -181,6 +182,7 @@ public void listTest() throws Exception { ""; MarkupElement.Builder m = MarkupElement.getBuilder(); m = m.beginList() + .setOrdered(true) .addEntry(31, 47) .addEntry(47, 61) .addEntry(61, 69) @@ -196,6 +198,7 @@ public void listTest() throws Exception { ListElement list = (ListElement) children.get(0); assertEquals(31, list.getStart()); assertEquals(89, list.getEnd()); + assertTrue(list.isOrdered()); assertEquals(4, list.getEntries().size()); assertEquals(list.getStart(), list.getEntries().get(0).getStart()); assertEquals(47, list.getEntries().get(1).getStart());