diff --git a/README.md b/README.md
index 840da87..742bddf 100644
--- a/README.md
+++ b/README.md
@@ -86,8 +86,14 @@ def html = gmd.gmdToHtml(text, [name: "Per"])
gmd.htmlToPdf(html, new File("pdfFile.pdf"))
```
-GMD supports the [Matrix](https://github.com/Alipsa/matrix) library directly, i.e. Matrix, Chart and MatrixXChart
-types can be used with the `out` PrintWriter object without needing to convert them into markdown first.
+GMD supports the [Matrix](https://github.com/Alipsa/matrix) library directly. `Matrix`,
+`se.alipsa.matrix.pict.Chart`, `se.alipsa.matrix.charm.Chart`, `se.alipsa.matrix.gg.GgChart`, and
+`MatrixXChart` types can be used with the `out` PrintWriter object without needing to convert them
+into markdown first. Pict, Charm, and GG charts accept `width`, `height`, optional alt text, and
+optional HTML attributes (for example, `out.println(chart, 640, 480, 'Sales chart', [class: 'chart'])`).
+They also accept alt text and attributes without explicit dimensions. Alt-only GG printing honors
+the dimensions configured on the chart; explicit GG dimensions are restored after rendering.
+MatrixXChart accepts optional alt text and HTML attributes.
Here is an example:
````
# Employees
diff --git a/gmd-core/pom.xml b/gmd-core/pom.xml
index 111e30a..41fb97b 100644
--- a/gmd-core/pom.xml
+++ b/gmd-core/pom.xml
@@ -177,6 +177,14 @@
se.alipsa.matrix
matrix-pict
+
+ se.alipsa.matrix
+ matrix-charts
+
+
+ se.alipsa.matrix
+ matrix-ggplot
+
se.alipsa.matrix
matrix-xchart
diff --git a/gmd-core/src/main/groovy/se/alipsa/gmd/core/Printer.groovy b/gmd-core/src/main/groovy/se/alipsa/gmd/core/Printer.groovy
index 6dda131..def4b64 100644
--- a/gmd-core/src/main/groovy/se/alipsa/gmd/core/Printer.groovy
+++ b/gmd-core/src/main/groovy/se/alipsa/gmd/core/Printer.groovy
@@ -3,6 +3,8 @@ package se.alipsa.gmd.core
import org.jsoup.nodes.Entities
import se.alipsa.groovy.svg.Svg
import se.alipsa.matrix.chartexport.ChartToSvg
+import se.alipsa.matrix.charm.Chart as CharmChart
+import se.alipsa.matrix.gg.GgChart
import se.alipsa.matrix.pict.CharmBridge;
import se.alipsa.matrix.pict.Chart;
import se.alipsa.matrix.core.Matrix
@@ -10,6 +12,9 @@ import se.alipsa.matrix.xchart.abstractions.MatrixXChart;
class Printer extends PrintWriter {
+ private static final int DEFAULT_CHART_WIDTH = 800
+ private static final int DEFAULT_CHART_HEIGHT = 600
+
Printer() {
super(new StringWriter());
}
@@ -51,11 +56,14 @@ class Printer extends PrintWriter {
private static String chartToMd(Chart x, double width, double height, String alt, Map attributes) {
- Svg svg = CharmBridge.renderSvg(x, width as int, height as int)
+ svgToMd(CharmBridge.renderSvg(x, width as int, height as int), alt, attributes)
+ }
+
+ private static String svgToMd(Svg svg, String alt, Map attributes) {
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
ChartToSvg.export(svg, os)
String imgContent = Base64.getEncoder().encodeToString(os.toByteArray())
- return imgToHtml("data:image/svg+xml;base64,${imgContent}", alt, attributes)
+ imgToHtml("data:image/svg+xml;base64,${imgContent}", alt, attributes)
}
}
@@ -63,7 +71,24 @@ class Printer extends PrintWriter {
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
x.exportSvg(os)
String imgContent = Base64.getEncoder().encodeToString(os.toByteArray())
- return imgToHtml("data:image/svg+xml;base64,${imgContent}", alt, attributes)
+ imgToHtml("data:image/svg+xml;base64,${imgContent}", alt, attributes)
+ }
+ }
+
+ private static String chartToMd(CharmChart x, double width, double height, String alt, Map attributes) {
+ svgToMd(x.render(width as int, height as int), alt, attributes)
+ }
+
+ private static String chartToMd(GgChart x, double width, double height, String alt, Map attributes) {
+ int originalWidth = x.width
+ int originalHeight = x.height
+ try {
+ x.width = width as int
+ x.height = height as int
+ svgToMd(x.render(), alt, attributes)
+ } finally {
+ x.width = originalWidth
+ x.height = originalHeight
}
}
@@ -104,14 +129,62 @@ class Printer extends PrintWriter {
print(isAtLineStart() ? terminateHtmlBlock(html) : html)
}
- void print(Chart x, double width = 800, double height = 600, String alt = '', Map attributes = [:]) {
+ void print(Chart x, double width = DEFAULT_CHART_WIDTH, double height = DEFAULT_CHART_HEIGHT, String alt = '', Map attributes = [:]) {
+ printChart(chartToMd(x, width, height, alt, attributes))
+ }
+
+ void println(Chart x, double width = DEFAULT_CHART_WIDTH, double height = DEFAULT_CHART_HEIGHT, String alt = '', Map attributes = [:]) {
+ println(chartToMd(x, width, height, alt, attributes))
+ }
+
+ void print(CharmChart x, double width = DEFAULT_CHART_WIDTH, double height = DEFAULT_CHART_HEIGHT, String alt = '', Map attributes = [:]) {
+ printChart(chartToMd(x, width, height, alt, attributes))
+ }
+
+ void println(CharmChart x, double width = DEFAULT_CHART_WIDTH, double height = DEFAULT_CHART_HEIGHT, String alt = '', Map attributes = [:]) {
+ println(chartToMd(x, width, height, alt, attributes))
+ }
+
+ void print(CharmChart x, String alt, Map attributes = [:]) {
+ printChart(chartToMd(x, DEFAULT_CHART_WIDTH, DEFAULT_CHART_HEIGHT, alt, attributes))
+ }
+
+ void println(CharmChart x, String alt, Map attributes = [:]) {
+ println(chartToMd(x, DEFAULT_CHART_WIDTH, DEFAULT_CHART_HEIGHT, alt, attributes))
+ }
+
+ void print(Chart x, String alt, Map attributes = [:]) {
+ printChart(chartToMd(x, DEFAULT_CHART_WIDTH, DEFAULT_CHART_HEIGHT, alt, attributes))
+ }
+
+ void println(Chart x, String alt, Map attributes = [:]) {
+ println(chartToMd(x, DEFAULT_CHART_WIDTH, DEFAULT_CHART_HEIGHT, alt, attributes))
+ }
+
+ /**
+ * Renders a GgChart at the supplied dimensions. The chart's original
+ * dimensions are restored before this method returns.
+ */
+ void print(GgChart x, double width = DEFAULT_CHART_WIDTH, double height = DEFAULT_CHART_HEIGHT, String alt = '', Map attributes = [:]) {
printChart(chartToMd(x, width, height, alt, attributes))
}
- void println(Chart x, double width = 800, double height = 600, String alt = '', Map attributes = [:]) {
+ /**
+ * Renders a GgChart at the supplied dimensions. The chart's original
+ * dimensions are restored before this method returns.
+ */
+ void println(GgChart x, double width = DEFAULT_CHART_WIDTH, double height = DEFAULT_CHART_HEIGHT, String alt = '', Map attributes = [:]) {
println(chartToMd(x, width, height, alt, attributes))
}
+ void print(GgChart x, String alt, Map attributes = [:]) {
+ printChart(svgToMd(x.render(), alt, attributes))
+ }
+
+ void println(GgChart x, String alt, Map attributes = [:]) {
+ println(svgToMd(x.render(), alt, attributes))
+ }
+
void print(MatrixXChart x, String alt = '', Map attributes = [:]) {
printChart(chartToMd(x, alt, attributes))
}
diff --git a/gmd-core/src/test/groovy/test/alipsa/groovy/gmd/GmdTest.groovy b/gmd-core/src/test/groovy/test/alipsa/groovy/gmd/GmdTest.groovy
index a646dc8..78172b9 100644
--- a/gmd-core/src/test/groovy/test/alipsa/groovy/gmd/GmdTest.groovy
+++ b/gmd-core/src/test/groovy/test/alipsa/groovy/gmd/GmdTest.groovy
@@ -547,13 +547,75 @@ def empData = Matrix.builder().data(
.build()
BarChart chart = BarChart.createVertical("Salaries", empData, "emp_name", ChartType.BASIC, "salary")
out.println(chart)
+out.println(chart, 'Pict chart')
```
'''
Gmd gmd = new Gmd()
String md = gmd.gmdToMd(text)
assertTrue(md.contains('# Employees'))
- String image = md.split("data:image/svg\\+xml;base64,", 2)[1].split('"', 2)[0]
- assertTrue(new String(Base64.decoder.decode(image), StandardCharsets.UTF_8).contains('