Changes for page PlantUML Macro
Last modified by Helge Dahl on 2018/03/11 07:52
From empty
To version 1.1
edited by Helge Dahl
on 2018/01/23 13:01
on 2018/01/23 13:01
Change comment: Imported from XAR
Summary
-
Page properties (6 modified, 0 added, 0 removed)
-
Objects (0 modified, 3 added, 0 removed)
Details
- Page properties
-
- Title
-
... ... @@ -1,0 +1,1 @@ 1 +PlantUML Macro - Parent
-
... ... @@ -1,0 +1,1 @@ 1 +Main.WebHome - Author
-
... ... @@ -1,1 +1,1 @@ 1 - XWiki.XWikiGuest1 +xwiki:XWiki.hde - Default language
-
... ... @@ -1,0 +1,1 @@ 1 +en - Syntax
-
... ... @@ -1,1 +1,1 @@ 1 -XWiki 2. 11 +XWiki 2.0 - Content
-
... ... @@ -1,0 +1,21 @@ 1 +This macro enables you to include UML diagrams inside your wiki pages using **PlantUML** ([[http://plantuml.sourceforge.net]]). 2 + 3 +== Configuration == 4 + 5 +{{velocity}} 6 +#if ($doc.getObject("XWiki.PlantUMLConfigurationClass").Server != '') 7 +The configured active server is :** $doc.getObject("XWiki.PlantUMLConfigurationClass").Server ** 8 +#else 9 +**No server specified**, using the embedded PlantUML implementation. 10 +#end 11 + 12 +To specify your own PlantUML server, {{html}}<a href="$xwiki.getURL( $doc.getFullName(), "edit", "editor=object&classname=XWiki.PlantUMLConfigurationClass&object=0")">edit this URL</a>{{/html}}. 13 +The default value is {{html}}http://www.plantuml.com/plantuml/{{/html}} 14 +Be careful, the server URL must end with a slash. 15 +{{/velocity}} 16 + 17 +== Version information == 18 + 19 +{{plantuml}} 20 +version 21 +{{/plantuml}}
- XWiki.PlantUMLConfigurationClass[0]
-
- XWiki.WikiMacroClass[0]
-
- Macro code
-
... ... @@ -1,0 +1,120 @@ 1 +{{groovy}} 2 +// Utility class and method from plantUML to encode the UML text. See below the starting point of the macro. 3 +import java.util.zip.* 4 + 5 +byte[] compress(byte[] input) { 6 + int len = input.length + 100; 7 + Deflater compresser = new Deflater(9, true); 8 + compresser.setInput(input); 9 + compresser.finish(); 10 + byte[] output = new byte[len]; 11 + int compressedDataLength = compresser.deflate(output); 12 + byte[] result = new byte[compressedDataLength]; 13 + System.arraycopy(output,0,result,0,compressedDataLength); 14 + return result; 15 +} 16 + 17 +class AsciiEncoder { 18 + char[] encode6bits = new char[64]; 19 + 20 + public AsciiEncoder() { 21 + for (byte b = 0; b < 64; b++) { 22 + encode6bits[b] = encode6bit(b as byte); 23 + } 24 + } 25 + 26 + public String encode(byte[] data) { 27 + final StringBuilder resu = new StringBuilder((int)((data.length * 4 + 2) / 3)); 28 + for (int i = 0; i < data.length; i += 3) { 29 + append3bytes(resu, data[i] & 0xFF, i + 1 < data.length ? data[i + 1] & 0xFF : 0, 30 + i + 2 < data.length ? data[i + 2] & 0xFF : 0); 31 + } 32 + return resu.toString(); 33 + } 34 + 35 + private char encode6bit(byte b) { 36 + assert b >= 0 && b < 64; 37 + if (b < 10) { 38 + return (char)(('0' as char) + b); 39 + } 40 + b -= 10; 41 + if (b < 26) { 42 + return (char)(('A' as char) + b); 43 + } 44 + b -= 26; 45 + if (b < 26) { 46 + return (char)(('a' as char) + b); 47 + } 48 + b -= 26; 49 + if (b == 0) { 50 + return '-' as char; 51 + } 52 + if (b == 1) { 53 + return '_' as char; 54 + } 55 + assert false; 56 + return '?'; 57 + } 58 + 59 + private void append3bytes(StringBuilder sb, int b1, int b2, int b3) { 60 + final int c1 = b1 >> 2; 61 + final int c2 = ((b1 & 0x3) << 4) | (b2 >> 4); 62 + final int c3 = ((b2 & 0xF) << 2) | (b3 >> 6); 63 + final int c4 = b3 & 0x3F; 64 + sb.append(encode6bits[c1 & 0x3F]); 65 + sb.append(encode6bits[c2 & 0x3F]); 66 + sb.append(encode6bits[c3 & 0x3F]); 67 + sb.append(encode6bits[c4 & 0x3F]); 68 + } 69 +} 70 + 71 +// Utility method to insert content in the uml script taking care of the @start marker. 72 +String insertHeader( String header, String origin) { 73 + def m = origin =~ /(?s)(@start[a-z]++)(.*)/ 74 + if (m.matches()) { 75 + return m[0][1] + "\n" + header + "\n" + m[0][2] 76 + } else { 77 + return header + "\n" + origin 78 + } 79 +} 80 + 81 +// STARTING POINT 82 +// Get the uml script 83 +def umltext = xcontext.macro.content 84 + 85 +// Add the optional 'include' content 86 +def include = xcontext.macro.params.include 87 +if (include) { 88 + def incDoc = xwiki.getDocument(include) 89 + if (!incDoc.isNew()) { 90 + umltext = insertHeader(incDoc.content, umltext) 91 + } else { 92 + println "**PlantUMLMacro WARNING**: Can't include page "+include 93 + } 94 +} 95 + 96 +// Get the configured server 97 +def macrodoc = xcontext.getMacro().get("doc") 98 +def serverurl 99 +def imageFormat 100 +def enableImageMap 101 +if (macrodoc.getObject("XWiki.PlantUMLConfigurationClass") != null) { 102 + serverurl = macrodoc.getObject('XWiki.PlantUMLConfigurationClass').getProperty('Server').value 103 + imageFormat = macrodoc.getObject('XWiki.PlantUMLConfigurationClass').getProperty('ImageFormat').value 104 + enableImageMap = macrodoc.getObject('XWiki.PlantUMLConfigurationClass').getProperty('EnableImageMap').value 105 +} 106 + 107 + 108 +if (serverurl == "") { // Uses the internal PlantUMLMacroGClass groovy implementation 109 + gObj = xwiki.parseGroovyFromPage( "XWiki.PlantUMLMacroGClass", "XWiki.PlantUMLMacroGClass") 110 + gObj.setObjects(doc, xcontext, umltext, imageFormat, enableImageMap) 111 + println gObj.run( request, response) 112 +} else { // Uses the external configured PlantUML server 113 + // Encode the UML content 114 + byte[] data = umltext.getBytes("UTF-8") 115 + byte[] compressed = compress(data) 116 + String encoded = new AsciiEncoder().encode(compressed) 117 + // Output the image wiki tag 118 + println "[[image:"+serverurl+"img/"+encoded+"||style=\"max-width:100%\"]]" 119 +} 120 +{{/groovy}} - Content description (Not applicable for "No content" type)
-
... ... @@ -1,0 +1,1 @@ 1 +The diagram definition using PlanUML's syntax. - Macro content type
-
... ... @@ -1,0 +1,1 @@ 1 +Mandatory - Default category
-
... ... @@ -1,0 +1,1 @@ 1 +content - Macro description
-
... ... @@ -1,0 +1,1 @@ 1 +Generate Diagrams using PlantUML. - Macro id
-
... ... @@ -1,0 +1,1 @@ 1 +plantuml - Macro name
-
... ... @@ -1,0 +1,1 @@ 1 +PlantUML - Supports inline mode
-
... ... @@ -1,0 +1,1 @@ 1 +No - Macro visibility
-
... ... @@ -1,0 +1,1 @@ 1 +Global
- XWiki.WikiMacroParameterClass[0]
-
- Parameter description
-
... ... @@ -1,0 +1,1 @@ 1 +The content of the specified wiki page will be inserted at the begining of the diagram definition. Please note the page name may be prefixed with its space and is case sensitive. For example, you may include: Sandbox.UMLskin - Parameter mandatory
-
... ... @@ -1,0 +1,1 @@ 1 +No - Parameter name
-
... ... @@ -1,0 +1,1 @@ 1 +include