diff --git a/build.gradle b/build.gradle index da3fb12..0a11e70 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ targetCompatibility = 17 description = 'Utilities to import diagrams and documentation into a Structurizr workspace' group = 'com.structurizr' -version = '1.6.0' +version = '1.7.0' test { useJUnitPlatform() diff --git a/docs/changelog.md b/docs/changelog.md index 937394e..bac876c 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,5 +1,9 @@ # Changelog +## 1.7.0 (unreleased) + +- Adds support for SVG images (https://github.com/structurizr/import/issues/10) + ## 1.6.0 (26th October 2023) - Fixes https://github.com/structurizr/import/issues/13 (Mermaid diagrams not working). diff --git a/src/main/java/com/structurizr/importer/documentation/DefaultImageImporter.java b/src/main/java/com/structurizr/importer/documentation/DefaultImageImporter.java index 3d8c640..f1cc2a3 100644 --- a/src/main/java/com/structurizr/importer/documentation/DefaultImageImporter.java +++ b/src/main/java/com/structurizr/importer/documentation/DefaultImageImporter.java @@ -7,6 +7,8 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.util.Base64; /** * This implementation scans a given directory and automatically imports all Markdown or AsciiDoc @@ -57,7 +59,7 @@ private void importImages(Documentable documentable, String root, File path) thr importImages(documentable, root + "/" + file.getName(), file); } } else { - if (name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".gif")) { + if (name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".gif") || name.endsWith(".svg")) { importImage(documentable, root, file); } } @@ -67,7 +69,7 @@ private void importImages(Documentable documentable, String root, File path) thr private void importImage(Documentable documentable, String path, File file) throws IOException { String contentType = ImageUtils.getContentType(file); - String base64Content = ImageUtils.getImageAsBase64(file); + String base64Content; String name; if (StringUtils.isNullOrEmpty(path)) { @@ -76,6 +78,13 @@ private void importImage(Documentable documentable, String path, File file) thro name = path + "/" + file.getName(); } + if (ImageUtils.CONTENT_TYPE_IMAGE_SVG.equalsIgnoreCase(contentType)) { + base64Content = Base64.getEncoder().encodeToString(Files.readAllBytes(file.toPath())); + } else { + contentType = ImageUtils.getContentType(file); + base64Content = ImageUtils.getImageAsBase64(file); + } + documentable.getDocumentation().addImage(new Image(name, contentType, base64Content)); } diff --git a/src/test/docs/images/image.svg b/src/test/docs/images/image.svg new file mode 100644 index 0000000..1d52641 --- /dev/null +++ b/src/test/docs/images/image.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/test/java/com/structurizr/importer/documentation/DefaultImageImporterTests.java b/src/test/java/com/structurizr/importer/documentation/DefaultImageImporterTests.java index a1e0267..2a71b83 100644 --- a/src/test/java/com/structurizr/importer/documentation/DefaultImageImporterTests.java +++ b/src/test/java/com/structurizr/importer/documentation/DefaultImageImporterTests.java @@ -109,7 +109,7 @@ public void test_importDocumentation_AddsAllImages_Recursively() { assertTrue(documentation.getImages().isEmpty()); imageImporter.importDocumentation(workspace, new File("./src/test/docs/images")); - assertEquals(8, documentation.getImages().size()); + assertEquals(9, documentation.getImages().size()); Image pngInDirectory = documentation.getImages().stream().filter(i -> i.getName().equals("image.png")).findFirst().get(); assertEquals("image/png", pngInDirectory.getType()); @@ -127,6 +127,10 @@ public void test_importDocumentation_AddsAllImages_Recursively() { assertEquals("image/gif", gifInDirectory.getType()); assertEquals("R0lGODlhIAAaAPcAAAAAAAACCwAFHAAGFAAGIwAIFgAKHAAKJgAMKgAOMwAPPAARHwAUOQ0UHQIVMgMVJQMVLAoVKwwVJBEVHgAYOAQYJwkYORAYJQIZKwoZJQMaMgoaKwobMxQcKQsjRwMnVxcoPBsoOAAtWx8vQAAwXwIzaQ9HehZLhEVMWRRNjB5Ng0VNYUtQWkFRXhZShBVTjRRVkxlVjhtVlBtWmQpXoxFXmxZYmRFZpBhZjxpZlRValRlamAdcrgxcqg1cpCFdmw1esRReqhleqx9eoyhenhNgrAxitBlirxNktCZknw5luxllsyJlrBJmuhhmuCNnsCVnpBRptRRpvBxpryNprhVqwhtrvBxrtSJrtRxtwCVuuyFytCZ0xid0uit0wCV4xi97xDh9xDGAyzuAy0KBy0SCw0iDw0aG0EuGyjuI2EuM1EiN2EOO2EaP1USR26SipZ+kqKSmsqamrGGq76SquG+w9Gy0/Im05nK183m1+Xa2+YS27YW28YS3+Iq38Iu37HO59Iq57HS6/oq683277IS79IW77ZG77YS8+3u9/Iu++Y7A9X7B/4PB8oLC/ozC/PX3///39f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAIAAaAEcI/wAlxUEhYQMGCAghaMDw4KCDCBAwVEgIYYNCDRxWxIGU0AFCDAhOMFnSREkVIEB69PDh48YNlTyMKGly5QSBCw4cYDgI4QECGFaaINkCqFCgQkiNDkKEaNAeRWaCwCDQQE6AAhY1IKTg4AABAgcOCPhKloCAs2QdGAggZ+dChg8yQNyw4cEDCRIiRMhQAYOGvxYrPNhwAAKHnQnjHnhxRQqSK4mQGkpaaJBlp4jOBJFxQILWhoMlIJBxJCgSMHWYIkK6FFEiRoLYBNGSojOLASNAa+XwFrHHiBhy5oQQwe6GEANaIOSQUIMDBSVO5MgBQ8aMGTJkxMg+w4YNGDhckP9g0BMxwsEHYlxBIsWIGDuMVDNVNAhpIjc9rMw4EGFi4gw/GVEFEl7o8cgdhkxGmWSIoCEEDAg8MBxihMEghRJSXCEIInwkZUggRxUyGSJhIAHDARlA4NFgGKQoQhJUXHGFFUgEYeONQQghRBBLWPEEER9AUFUAA1j0gIq/AafiRzwlttMDAgxAR4pHPpkQQ31RtJNwHvWXgXFKfrTABg4gABYCaKYZFpoJJFAmBAQgoFVxCGnlnAMlDIEFe1b02ScWgGJhRRZ9RjEFFCLE1dFHCLywpxRN8MBFGmyw0UYbamS6hhtfCOhECgRIYF5PGSx2RRRR9DCHI5FR5scfgUy/pgcWS8hAgEFNKqZDFFIA0QUehfyRIGWWjUjGZhH6RxwEANYgxYBa5LHHIcOKmBQhjRSCRg0/3GrBik/+FJQRv1ZGGYhMDbJIIWUUYUNnCBwmGHpASSGFqo/04SGIhazmiCB77nDARFrBJQEBIi2BBBI0YBFGGRBHTAYZY2jRwxJMqCBABysIAAKTwYlgwgsvwADDDtmZXF12271wgggeGMBCJG+gcJGdGGyQwc4ZNIAXzxlIMEEDO9OFAhySBAQAOw==", gifInDirectory.getContent()); + Image svgInDirectory = documentation.getImages().stream().filter(i -> i.getName().equals("image.svg")).findFirst().get(); + assertEquals("image/svg+xml", svgInDirectory.getType()); + assertEquals("PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4KICA8Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIzIiBmaWxsPSJyZWQiIC8+Cjwvc3ZnPiA=", svgInDirectory.getContent()); + Image pngInSubDirectory = documentation.getImages().stream().filter(i -> i.getName().equals("images/image.png")).findFirst().get(); assertEquals("image/png", pngInSubDirectory.getType()); assertTrue(pngInSubDirectory.getContent().startsWith("iVBORw0KGgoAAAANSUhEUgAAACAAAAAaCAYAAADWm14/AAAD"));