-
Notifications
You must be signed in to change notification settings - Fork 12
Add support for markdown formatting in descriptions #759
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Yauhenikapl
merged 19 commits into
eclipse-esmf:main
from
bci-oss:723-support-for-markdown-formatting-in-descriptions
May 19, 2025
Merged
Changes from 5 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
6a82268
Add Java API for getting correct markdown parts from descriptions
Yauhenikapl a760c77
Revert "Add Java API for getting correct markdown parts from descript…
Yauhenikapl 9afa8f2
Add Java API for getting correct markdown parts from descriptions
Yauhenikapl f1fbaba
Fix styles
Yauhenikapl a5c84bf
Merge branch 'main' into 723-support-for-markdown-formatting-in-descr…
Yauhenikapl 88e81da
Fix styles
Yauhenikapl 7be368b
Update logic
Yauhenikapl 5d29f2a
Update tests
Yauhenikapl a0de13e
Update project tot new version parent 20
Yauhenikapl 17b1e9e
Add tests and refactoring
Yauhenikapl 1229834
fix tests
Yauhenikapl 08b4bd6
fix styles
Yauhenikapl e7be12e
fix styles
Yauhenikapl 5258e3c
Update tests and add markdown description Model
Yauhenikapl 8d753c6
Update tests and refactoring
Yauhenikapl f5e6174
Fix tests
Yauhenikapl 2d80da9
Fix formatting
atextor b36167b
Fix Databricks SQL generation to work with multiline comments
atextor a7f3a71
Make line break escaping work on Windows
atextor File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
160 changes: 100 additions & 60 deletions
160
...ta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/utils/DescriptionsUtilsTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,95 +1,135 @@ | ||
package org.eclipse.esmf.aspectmodel.utils; | ||
|
||
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
||
import java.util.List; | ||
import java.util.Locale; | ||
|
||
import org.eclipse.esmf.aspectmodel.AspectModelFile; | ||
import org.eclipse.esmf.metamodel.AspectModel; | ||
import org.eclipse.esmf.test.TestAspect; | ||
import org.eclipse.esmf.test.TestResources; | ||
|
||
import org.junit.jupiter.api.BeforeAll; | ||
import org.junit.jupiter.api.Test; | ||
|
||
class DescriptionsUtilsTest { | ||
|
||
private static String testDescription; | ||
|
||
@BeforeAll | ||
public static void init() { | ||
final AspectModel aspectModel = TestResources.load( TestAspect.ASPECT_WITH_MARKDOWN_DESCRIPTION ); | ||
final AspectModelFile originalFile = aspectModel.files().iterator().next(); | ||
testDescription = originalFile.elements().getFirst().getDescription( Locale.ENGLISH ); | ||
} | ||
|
||
@Test | ||
void testExtractNotes_singleNote() { | ||
final String description = "> NOTE: This is a note.\n> Continued on the next line."; | ||
final List<String> notes = DescriptionsUtils.notes( description ); | ||
assertEquals( 1, notes.size() ); | ||
assertEquals( "This is a note.\nContinued on the next line.", notes.get( 0 ) ); | ||
void testExtractNotesSingleNote() { | ||
final List<String> notes = DescriptionsUtils.notes( testDescription ); | ||
assertThat( notes ).hasSize( 1 ); | ||
assertEquals( "This is a note block.\nIt supports multiple lines.\nHere's a second line of the note.", notes.get( 0 ) ); | ||
} | ||
|
||
@Test | ||
void testExtractExamples_multipleExamples() { | ||
final String description = | ||
""" | ||
> EXAMPLE 1: First example. | ||
> More detail. | ||
|
||
> EXAMPLE 2: Second example. | ||
"""; | ||
final List<String> examples = DescriptionsUtils.examples( description ); | ||
void testExtractExamplesMultipleExamples() { | ||
final List<String> examples = DescriptionsUtils.examples( testDescription ); | ||
|
||
assertEquals( 2, examples.size() ); | ||
assertEquals( "First example.\nMore detail.", examples.get( 0 ) ); | ||
assertEquals( "Second example.", examples.get( 1 ) ); | ||
assertEquals( "This is the first example block.\nIt can span several lines, and supports *italic* and **bold** text.", | ||
examples.get( 0 ) ); | ||
assertEquals( "This is the second example.\nAlso multiline, for testing multiple example entries.", examples.get( 1 ) ); | ||
} | ||
|
||
@Test | ||
void testExtractExamplesMultipleExamplesWithBoldAndItalicText() { | ||
final String html = DescriptionsUtils.toHtml( testDescription ); | ||
|
||
assertThat( html ).contains( | ||
"This is the first example block.\nIt can span several lines, and supports <em>italic</em> and <strong>bold</strong> text." ); | ||
} | ||
|
||
@Test | ||
void testExtractSources_withLink() { | ||
final String description = "> SOURCE: Source with [link](https://example.com)"; | ||
final List<String> sources = DescriptionsUtils.sources( description ); | ||
void testExtractSourcesWithLink() { | ||
final List<String> sources = DescriptionsUtils.sources( testDescription ); | ||
assertEquals( 1, sources.size() ); | ||
assertTrue( sources.get( 0 ).contains( "[link](https://example.com)" ) ); | ||
assertThat( sources.get( 0 ) ).contains( "ISO 12345:2023, section 4.2.1\n" + "with an inline [link](https://www.example.com/spec)." ); | ||
} | ||
|
||
@Test | ||
void testMixedBlockTypes() { | ||
final String description = | ||
""" | ||
> NOTE: A note block. | ||
> EXAMPLE: An example block. | ||
|
||
> SOURCE: A source block. | ||
"""; | ||
assertEquals( 1, DescriptionsUtils.notes( description ).size() ); | ||
assertEquals( 1, DescriptionsUtils.examples( description ).size() ); | ||
assertEquals( 1, DescriptionsUtils.sources( description ).size() ); | ||
assertEquals( 1, DescriptionsUtils.notes( testDescription ).size() ); | ||
assertEquals( 2, DescriptionsUtils.examples( testDescription ).size() ); | ||
assertEquals( 1, DescriptionsUtils.sources( testDescription ).size() ); | ||
} | ||
|
||
@Test | ||
void testNoBlocks() { | ||
final String description = "This is a plain description without any special blocks."; | ||
assertTrue( DescriptionsUtils.notes( description ).isEmpty() ); | ||
assertTrue( DescriptionsUtils.examples( description ).isEmpty() ); | ||
assertTrue( DescriptionsUtils.sources( description ).isEmpty() ); | ||
assertThat( DescriptionsUtils.notes( description ) ).isEmpty(); | ||
assertThat( DescriptionsUtils.examples( description ) ).isEmpty(); | ||
assertThat( DescriptionsUtils.sources( description ) ).isEmpty(); | ||
} | ||
|
||
@Test | ||
void testToHtml_withAllBlockTypes() { | ||
final String description = | ||
""" | ||
> NOTE: This is a note. | ||
> With multiple lines. | ||
|
||
> EXAMPLE 1: First example. | ||
> Additional example content. | ||
|
||
> EXAMPLE 2: Second example. | ||
|
||
> SOURCE: Source information here. | ||
|
||
Some **markdown** content here. | ||
1. Ordered | ||
2. List | ||
"""; | ||
|
||
final String html = DescriptionsUtils.toHtml( description ); | ||
|
||
assertTrue( html.contains( "<div class=\"note\">" ) ); | ||
assertTrue( html.contains( "This is a note." ) ); | ||
void testToHtmlWithAllBlockTypes() { | ||
final String description = """ | ||
> NOTE: This is a note. | ||
> With multiple lines. | ||
|
||
> EXAMPLE 1: First example. | ||
> Additional example content. | ||
|
||
> EXAMPLE 2: Second example. | ||
|
||
> SOURCE: Source information here. | ||
|
||
Some **markdown** content here. | ||
1. Ordered | ||
2. List | ||
"""; | ||
|
||
final String html = DescriptionsUtils.toHtml( testDescription ); | ||
|
||
assertThat( html ).contains( "<div class=\"note\">" ); | ||
assertThat( html ).contains( "This is a note block.\nIt supports multiple lines.\nHere's a second line of the note." ); | ||
assertTrue( html.contains( "<ul class=\"example-list\">" ) || html.contains( "<div class=\"example\">" ) ); | ||
assertTrue( html.contains( "First example." ) ); | ||
assertTrue( html.contains( "<div class=\"source\">" ) ); | ||
assertTrue( html.contains( "Source information here." ) ); | ||
assertTrue( html.contains( "<strong>markdown</strong>" ) ); | ||
assertTrue( html.contains( "<ol>" ) ); | ||
assertThat( html ).contains( | ||
"This is the first example block.\nIt can span several lines, and supports <em>italic</em> and <strong>bold</strong> text." ); | ||
assertThat( html ).contains( "<div class=\"source\">" ); | ||
assertThat( html ).contains( "ISO 12345:2023, section 4.2.1\nwith an inline <a href=\"https://www.example.com/spec\">link</a>." ); | ||
assertThat( html ).contains( "<ol>" ); | ||
} | ||
|
||
@Test | ||
void testMarkdownRenderingBulletList() { | ||
String html = DescriptionsUtils.toHtml( testDescription ); | ||
assertThat( html ).contains( "<ul>" ); | ||
assertThat( html ).contains( "<li>Item A</li>" ); | ||
assertThat( html ).contains( "<li>Item B</li>" ); | ||
assertThat( html ).contains( "<li>Item C</li>" ); | ||
} | ||
|
||
@Test | ||
void testMarkdownRenderingOrderedList() { | ||
String html = DescriptionsUtils.toHtml( testDescription ); | ||
assertThat( html ).contains( "<ol>" ); | ||
assertThat( html ).contains( "<li>First</li>" ); | ||
assertThat( html ).contains( "<li>Second</li>" ); | ||
assertThat( html ).contains( "<li>Third</li>" ); | ||
} | ||
|
||
@Test | ||
void testMarkdownRenderingWithLink() { | ||
String html = DescriptionsUtils.toHtml( testDescription ); | ||
assertThat( html ).contains( "<a href=\"https://example.com\">Visit Example</a>" ); | ||
} | ||
|
||
@Test | ||
void testHtmlOutputDoesNotContainMarkdownSyntax() { | ||
String html = DescriptionsUtils.toHtml( testDescription ); | ||
assertThat( html ).doesNotContain( "[Visit Example](https://example.com)" ); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
...ls/src/main/resources/valid/org.eclipse.esmf.test/1.0.0/AspectWithMarkdownDescription.ttl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Copyright (c) 2025 Robert Bosch Manufacturing Solutions GmbH | ||
# | ||
# See the AUTHORS file(s) distributed with this work for additional | ||
# information regarding authorship. | ||
# | ||
# This Source Code Form is subject to the terms of the Mozilla Public | ||
# License, v. 2.0. If a copy of the MPL was not distributed with this | ||
# file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
# | ||
# SPDX-License-Identifier: MPL-2.0 | ||
|
||
@prefix : <urn:samm:org.eclipse.esmf.test:1.0.0#> . | ||
@prefix samm: <urn:samm:org.eclipse.esmf.samm:meta-model:2.2.0#> . | ||
@prefix samm-c: <urn:samm:org.eclipse.esmf.samm:characteristic:2.2.0#> . | ||
|
||
:AspectWithMarkdownDescription a samm:Aspect ; | ||
samm:properties ( :myProperty ) ; | ||
samm:operations ( ) . | ||
|
||
:myProperty a samm:Property ; | ||
samm:description """ | ||
This is a sample concept demonstrating **Markdown** support in samm:description. | ||
|
||
> NOTE: This is a note block. | ||
> It supports multiple lines. | ||
> Here's a second line of the note. | ||
|
||
> EXAMPLE 1: This is the first example block. | ||
> It can span several lines, and supports *italic* and **bold** text. | ||
|
||
> EXAMPLE 2: This is the second example. | ||
> Also multiline, for testing multiple example entries. | ||
|
||
> SOURCE: ISO 12345:2023, section 4.2.1 | ||
> with an inline [link](https://www.example.com/spec). | ||
|
||
Unordered list: | ||
* Item A | ||
* Item B | ||
* Item C | ||
|
||
Ordered list: | ||
1. First | ||
2. Second | ||
3. Third | ||
|
||
You can also include inline links like [Visit Example](https://example.com). | ||
|
||
Another paragraph after a blank line to simulate text flow and paragraph breaks. | ||
"""@en ; | ||
Yauhenikapl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
samm:characteristic samm-c:Text . |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.