Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ jobs:
cache: maven

- name: Build and run tests
# Reactor slice: the engine plus the extracted graph-compose-testing
# module and the graph-compose-qa cross-module suites (which need the
# testing module + the engine test-jar on the classpath and so cannot
# live in the engine's own test scope). -am pulls the fonts / emoji
# upstreams; render-docx / bundle / examples / benchmarks are excluded.
run: ./mvnw -B -ntp -f aggregator/pom.xml clean verify -pl :graph-compose-core,:graph-compose-testing,:graph-compose-qa -am
# Reactor slice: the engine, the render-docx / render-pptx semantic backends,
# the extracted graph-compose-testing module, and the graph-compose-qa
# cross-module suites (which need the testing module + the engine test-jar on
# the classpath and so cannot live in the engine's own test scope). -am pulls
# the fonts / emoji upstreams; bundle / examples / benchmarks are excluded.
run: ./mvnw -B -ntp -f aggregator/pom.xml clean verify -pl :graph-compose-core,:graph-compose-render-docx,:graph-compose-render-pptx,:graph-compose-testing,:graph-compose-qa -am

- name: Generate Javadoc
# Run only on the baseline JDK — Javadoc output is identical
Expand Down
16 changes: 13 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,25 @@ jobs:
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}

- name: Publish render-docx to Maven Central
# The semantic DOCX/PPTX backend, lockstep-versioned with the engine
# (ships on the same v* tag). graph-compose resolves from the local repo
# installed by the engine deploy above.
# The semantic DOCX backend, lockstep-versioned with the engine (ships on
# the same v* tag). graph-compose-core resolves from the local repo installed
# by the engine deploy above.
run: ./mvnw -B -ntp -f render-docx/pom.xml -P release -DskipTests -Dgpg.skip=false deploy
env:
CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
CENTRAL_TOKEN: ${{ secrets.CENTRAL_TOKEN }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}

- name: Publish render-pptx to Maven Central
# The semantic PPTX backend, lockstep-versioned with the engine (ships on
# the same v* tag). graph-compose-core resolves from the local repo installed
# by the engine deploy above.
run: ./mvnw -B -ntp -f render-pptx/pom.xml -P release -DskipTests -Dgpg.skip=false deploy
env:
CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
CENTRAL_TOKEN: ${{ secrets.CENTRAL_TOKEN }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}

- name: Publish testing to Maven Central
# Consumer testing support (LayoutSnapshotAssertions / PdfVisualRegression),
# lockstep-versioned with the engine (ships on the same v* tag). graph-compose
Expand Down
16 changes: 9 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,20 @@ for this cycle.
**`graph-compose-core`** coordinate, and the original **`graph-compose` coordinate
becomes a thin drop-in aggregator** that depends on `graph-compose-core` — so an
existing `graph-compose` dependency keeps compiling and rendering PDF unchanged.
Consumer-testing support (`graph-compose-testing`) and the semantic DOCX/PPTX
backend (`graph-compose-render-docx`) are already separate artifacts; the PDF
Consumer-testing support (`graph-compose-testing`) and the semantic DOCX / PPTX
backends (`graph-compose-render-docx` / `graph-compose-render-pptx`) are already
separate artifacts; the PDF
render backend and the built-in templates move into their own modules over the
rest of the 2.0 cycle, at which point `graph-compose` aggregates the PDF backend
and `graph-compose-core` becomes the lean, bring-your-own-backend coordinate. The
optional `graph-compose-fonts` / `graph-compose-emoji` artifacts are unchanged.
Full install guidance ships with 2.0.0.
- `graph-compose-render-docx` is now a separate artifact: the semantic DOCX/PPTX
backend and Apache POI leave the `graph-compose` jar. `DocxSemanticBackend` moves
to `com.demcha.compose.document.backend.semantic.docx` and `PptxSemanticBackend`
to `com.demcha.compose.document.backend.semantic.pptx`; add
`graph-compose-render-docx` (it brings POI transitively) to export DOCX. The
- The semantic office backends are separate artifacts and Apache POI leaves the
engine: `DocxSemanticBackend` ships in `graph-compose-render-docx` (which brings
POI transitively — add it to export DOCX), and `PptxSemanticBackend` ships in its
own `graph-compose-render-pptx` (a POI-free skeleton for now — add it for the
slide-safe semantic manifest). Their packages —
`com.demcha.compose.document.backend.semantic.{docx,pptx}` — are unchanged. The
`no-poi` build profile is retired.
- `graph-compose-testing` is now a separate artifact: the consumer testing
support — `LayoutSnapshotAssertions` (deterministic layout snapshots) and
Expand Down
1 change: 1 addition & 0 deletions aggregator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
<module>../fonts</module>
<module>../emoji</module>
<module>../render-docx</module>
<module>../render-pptx</module>
<module>../testing</module>
<module>../bundle</module>
<module>../examples</module>
Expand Down
7 changes: 4 additions & 3 deletions render-docx/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
<modelVersion>4.0.0</modelVersion>

<!--
Semantic office export backend (DOCX today, a PPTX skeleton) split out of
the engine jar in the 2.0 module line. Apache POI (~10 MB) lives here, not
Semantic DOCX export backend split out of the engine jar in the 2.0 module
line (the PPTX skeleton split further into graph-compose-render-pptx).
Apache POI (~10 MB) lives here, not
in the lean core: a consumer that only renders PDF never pulls POI, and an
app that wants Word output adds this one artifact (it brings the core
transitively). SemanticBackend / SemanticExportContext / manifest — the SPI
Expand All @@ -21,7 +22,7 @@
<version>2.0.0-SNAPSHOT</version>

<name>GraphCompose Render — DOCX</name>
<description>Semantic DOCX / PPTX export backend for GraphCompose, backed by Apache POI.</description>
<description>Semantic DOCX export backend for GraphCompose, backed by Apache POI.</description>
<url>https://github.com/DemchaAV/GraphCompose</url>

<licenses>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,28 @@

import com.demcha.compose.GraphCompose;
import com.demcha.compose.document.api.DocumentSession;
import com.demcha.compose.document.backend.semantic.SemanticExportManifest;
import com.demcha.compose.document.backend.semantic.pptx.PptxSemanticBackend;
import com.demcha.compose.document.node.ContainerNode;
import com.demcha.compose.document.node.ParagraphNode;
import com.demcha.compose.document.node.ShapeNode;
import com.demcha.compose.document.node.TextAlign;
import com.demcha.compose.document.style.DocumentColor;
import com.demcha.compose.document.style.DocumentInsets;
import com.demcha.compose.document.style.DocumentStroke;
import com.demcha.compose.document.style.DocumentTextStyle;
import org.junit.jupiter.api.Test;

import java.awt.Color;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Exercises {@code DocumentSession.export(...)} with the semantic office backends
* from their new home. Moved out of the engine's {@code DocumentSessionTest} when
* the DOCX/PPTX backends were extracted to graph-compose-render-docx (the engine
* test scope can no longer see them). POI is always present in this module, so the
* old no-poi guard is dropped.
* Exercises {@code DocumentSession.export(new DocxSemanticBackend())} from its new
* home. Moved out of the engine's {@code DocumentSessionTest} when the DOCX backend
* was extracted to graph-compose-render-docx (the engine test scope can no longer
* see it). POI is always present in this module, so the old no-poi guard is dropped.
* The PPTX backend moved to graph-compose-render-pptx and is covered there.
*/
class SessionSemanticExportTest {

@Test
void semanticBackendsShouldExportManifestsFromDocumentGraph() throws Exception {
void docxBackendShouldExportZipPackageFromDocumentGraph() throws Exception {
try (DocumentSession session = GraphCompose.document()
.pageSize(200, 200)
.margin(DocumentInsets.of(10))
Expand All @@ -51,20 +45,6 @@ void semanticBackendsShouldExportManifestsFromDocumentGraph() throws Exception {
// of any ZIP container are the local-file-header signature.
assertThat(docx[0]).isEqualTo((byte) 'P');
assertThat(docx[1]).isEqualTo((byte) 'K');

session.clear();
session.add(new ContainerNode(
"PptxRoot",
List.of(new ShapeNode("Box", 40, 20, Color.BLUE, DocumentStroke.of(DocumentColor.BLACK, 1), DocumentInsets.zero(), DocumentInsets.zero())),
8,
DocumentInsets.zero(),
DocumentInsets.zero(),
null,
null));

SemanticExportManifest pptx = session.export(new PptxSemanticBackend());
assertThat(pptx.backendName()).isEqualTo("pptx-semantic");
assertThat(pptx.nodeKinds()).contains("ContainerNode", "ShapeNode");
}
}
}
216 changes: 216 additions & 0 deletions render-pptx/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<!--
Semantic PPTX export backend, split out of graph-compose-render-docx in the
2.0 module line so a consumer that wants slide output does not also pull the
DOCX backend's Apache POI. Today PptxSemanticBackend is a skeleton that
validates slide-safe semantic nodes and returns an export manifest, so this
module needs nothing beyond the core — POI joins only when real .pptx
emission lands. SemanticBackend / SemanticExportContext / manifest — the SPI
— stay in the core `document.backend.semantic` package.

Standalone pom (no aggregator parent, like fonts/render-docx); its version
tracks the engine line in lockstep (bumped by cut-release.ps1), and the
`release` profile is copy-pasted from the engine pom.
-->
<groupId>io.github.demchaav</groupId>
<artifactId>graph-compose-render-pptx</artifactId>
<version>2.0.0-SNAPSHOT</version>

<name>GraphCompose Render — PPTX</name>
<description>Semantic PPTX export backend for GraphCompose (slide-safe semantic node validation).</description>
<url>https://github.com/DemchaAV/GraphCompose</url>

<licenses>
<license>
<name>MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
<distribution>repo</distribution>
</license>
</licenses>

<developers>
<developer>
<id>DemchaAV</id>
<name>Artem Demchyshyn</name>
<email>demchishynartem@gmail.com</email>
<url>https://github.com/DemchaAV</url>
<roles>
<role>Lead Developer</role>
<role>Architect</role>
</roles>
<timezone>UTC 0</timezone>
</developer>
</developers>

<scm>
<connection>scm:git:https://github.com/DemchaAV/GraphCompose.git</connection>
<developerConnection>scm:git:ssh://git@github.com/DemchaAV/GraphCompose.git</developerConnection>
<url>https://github.com/DemchaAV/GraphCompose/tree/main</url>
</scm>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>17</maven.compiler.release>

<junit.bom.version>6.1.1</junit.bom.version>
<assertj.version>3.27.7</assertj.version>
<logback.version>1.5.37</logback.version>
<graphcompose.fonts.version>1.0.0</graphcompose.fonts.version>

<maven.compiler.plugin.version>3.15.0</maven.compiler.plugin.version>
<maven.jar.plugin.version>3.5.0</maven.jar.plugin.version>
<maven.surefire.plugin.version>3.5.6</maven.surefire.plugin.version>
<maven.source.plugin.version>3.4.0</maven.source.plugin.version>
<maven.javadoc.plugin.version>3.12.0</maven.javadoc.plugin.version>
<maven.gpg.plugin.version>3.2.8</maven.gpg.plugin.version>
<central.publishing.plugin.version>0.11.0</central.publishing.plugin.version>

<!-- See the engine pom: opted in via -Dgpg.skip=false on the publish workflow. -->
<gpg.skip>true</gpg.skip>
</properties>

<dependencies>
<dependency>
<groupId>io.github.demchaav</groupId>
<artifactId>graph-compose-core</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.bom.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>test</scope>
</dependency>
<!--
The export test builds a DocumentSession, which lays out text through the
font metrics seam; the bundled families come from the published fonts
artifact (same as the engine's own test suite since v2.0).
-->
<dependency>
<groupId>io.github.demchaav</groupId>
<artifactId>graph-compose-fonts</artifactId>
<version>${graphcompose.fonts.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<release>${maven.compiler.release}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven.jar.plugin.version}</version>
</plugin>
</plugins>
</build>

<profiles>
<!-- Maven Central release artefacts — mirrors the engine pom's `release`
profile (sources + javadoc + GPG + central-publishing). Standalone by
design, so the configuration is duplicated rather than inherited. -->
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${maven.source.plugin.version}</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven.javadoc.plugin.version}</version>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<doclint>none</doclint>
<failOnError>false</failOnError>
<quiet>true</quiet>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>${maven.gpg.plugin.version}</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<skip>${gpg.skip}</skip>
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>${central.publishing.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
<autoPublish>false</autoPublish>
<waitUntil>validated</waitUntil>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Loading