From empty
To version 1.1
edited by Helge Dahl
on 2018/01/23 13:01
Change comment: Imported from XAR

Summary

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.XWikiGuest
1 +xwiki:XWiki.hde
Default language
... ... @@ -1,0 +1,1 @@
1 +en
Syntax
... ... @@ -1,1 +1,1 @@
1 -XWiki 2.1
1 +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

Tips

You can click on the arrows next to the breadcrumb elements to quickly navigate to sibling and children pages.

Need help?

If you need help with XWiki you can contact: