diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000..7d6f27a14
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.java text=auto
diff --git a/.github/labeler.yml b/.github/labeler.yml
index 4f260b7ec..3924b988d 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -1,37 +1,55 @@
'm:release':
-- 'CHANGELOG.md'
-- 'gradle.properties'
+- changed-files:
+ - any-glob-to-any-file:
+ - 'CHANGELOG.md'
+ - 'gradle.properties'
'm:docs':
-- '*.md'
-- 'docs/**/*'
+- changed-files:
+ - any-glob-to-any-file:
+ - '*.md'
+ - 'docs/**/*'
'm:workflow':
-- .github/**
+- changed-files:
+ - any-glob-to-any-file:
+ - .github/**
'm:gradle':
-- 'gradle*'
-- 'gradle/**'
-- '**/settings.gradle.*'
-- '**/build.gradle.*'
-- 'sjpp.jar'
+- changed-files:
+ - any-glob-to-any-file:
+ - 'gradle*'
+ - 'gradle/**'
+ - '**/settings.gradle.*'
+ - '**/build.gradle.*'
+ - 'sjpp.jar'
'm:source':
-- 'skin/**/*'
-- 'src/**/*'
-- 'stdlib/**/*'
-- 'svg/**/*'
-- 'themes/**/*'
-- 'manifest.txt'
+- changed-files:
+ - any-glob-to-any-file:
+ - 'skin/**/*'
+ - 'src/**/*'
+ - 'stdlib/**/*'
+ - 'svg/**/*'
+ - 'themes/**/*'
+ - 'manifest.txt'
'm:test':
-- 'test/**/*'
+- changed-files:
+ - any-glob-to-any-file:
+ - 'test/**/*'
'm:license':
-- '**/*license.txt'
+- changed-files:
+ - any-glob-to-any-file:
+ - '**/*license.txt'
'm:docker':
-- Dockerfile
+- changed-files:
+ - any-glob-to-any-file:
+ - Dockerfile
'm:native':
-- .github/workflows/native-image.yml
+- changed-files:
+ - any-glob-to-any-file:
+ - .github/workflows/native-image.yml
diff --git a/.github/workflows/add-triage-label.yml b/.github/workflows/add-triage-label.yml
index 56da33e00..c98272529 100644
--- a/.github/workflows/add-triage-label.yml
+++ b/.github/workflows/add-triage-label.yml
@@ -12,7 +12,7 @@ jobs:
permissions:
issues: write
steps:
- - uses: actions/github-script@v6
+ - uses: actions/github-script@v7
with:
script: |
github.rest.issues.addLabels({
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1bc3effb2..7b685a9f5 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -99,7 +99,7 @@ jobs:
- name: Set up java
if: needs.workflow_config.outputs.do_test_linux == 'true'
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: temurin
@@ -115,7 +115,7 @@ jobs:
run: gradle test --no-daemon -i
- name: Upload test reports
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: needs.workflow_config.outputs.do_test_linux == 'true'
with:
# Using github.run_number here to reduce confusion when downloading & comparing from several builds
@@ -132,7 +132,7 @@ jobs:
- name: Checkout the repository
uses: actions/checkout@v4
- name: Set up java
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: 17
distribution: temurin
@@ -172,7 +172,7 @@ jobs:
run: |
echo "release_version=$(gradle properties -q | grep "version:" | awk '{print $2}')" >> $GITHUB_OUTPUT
- name: Cache libs
- uses: actions/cache/save@v3
+ uses: actions/cache/save@v4
with:
path: |
build/libs
@@ -195,7 +195,7 @@ jobs:
uses: actions/checkout@v4
- name: Set up java
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: 17
distribution: temurin
@@ -221,14 +221,14 @@ jobs:
uses: actions/checkout@v4
- name: Set up java
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: 17
distribution: temurin
cache: gradle
- name: Restore Libs cache
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: |
build/libs
@@ -244,7 +244,7 @@ jobs:
enableCrossOsArchive: true
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
# Using github.run_number here to reduce confusion when downloading & comparing artifacts from several builds
name: ${{ github.run_number }}-artifacts
diff --git a/.github/workflows/close-and-put-in-backlog.yml b/.github/workflows/close-and-put-in-backlog.yml
index 26afa923d..91ad3c50d 100644
--- a/.github/workflows/close-and-put-in-backlog.yml
+++ b/.github/workflows/close-and-put-in-backlog.yml
@@ -7,7 +7,7 @@ jobs:
if: github.event.label.name == 'p:backlog'
runs-on: ubuntu-latest
steps:
- - uses: actions/github-script@v6
+ - uses: actions/github-script@v7
with:
script: |
const welcomeMessage = `
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index 07b21837d..2a340279e 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -9,4 +9,4 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:
- - uses: actions/labeler@v4
+ - uses: actions/labeler@v5
diff --git a/.github/workflows/native-image.yml b/.github/workflows/native-image.yml
index de3990925..7db154b09 100644
--- a/.github/workflows/native-image.yml
+++ b/.github/workflows/native-image.yml
@@ -32,7 +32,7 @@ jobs:
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
- - uses: actions/cache/restore@v3
+ - uses: actions/cache/restore@v4
with:
path: |
build/libs
@@ -57,7 +57,7 @@ jobs:
native-image -H:ConfigurationFileDirectories=native-image-config-dir --no-fallback --report-unsupported-elements-at-runtime -jar "build/libs/plantuml-${{ inputs.release-version }}.jar" -H:Path="build/libs" -H:Name="plantuml-${{ matrix.platform }}-${{ inputs.release-version }}"
- name: Cache native image
- uses: actions/cache/save@v3
+ uses: actions/cache/save@v4
with:
path: "build/libs/plantuml-${{ matrix.platform }}-*"
key: "native-image-${{ matrix.platform }}-${{ github.run_id }}"
diff --git a/.gitignore b/.gitignore
index 73ddb5bb8..da13ed288 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,7 @@
out
#vscode files
-/bin
+**/bin/
# Ant result file
plantuml.jar
diff --git a/BUILDING.md b/BUILDING.md
index 3c436bdb5..be2856729 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -2,7 +2,7 @@
Thank you for your interest in contributing to PlantUML! This guide will help you build the PlantUML project.
-PlantUML can be built using either [Gradle](#building-plantuml-with-gradle) or [Ant](#building-plantuml-with-ant-alternative-method). It's recommended to use Gradle as the primary build tool for this project. You will find instructions for both methods, starting with Gradle.
+PlantUML can be built using either [Gradle](#-building-plantuml-with-gradle) or [Ant](#-building-plantuml-with-ant-alternative-method). It's recommended to use Gradle as the primary build tool for this project. You will find instructions for both methods, starting with Gradle.
## ☕ Java Compatibility and Development Notes
diff --git a/README.md b/README.md
index 94a914390..ed53dcb1e 100644
--- a/README.md
+++ b/README.md
@@ -56,6 +56,7 @@ PlantUML is a component that allows you to create various UML diagrams through s
- [SDL (Specification and Description Language)](http://plantuml.com/activity-diagram-beta#sdl)
- [Ditaa diagram](http://plantuml.com/ditaa)
- [Gantt diagram](http://plantuml.com/gantt-diagram)
+ - [Chronology diagram](http://plantuml.com/chronology-diagram)
- [MindMap diagram](http://plantuml.com/mindmap-diagram)
- [WBS (Work Breakdown Structure)](http://plantuml.com/wbs-diagram)
- [Mathematical Notations (AsciiMath, JLaTeXMath)](http://plantuml.com/ascii-math)
diff --git a/build.gradle.kts b/build.gradle.kts
index 72fb2d760..6b79adc39 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -31,8 +31,9 @@ dependencies {
compileOnly("org.apache.ant:ant:1.10.14")
testImplementation("io.github.glytching:junit-extensions:2.6.0")
- testImplementation("org.assertj:assertj-core:3.24.2")
- testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
+ testImplementation("org.assertj:assertj-core:3.25.3")
+ testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
+ testImplementation("org.xmlunit:xmlunit-core:2.9.+")
if (JavaVersion.current().isJava8) {
testImplementation("org.mockito:mockito-core:4.+")
testImplementation("org.mockito:mockito-junit-jupiter:4.+")
diff --git a/docs/PACKAGE_AND_DISTRIBUTION.md b/docs/PACKAGE_AND_DISTRIBUTION.md
new file mode 100644
index 000000000..c1266219c
--- /dev/null
+++ b/docs/PACKAGE_AND_DISTRIBUTION.md
@@ -0,0 +1,97 @@
+# PlantUML packages and PlantUML on the _[most popular]_ GNU/Linux distributions
+
+## PlantUML packages
+
+### GitHub _(The main PlantUML package repository)_
+[![GitHub Release](https://img.shields.io/github/v/release/plantuml/plantuml)](https://github.com/plantuml/plantuml/releases/latest)
+
+### Chocolatey
+[![Chocolatey Version](https://img.shields.io/chocolatey/v/plantuml)](https://community.chocolatey.org/packages/plantuml)
+
+### Docker
+[![Docker Image Version](https://img.shields.io/docker/v/plantuml/plantuml)](https://github.com/plantuml/plantuml/pkgs/container/plantuml)
+
+### Homebrew
+[![homebrew version](https://img.shields.io/homebrew/v/plantuml)](https://formulae.brew.sh/formula/plantuml)
+
+### Maven
+[![Maven Central Version](https://img.shields.io/maven-central/v/net.sourceforge.plantuml/plantuml)](https://mvnrepository.com/artifact/net.sourceforge.plantuml/plantuml)
+
+### Scoop
+[![Scoop Version](https://img.shields.io/scoop/v/plantuml?bucket=extras)](https://scoop.sh/#/apps?q=plantuml)
+
+
+
+## PlantUML on the _[most popular]_ GNU/Linux distributions
+
+### [Alpine Linux](https://www.alpinelinux.org)
+| Type | Link |
+| ------- | ---- |
+| Distribution | ![Alpine Linux](https://img.shields.io/badge/Alpine_Linux-%230D597F.svg?style=for-the-badge&logo=alpine-linux&logoColor=white) |
+| Last PlantUML version | |
+| Link | https://pkgs.alpinelinux.org/packages?name=plantuml&branch=edge |
+| Specificity | |
+
+### [Archlinux](https://archlinux.org)
+| Type | Link |
+| ------- | ---- |
+| Distribution | ![Arch](https://img.shields.io/badge/Arch%20Linux-1793D1?logo=arch-linux&logoColor=fff&style=for-the-badge) |
+| Last PlantUML version | [![Arch Linux package](https://img.shields.io/archlinux/v/extra/any/plantuml)](https://archlinux.org/packages/extra/any/plantuml/) |
+| Link | https://archlinux.org/packages/extra/any/plantuml/ |
+| Specificity | |
+
+### [Debian](https://www.debian.org)
+| Type | Link |
+| ------- | ---- |
+| Distribution | ![Debian](https://img.shields.io/badge/Debian-D70A53?style=for-the-badge&logo=debian&logoColor=white) |
+| Last PlantUML version | [![Debian package](https://img.shields.io/debian/v/plantuml)](https://salsa.debian.org/debian/plantuml) |
+| Link | https://salsa.debian.org/debian/plantuml |
+| Specificity | https://salsa.debian.org/debian/plantuml/-/tree/master/debian |
+
+### [Fedora](https://fedoraproject.org)
+| Type | Link |
+| ------- | ---- |
+| Distribution | ![Fedora](https://img.shields.io/badge/Fedora-294172?style=for-the-badge&logo=fedora&logoColor=white) |
+| Last PlantUML version | [![Fedora package](https://img.shields.io/fedora/v/plantuml)](https://src.fedoraproject.org/rpms/plantuml) |
+| Link | https://src.fedoraproject.org/rpms/plantuml |
+| Specificity | |
+
+### [Gentoo](https://www.gentoo.org/)
+| Type | Link |
+| ------- | ---- |
+| Distribution | ![Gentoo](https://img.shields.io/badge/Gentoo-54487A?style=for-the-badge&logo=gentoo&logoColor=white) |
+| Last PlantUML version | |
+| Link | https://packages.gentoo.org/packages/media-gfx/plantuml |
+| Specificity | |
+
+### [openSUSE](https://www.opensuse.org)
+| Type | Link |
+| ------- | ---- |
+| Distribution | ![openSUSE](https://img.shields.io/badge/openSUSE-%2364B345?style=for-the-badge&logo=openSUSE&logoColor=white) |
+| Last PlantUML version | |
+| Link | https://build.opensuse.org/search?search_text=plantuml |
+| Specificity | https://build.opensuse.org/package/show/Java:packages/plantuml
https://build.opensuse.org/package/show/home:mnhauke/plantuml |
+
+### [SUSE](https://www.suse.com)
+| Type | Link |
+| ------- | ---- |
+| Distribution | ![Suse](https://img.shields.io/badge/SUSE-0C322C?style=for-the-badge&logo=SUSE&logoColor=white) |
+| Last PlantUML version | |
+| Link | https://packagehub.suse.com/packages/plantuml/ |
+| Specificity | |
+
+### [Ubuntu](https://ubuntu.com)
+| Type | Link |
+| ------- | ---- |
+| Distribution | ![Ubuntu](https://img.shields.io/badge/Ubuntu-E95420?style=for-the-badge&logo=ubuntu&logoColor=white) |
+| Last PlantUML version | [![Ubuntu Package Version](https://img.shields.io/ubuntu/v/plantuml)](https://packages.ubuntu.com/search?keywords=plantuml&searchon=names&suite=all§ion=all) |
+| Link | https://packages.ubuntu.com/search?keywords=plantuml&searchon=names&suite=all§ion=all |
+| Specificity | |
+
+
+# Reference and acknowledgement
+- https://en.wikipedia.org/wiki/List_of_software_package_management_systems
+- https://en.wikipedia.org/wiki/List_of_Linux_distributions
+- https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/creating-a-default-community-health-file
+- https://shields.io
+
diff --git a/docs/SUPPORT.md b/docs/SUPPORT.md
new file mode 100644
index 000000000..555a79f16
--- /dev/null
+++ b/docs/SUPPORT.md
@@ -0,0 +1,58 @@
+# 🌱 PlantUML Support
+
+Thank you for using PlantUML! If you need assistance or have questions, please refer to the following resources:
+
+## Where to Get Support
+
+### GitHub Issues
+
+- For reporting bugs or issues, open an [issue on GitHub](https://github.com/plantuml/plantuml/issues).
+ - When submitting an issue, provide clear steps to reproduce the problem and include your PlantUML version.
+- Before creating a new issue, search the existing ones on [GitHub](https://github.com/plantuml/plantuml/issues) to see if your problem has already been addressed.
+
+### Community Forum
+
+- Visit our [Community Forum](https://forum.plantuml.net/) for discussions, FAQs, and community support.
+- Check for existing threads to see if your question has already been answered.
+
+### Discord
+
+- Feel free to ask questions on our official [Discord](https://discord.com/invite/sXhzexAQGh) server.
+
+## Asking Questions
+
+If you have a question about using PlantUML:
+
+- Search through the [official documentation](https://plantuml.com/) and available resources before asking.
+- Feel free to ask questions on the GitHub issues or the Community Forum after performing initial research.
+- Provide as much detail as possible when asking questions to receive effective assistance.
+
+## Contributing
+
+We welcome contributions to PlantUML! If you're interested in contributing:
+
+### Reporting Bugs
+
+- Ensure you're using the latest version and search for existing issues on GitHub or the Community Forum before reporting a bug.
+- Submit a bug report on [GitHub](https://github.com/plantuml/plantuml/issues) with clear steps to reproduce and your environment details.
+
+### Suggesting Enhancements
+
+- Search existing enhancement suggestions on GitHub or the Community Forum before submitting a new one.
+- Submit your enhancement suggestion with a clear title and detailed description on [GitHub](https://github.com/plantuml/plantuml/issues).
+
+### Your First Code Contribution
+
+- Review our [contributing guide](CONTRIBUTING.md) to get started with code contributions.
+- If you're new to contributing, consider tackling issues labeled as 'good first issue' or 'help wanted'.
+
+## Additional Resources
+
+- For comprehensive documentation, refer to the [official PlantUML Javadoc](https://plantuml.github.io/plantuml/).
+- Explore the [GitHub issues](https://github.com/plantuml/plantuml/issues/) for discussions and known problems.
+
+## 🧑🤝🧑 Community Support
+
+Feel free to engage with the PlantUML community on GitHub and the Community Forum.
+
+Thank you for being a part of the PlantUML community!
diff --git a/gradle.properties b/gradle.properties
index 39994fd2b..4b0a74673 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
# Warning, "version" should be the same in gradle.properties and Version.java
# Any idea anyone how to magically synchronize those :-) ?
-version = 1.2023.13beta1
+version = 1.2024.4beta6
org.gradle.workers.max = 3
\ No newline at end of file
diff --git a/plantuml-asl/build.gradle.kts b/plantuml-asl/build.gradle.kts
index 79ebca686..b4217ad15 100644
--- a/plantuml-asl/build.gradle.kts
+++ b/plantuml-asl/build.gradle.kts
@@ -25,9 +25,10 @@ java {
dependencies {
compileOnly("org.apache.ant:ant:1.10.14")
- testImplementation("org.assertj:assertj-core:3.24.2")
- testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
+ testImplementation("org.assertj:assertj-core:3.25.3")
+ testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testImplementation("org.scilab.forge:jlatexmath:1.0.7")
+ testImplementation("org.xmlunit:xmlunit-core:2.9.+")
}
repositories {
diff --git a/plantuml-bsd/build.gradle.kts b/plantuml-bsd/build.gradle.kts
index f57ec2fe1..393e7a45c 100644
--- a/plantuml-bsd/build.gradle.kts
+++ b/plantuml-bsd/build.gradle.kts
@@ -25,8 +25,8 @@ java {
dependencies {
compileOnly("org.apache.ant:ant:1.10.14")
- testImplementation("org.assertj:assertj-core:3.24.2")
- testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
+ testImplementation("org.assertj:assertj-core:3.25.3")
+ testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testImplementation("org.scilab.forge:jlatexmath:1.0.7")
}
diff --git a/plantuml-epl/build.gradle.kts b/plantuml-epl/build.gradle.kts
index 0c94e1a85..5bf7756f4 100644
--- a/plantuml-epl/build.gradle.kts
+++ b/plantuml-epl/build.gradle.kts
@@ -25,9 +25,10 @@ java {
dependencies {
compileOnly("org.apache.ant:ant:1.10.14")
- testImplementation("org.assertj:assertj-core:3.24.2")
- testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
+ testImplementation("org.assertj:assertj-core:3.25.3")
+ testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testImplementation("org.scilab.forge:jlatexmath:1.0.7")
+ testImplementation("org.xmlunit:xmlunit-core:2.9.+")
}
repositories {
diff --git a/plantuml-gplv2/build.gradle.kts b/plantuml-gplv2/build.gradle.kts
index 740d97e91..c7df0ca29 100644
--- a/plantuml-gplv2/build.gradle.kts
+++ b/plantuml-gplv2/build.gradle.kts
@@ -25,9 +25,10 @@ java {
dependencies {
compileOnly("org.apache.ant:ant:1.10.14")
- testImplementation("org.assertj:assertj-core:3.24.2")
- testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
+ testImplementation("org.assertj:assertj-core:3.25.3")
+ testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testImplementation("org.scilab.forge:jlatexmath:1.0.7")
+ testImplementation("org.xmlunit:xmlunit-core:2.9.+")
}
repositories {
diff --git a/plantuml-lgpl/build.gradle.kts b/plantuml-lgpl/build.gradle.kts
index f110030e0..667667df0 100644
--- a/plantuml-lgpl/build.gradle.kts
+++ b/plantuml-lgpl/build.gradle.kts
@@ -25,9 +25,10 @@ java {
dependencies {
compileOnly("org.apache.ant:ant:1.10.14")
- testImplementation("org.assertj:assertj-core:3.24.2")
- testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
+ testImplementation("org.assertj:assertj-core:3.25.3")
+ testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testImplementation("org.scilab.forge:jlatexmath:1.0.7")
+ testImplementation("org.xmlunit:xmlunit-core:2.9.+")
}
repositories {
diff --git a/plantuml-mit/build.gradle.kts b/plantuml-mit/build.gradle.kts
index 995be47c3..d7e2cf555 100644
--- a/plantuml-mit/build.gradle.kts
+++ b/plantuml-mit/build.gradle.kts
@@ -25,9 +25,10 @@ java {
dependencies {
compileOnly("org.apache.ant:ant:1.10.14")
- testImplementation("org.assertj:assertj-core:3.24.2")
- testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
+ testImplementation("org.assertj:assertj-core:3.25.3")
+ testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testImplementation("org.scilab.forge:jlatexmath:1.0.7")
+ testImplementation("org.xmlunit:xmlunit-core:2.9.+")
}
repositories {
diff --git a/skin/plantuml.skin b/skin/plantuml.skin
index 9f7920474..e71b91a42 100644
--- a/skin/plantuml.skin
+++ b/skin/plantuml.skin
@@ -367,9 +367,21 @@ ganttDiagram {
Margin 5
Padding 5
}
+ verticalSeparator {
+ LineThickness 2
+ LineStyle 2-2
+ LineColor black
+ }
timeline {
BackgroundColor transparent
LineColor #C0C0C0
+ FontSize 10
+ month {
+ FontSize 12
+ }
+ year {
+ FontSize 14
+ }
}
closed {
BackGroundColor #F1E5E5
diff --git a/src/com/plantuml/api/cheerpj/v1/DirectDraw.java b/src/com/plantuml/api/cheerpj/v1/DirectDraw.java
index 295b0cc0b..88572fcf6 100644
--- a/src/com/plantuml/api/cheerpj/v1/DirectDraw.java
+++ b/src/com/plantuml/api/cheerpj/v1/DirectDraw.java
@@ -53,6 +53,7 @@ import net.sourceforge.plantuml.BlockUml;
import net.sourceforge.plantuml.BlockUmlBuilder;
import net.sourceforge.plantuml.ErrorUml;
import net.sourceforge.plantuml.FileFormat;
+import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.error.PSystemError;
import net.sourceforge.plantuml.klimt.color.ColorMapper;
@@ -122,7 +123,7 @@ public class DirectDraw {
ug.apply(back).apply(back.bg()).draw(URectangle.build(frameWidth, frameHeight));
WasmLog.log("...drawing...");
- system.exportDiagramGraphic(ug);
+ system.exportDiagramGraphic(ug, new FileFormatOption(FileFormat.PNG));
WasmLog.log("done!");
diff --git a/src/com/plantuml/api/cheerpj/v1/Raw.java b/src/com/plantuml/api/cheerpj/v1/Raw.java
index c8a12200e..e1ec34f5c 100644
--- a/src/com/plantuml/api/cheerpj/v1/Raw.java
+++ b/src/com/plantuml/api/cheerpj/v1/Raw.java
@@ -55,6 +55,7 @@ import net.sourceforge.plantuml.BlockUmlBuilder;
import net.sourceforge.plantuml.EmptyImageBuilder;
import net.sourceforge.plantuml.ErrorUml;
import net.sourceforge.plantuml.FileFormat;
+import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.api.ImageDataSimple;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.core.ImageData;
@@ -124,7 +125,7 @@ public class Raw {
ug.resetMax();
WasmLog.log("...drawing...");
- system.exportDiagramGraphic(ug);
+ system.exportDiagramGraphic(ug, new FileFormatOption(FileFormat.PNG));
final int width = (int) (2 + ug.getMaxX());
final int height = (int) (2 + ug.getMaxY());
@@ -208,7 +209,7 @@ public class Raw {
ug.resetMax();
WasmLog.log("...drawing...");
- system.exportDiagramGraphic(ug);
+ system.exportDiagramGraphic(ug, new FileFormatOption(FileFormat.PNG));
final int width = (int) (2 + ug.getMaxX());
final int height = (int) (2 + ug.getMaxY());
diff --git a/src/h/package-info.java b/src/h/package-info.java
index dff6c2a46..154188af6 100644
--- a/src/h/package-info.java
+++ b/src/h/package-info.java
@@ -12,9 +12,9 @@
*
*
*
- * @see gen
+ * @see "gen"
* @see gen.annotation
- * @see gen.lib
+ * @see "gen.lib"
* @see gen.plugin.dot_layout
* @see smetana.core
* @see net.sourceforge.plantuml.sdot
diff --git a/src/jcckit/package-info.java b/src/jcckit/package-info.java
new file mode 100644
index 000000000..6bc88456f
--- /dev/null
+++ b/src/jcckit/package-info.java
@@ -0,0 +1,16 @@
+/*
+ * ⚠ Disclaimer 🚩
+ * This file was not part of the original package.
+ * It was included only on the PlantUML package
+ * to provide source citation and documentation.
+ *
+ */
+/**
+ * Internal copy of
+ *
+ * JCCKit
(code of Franz-Josef Elmer).
+ *
+ * @see net.sourceforge.plantuml.jcckit
+ *
+ */
+package jcckit;
diff --git a/src/jcckit/readme.md b/src/jcckit/readme.md
new file mode 100644
index 000000000..19b4239f5
--- /dev/null
+++ b/src/jcckit/readme.md
@@ -0,0 +1,15 @@
+> [!WARNING]
+> **Disclaimer**:
+> This file was not part of the original package.
+> It was included only on the PlantUML package to provide source citation and documentation.
+
+# Directory Documentation for `jcckit`
+
+## Description
+Internal copy of `JCCKit` _(code of Franz-Josef Elmer)_.
+
+## Credit
+- [JCCKit _(on Sourceforge)_](https://jcckit.sourceforge.net)
+
+## See more information on
+- [readme of `plantuml/jcckit`](../net/sourceforge/plantuml/jcckit/readme.md)
diff --git a/src/net/atmp/CucaDiagram.java b/src/net/atmp/CucaDiagram.java
index d13c5fda3..c91cc88d6 100644
--- a/src/net/atmp/CucaDiagram.java
+++ b/src/net/atmp/CucaDiagram.java
@@ -376,13 +376,13 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy,
// ::done
@Override
- final public void exportDiagramGraphic(UGraphic ug) {
+ final public void exportDiagramGraphic(UGraphic ug, FileFormatOption fileFormatOption) {
final CucaDiagramFileMaker maker = new CucaDiagramFileMakerSmetana(this, ug.getStringBounder());
maker.createOneGraphic(ug);
}
@Override
- final protected TextBlock getTextBlock() {
+ final protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
throw new UnsupportedOperationException();
}
diff --git a/src/net/sourceforge/plantuml/AbstractPSystem.java b/src/net/sourceforge/plantuml/AbstractPSystem.java
index abebc8b07..e45fe9f16 100644
--- a/src/net/sourceforge/plantuml/AbstractPSystem.java
+++ b/src/net/sourceforge/plantuml/AbstractPSystem.java
@@ -114,14 +114,14 @@ public abstract class AbstractPSystem implements Diagram {
}
final public String getMetadata() {
- if (source == null)
+ if (source == null)
return getVersion();
-
+
final String rawString = source.getRawString("\n");
final String plainString = source.getPlainString("\n");
- if (rawString != null && rawString.equals(plainString))
+ if (rawString != null && rawString.equals(plainString))
return rawString + BackSlash.NEWLINE + getVersion();
-
+
return rawString + BackSlash.NEWLINE + plainString + BackSlash.NEWLINE + getVersion();
}
@@ -130,9 +130,9 @@ public abstract class AbstractPSystem implements Diagram {
}
final public long seed() {
- if (source == null)
+ if (source == null)
return 42;
-
+
return getSource().seed();
}
@@ -159,9 +159,9 @@ public abstract class AbstractPSystem implements Diagram {
}
public DisplayPositionned getTitle() {
- if (source == null)
+ if (source == null)
return DisplayPositioned.single(Display.empty(), HorizontalAlignment.CENTER, VerticalAlignment.TOP);
-
+
return DisplayPositioned.single(source.getTitle(), HorizontalAlignment.CENTER, VerticalAlignment.TOP);
}
@@ -247,7 +247,7 @@ public abstract class AbstractPSystem implements Diagram {
}
@Override
- public void exportDiagramGraphic(UGraphic ug) {
+ public void exportDiagramGraphic(UGraphic ug, FileFormatOption fileFormatOption) {
final UFont font = UFont.monospaced(14);
final FontConfiguration fc = FontConfiguration.blackBlueTrue(font);
final UText text = UText.build("Not implemented yet for " + getClass().getName(), fc);
diff --git a/src/net/sourceforge/plantuml/AnnotatedBuilder.java b/src/net/sourceforge/plantuml/AnnotatedBuilder.java
index 5b539e082..719d20fa4 100644
--- a/src/net/sourceforge/plantuml/AnnotatedBuilder.java
+++ b/src/net/sourceforge/plantuml/AnnotatedBuilder.java
@@ -40,6 +40,7 @@ import net.sourceforge.plantuml.abel.DisplayPositioned;
import net.sourceforge.plantuml.activitydiagram3.ftile.EntityImageLegend;
import net.sourceforge.plantuml.cucadiagram.DisplaySection;
import net.sourceforge.plantuml.klimt.Fashion;
+import net.sourceforge.plantuml.klimt.LineBreakStrategy;
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.color.HColor;
import net.sourceforge.plantuml.klimt.creole.Display;
@@ -167,7 +168,7 @@ public class AnnotatedBuilder {
final Style style = StyleSignatureBasic.of(SName.root, SName.document, SName.title)
.getMergedStyle(skinParam.getCurrentStyleBuilder());
final TextBlock block = style.createTextBlockBordered(title.getDisplay(), skinParam.getIHtmlColorSet(),
- skinParam, Style.ID_TITLE);
+ skinParam, Style.ID_TITLE, LineBreakStrategy.NONE);
return block;
}
@@ -179,7 +180,7 @@ public class AnnotatedBuilder {
final Style style = StyleSignatureBasic.of(SName.root, SName.document, SName.caption)
.getMergedStyle(skinParam.getCurrentStyleBuilder());
return style.createTextBlockBordered(caption.getDisplay(), skinParam.getIHtmlColorSet(), skinParam,
- Style.ID_CAPTION);
+ Style.ID_CAPTION, LineBreakStrategy.NONE);
}
diff --git a/src/net/sourceforge/plantuml/BlockUml.java b/src/net/sourceforge/plantuml/BlockUml.java
index 9a4229bad..b5c6b76c7 100644
--- a/src/net/sourceforge/plantuml/BlockUml.java
+++ b/src/net/sourceforge/plantuml/BlockUml.java
@@ -143,7 +143,7 @@ public class BlockUml {
this.data = new ArrayList<>(strings);
} else {
final TimLoader timLoader = new TimLoader(mode.getImportedFiles(), defines, charset,
- (DefinitionsContainer) mode);
+ (DefinitionsContainer) mode, strings.get(0));
this.included.addAll(timLoader.load(strings));
this.data = timLoader.getResultList();
this.debug = timLoader.getDebug();
diff --git a/src/net/sourceforge/plantuml/EmbeddedDiagram.java b/src/net/sourceforge/plantuml/EmbeddedDiagram.java
index 9543cdd91..6cdd7abed 100644
--- a/src/net/sourceforge/plantuml/EmbeddedDiagram.java
+++ b/src/net/sourceforge/plantuml/EmbeddedDiagram.java
@@ -119,6 +119,9 @@ public class EmbeddedDiagram extends AbstractTextBlock implements Line, Atom {
if (s.equals(EMBEDDED_START + "files"))
return "files";
+ if (s.equals(EMBEDDED_START + "chronology"))
+ return "chronology";
+
return null;
}
diff --git a/src/net/sourceforge/plantuml/Option.java b/src/net/sourceforge/plantuml/Option.java
index 2f1db45a0..cf810f740 100644
--- a/src/net/sourceforge/plantuml/Option.java
+++ b/src/net/sourceforge/plantuml/Option.java
@@ -112,6 +112,9 @@ public class Option {
private FileFormatOption fileFormatOption = new FileFormatOption(FileFormat.PNG);
+ /**
+ * @deprecated Use {@link #setFileFormatOption(FileFormatOption)} instead
+ */
@Deprecated
@ApiWarning(willBeRemoved = "in next major release")
final public void setFileFormat(FileFormat fileFormat) {
@@ -440,9 +443,11 @@ public class Option {
} else if (s.equalsIgnoreCase("-preproc")) {
preprocessorOutput = OptionPreprocOutputMode.NORMAL;
+ setFileFormatOption(new FileFormatOption(FileFormat.PREPROC));
} else if (s.equalsIgnoreCase("-cypher")) {
preprocessorOutput = OptionPreprocOutputMode.CYPHER;
+ setFileFormatOption(new FileFormatOption(FileFormat.PREPROC));
} else if (s.equalsIgnoreCase("-checkmetadata")) {
checkMetadata = true;
diff --git a/src/net/sourceforge/plantuml/OptionPrint.java b/src/net/sourceforge/plantuml/OptionPrint.java
index df6938de7..984b8db51 100644
--- a/src/net/sourceforge/plantuml/OptionPrint.java
+++ b/src/net/sourceforge/plantuml/OptionPrint.java
@@ -85,83 +85,77 @@ public class OptionPrint {
System.out.println("\t?\tone and only one character but '" + SFile.separator + "'");
System.out.println("\t**\tmeans any characters (used to recurse through directories)");
System.out.println();
- System.out.println("where options include:");
- System.out.println(" -darkmode\t\tTo use dark mode for diagrams");
- System.out.println(" -gui\t\tTo run the graphical user interface");
- System.out.println(" -tpng\t\tTo generate images using PNG format (default)");
- System.out.println(" -tsvg\t\tTo generate images using SVG format");
- System.out.println(" -teps\t\tTo generate images using EPS format");
- System.out.println(" -tpdf\t\tTo generate images using PDF format");
- System.out.println(" -tvdx\t\tTo generate images using VDX format");
- System.out.println(" -txmi\t\tTo generate XMI file for class diagram");
- System.out.println(" -tscxml\t\tTo generate SCXML file for state diagram");
- System.out.println(" -thtml\t\tTo generate HTML file for class diagram");
- System.out.println(" -ttxt\t\tTo generate images with ASCII art");
- System.out.println(" -tutxt\t\tTo generate images with ASCII art using Unicode characters");
- System.out.println(" -tlatex\t\tTo generate images using LaTeX/Tikz format");
- System.out.println(" -tlatex:nopreamble\tTo generate images using LaTeX/Tikz format without preamble");
- System.out.println(" -o[utput] \"dir\"\tTo generate images in the specified directory");
- System.out.println(" -DVAR1=value\tTo set a preprocessing variable as if '!define VAR1 value' were used");
- System.out.println(" -Sparam1=value\tTo set a skin parameter as if 'skinparam param1 value' were used");
- System.out.println(" -Ppragma1=value\tTo set pragma as if '!pragma pragma1 value' were used");
- // System.out.println(" -config \"file\"\tTo read the provided config file
- // before each diagram");
final char separator = SFile.separatorChar;
- System.out.println(" -I" + separator + "path" + separator + "to" + separator
- + "file\tTo include file as if '!include file' were used");
- System.out.println(
- " -I" + separator + "path" + separator + "to" + separator + "*.puml\tTo include files with pattern");
- System.out.println(" -theme xxx\t\tTo use a specific theme");
- System.out.println(" -charset xxx\tTo use a specific charset (default is " + charset + ")");
- System.out.println(" -e[x]clude pattern\tTo exclude files that match the provided pattern");
- System.out.println(" -metadata\t\tTo retrieve PlantUML sources from PNG images");
- System.out.println(" -nometadata\t\tTo NOT export metadata in PNG/SVG generated files");
+ System.out.println("where options include:");
+ System.out.println(" -author[s]\t\tTo print information about PlantUML authors");
System.out.println(" -checkmetadata\t\tSkip PNG files that don't need to be regenerated");
- System.out.println(" -version\t\tTo display information about PlantUML and Java versions");
- System.out.println(" -v[erbose]\t\tTo have log information");
- System.out.println(" -quiet\t\tTo NOT print error message into the console");
- System.out.println(" -debugsvek\t\tTo generate intermediate svek files");
- System.out.println(" -h[elp]\t\tTo display this help message");
- System.out.println(" -testdot\t\tTo test the installation of graphviz");
- System.out.println(" -graphvizdot \"exe\"\tTo specify dot executable");
- System.out.println(" -p[ipe]\t\tTo use stdin for PlantUML source and stdout for PNG/SVG/EPS generation");
- System.out.println(
- " -encodesprite 4|8|16[z] \"file\"\tTo encode a sprite at gray level (z for compression) from an image");
- System.out.println(" -computeurl|-encodeurl\tTo compute the encoded URL of a PlantUML source file");
- System.out.println(" -decodeurl\t\tTo retrieve the PlantUML source from an encoded URL");
- System.out.println(" -syntax\t\tTo report any syntax error from standard input without generating images");
- System.out.println(" -language\t\tTo print the list of PlantUML keywords");
- // System.out.println(" -nosuggestengine\tTo disable the suggest engine when
- // errors in diagrams");
System.out.println(" -checkonly\t\tTo check the syntax of files without generating images");
+ System.out.println(" -charset xxx\tTo use a specific charset (default is " + charset + ")");
+ System.out.println(" -computeurl|-encodeurl\tTo compute the encoded URL of a PlantUML source file");
+ // System.out.println(" -config \"file\"\tTo read the provided config file
+ System.out.println(" -cypher\t\tTo cypher texts of diagrams so that you can share them");
+ System.out.println(" -DVAR1=value\tTo set a preprocessing variable as if '!define VAR1 value' were used");
+ System.out.println(" -darkmode\t\tTo use dark mode for diagrams");
+ System.out.println(" -debugsvek\t\tTo generate intermediate svek files");
+ System.out.println(" -decodeurl\t\tTo retrieve the PlantUML source from an encoded URL");
+ System.out.println(" -disablestats\tTo disable statistics computation (default)");
+ System.out.println(" -duration\t\tTo print the duration of complete diagrams processing");
+ System.out.println(" -e[x]clude pattern\tTo exclude files that match the provided pattern");
+ System.out.println(" -enablestats\tTo enable statistics computation");
+ System.out.println(" -encodesprite 4|8|16[z] \"file\"\tTo encode a sprite at gray level (z for compression) from an image");
+ System.out.println(" -extractstdlib\tTo extract PlantUML Standard Library into stdlib folder");
System.out.println(" -failfast\t\tTo stop processing as soon as a syntax error in diagram occurs");
System.out.println(" -failfast2\t\tTo do a first syntax check before processing files, to fail even faster");
- System.out.println(" -noerror\t\tTo skip images when error in diagrams");
- System.out.println(" -duration\t\tTo print the duration of complete diagrams processing");
+ System.out.println(" -filedir xxx\tTo behave as if the PlantUML source is in this dir (only affects '-pipe' and PicoWeb 'POST /render')");
+ System.out.println(" -filename \"example.puml\"\tTo override %filename% variable");
+ System.out.println(" -graphvizdot \"exe\"\tTo specify dot executable");
+ System.out.println(" -gui\t\tTo run the graphical user interface");
+ System.out.println(" -h[elp]\t\tTo display this help message");
+ System.out.println(" -htmlstats\t\tTo output general statistics in file plantuml-stats.html");
+ System.out.println(" -I" + separator + "path" + separator + "to" + separator + "file\tTo include file as if '!include file' were used");
+ System.out.println(" -I" + separator + "path" + separator + "to" + separator + "*.puml\tTo include files with pattern");
+ System.out.println(" -language\t\tTo print the list of PlantUML keywords");
+ System.out.println(" -loopstats\t\tTo continuously print statistics about usage");
+ System.out.println(" -metadata\t\tTo retrieve PlantUML sources from PNG images");
System.out.println(" -nbthread N\t\tTo use (N) threads for processing");
System.out.println(" -nbthread auto\tTo use " + Option.defaultNbThreads() + " threads for processing");
- System.out
- .println(" -timeout N\t\tProcessing timeout in (N) seconds. Defaults to 15 minutes (900 seconds).");
- System.out.println(" -author[s]\t\tTo print information about PlantUML authors");
+ System.out.println(" -noerror\t\tTo skip images when error in diagrams");
+ System.out.println(" -nometadata\t\tTo NOT export metadata in PNG/SVG generated files");
+ System.out.println(" -o[utput] \"dir\"\tTo generate images in the specified directory");
System.out.println(" -overwrite\t\tTo allow to overwrite read only files");
- System.out.println(" -printfonts\t\tTo print fonts available on your system");
- System.out.println(" -enablestats\tTo enable statistics computation");
- System.out.println(" -disablestats\tTo disable statistics computation (default)");
- System.out.println(" -htmlstats\t\tTo output general statistics in file plantuml-stats.html");
- System.out.println(" -xmlstats\t\tTo output general statistics in file plantuml-stats.xml");
- System.out.println(" -realtimestats\tTo generate statistics on the fly rather than at the end");
- System.out.println(" -loopstats\t\tTo continuously print statistics about usage");
- System.out.println(" -splash\t\tTo display a splash screen with some progress bar");
- System.out.println(" -progress\t\tTo display a textual progress bar in console");
- System.out.println(" -pipeimageindex N\tTo generate the Nth image with pipe option");
- System.out.println(" -stdlib\t\tTo print standard library info");
- System.out.println(" -extractstdlib\tTo extract PlantUML Standard Library into stdlib folder");
- System.out.println(
- " -filedir xxx\tTo behave as if the PlantUML source is in this dir (only affects '-pipe' and PicoWeb 'POST /render')");
- System.out.println(" -filename \"example.puml\"\tTo override %filename% variable");
- System.out.println(" -preproc\t\tTo output preprocessor text of diagrams");
- System.out.println(" -cypher\t\tTo cypher texts of diagrams so that you can share them");
+ System.out.println(" -Ppragma1=value\tTo set pragma as if '!pragma pragma1 value' were used");
+ System.out.println(" -p[ipe]\t\tTo use stdin for PlantUML source and stdout for PNG/SVG/EPS generation");
System.out.println(" -picoweb\t\tTo start internal HTTP Server. See https://plantuml.com/picoweb");
+ System.out.println(" -pipeimageindex N\tTo generate the Nth image with pipe option");
+ System.out.println(" -preproc\t\tTo output preprocessor text of diagrams");
+ System.out.println(" -printfonts\t\tTo print fonts available on your system");
+ System.out.println(" -progress\t\tTo display a textual progress bar in console");
+ System.out.println(" -quiet\t\tTo NOT print error message into the console");
+ System.out.println(" -realtimestats\tTo generate statistics on the fly rather than at the end");
+ System.out.println(" -Sparam1=value\tTo set a skin parameter as if 'skinparam param1 value' were used");
+ System.out.println(" -splash\t\tTo display a splash screen with some progress bar");
+ System.out.println(" -stdlib\t\tTo print standard library info");
+ System.out.println(" -syntax\t\tTo report any syntax error from standard input without generating images");
+ System.out.println(" -testdot\t\tTo test the installation of graphviz");
+ System.out.println(" -theme xxx\t\tTo use a specific theme");
+ System.out.println(" -timeout N\t\tProcessing timeout in (N) seconds. Defaults to 15 minutes (900 seconds).");
+ System.out.println(" -teps\t\tTo generate images using EPS format");
+ System.out.println(" -testdot\t\tTo test the installation of graphviz");
+ System.out.println(" -theme xxx\t\tTo use a specific theme");
+ System.out.println(" -thtml\t\tTo generate HTML file for class diagram");
+ System.out.println(" -tlatex:nopreamble\tTo generate images using LaTeX/Tikz format without preamble");
+ System.out.println(" -tlatex\t\tTo generate images using LaTeX/Tikz format");
+ System.out.println(" -tpdf\t\tTo generate images using PDF format");
+ System.out.println(" -tpng\t\tTo generate images using PNG format (default)");
+ System.out.println(" -tscxml\t\tTo generate SCXML file for state diagram");
+ System.out.println(" -tsvg\t\tTo generate images using SVG format");
+ System.out.println(" -ttxt\t\tTo generate images with ASCII art");
+ System.out.println(" -tutxt\t\tTo generate images with ASCII art using Unicode characters");
+ System.out.println(" -tvdx\t\tTo generate images using VDX format");
+ System.out.println(" -txmi\t\tTo generate XMI file for class diagram");
+ System.out.println(" -v[erbose]\t\tTo have log information");
+ System.out.println(" -version\t\tTo display information about PlantUML and Java versions");
+ System.out.println(" -xmlstats\t\tTo output general statistics in file plantuml-stats.xml");
System.out.println();
System.out.println("If needed, you can setup the environment variable GRAPHVIZ_DOT.");
exit(0);
diff --git a/src/net/sourceforge/plantuml/PSystemBuilder.java b/src/net/sourceforge/plantuml/PSystemBuilder.java
index 4838270f2..66b642108 100644
--- a/src/net/sourceforge/plantuml/PSystemBuilder.java
+++ b/src/net/sourceforge/plantuml/PSystemBuilder.java
@@ -49,6 +49,7 @@ import net.sourceforge.plantuml.api.PSystemFactory;
import net.sourceforge.plantuml.board.BoardDiagramFactory;
import net.sourceforge.plantuml.bpm.BpmDiagramFactory;
import net.sourceforge.plantuml.cheneer.ChenEerDiagramFactory;
+import net.sourceforge.plantuml.chronology.ChronologyDiagramFactory;
import net.sourceforge.plantuml.classdiagram.ClassDiagramFactory;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.core.DiagramType;
@@ -253,6 +254,7 @@ public class PSystemBuilder {
// ::done
factories.add(new GanttDiagramFactory());
+ factories.add(new ChronologyDiagramFactory());
factories.add(new FlowDiagramFactory());
// ::comment when __CORE__
diff --git a/src/net/sourceforge/plantuml/PlainDiagram.java b/src/net/sourceforge/plantuml/PlainDiagram.java
index 7945b7feb..88385e9e5 100644
--- a/src/net/sourceforge/plantuml/PlainDiagram.java
+++ b/src/net/sourceforge/plantuml/PlainDiagram.java
@@ -66,14 +66,13 @@ public abstract class PlainDiagram extends AbstractPSystem {
}
@Override
- public void exportDiagramGraphic(UGraphic ug) {
- final FileFormatOption option = new FileFormatOption(FileFormat.PNG);
+ public void exportDiagramGraphic(UGraphic ug, FileFormatOption fileFormatOption) {
try {
- final UDrawable rootDrawable = getRootDrawable(option);
+ final UDrawable rootDrawable = getRootDrawable(fileFormatOption);
rootDrawable.drawU(ug);
} catch (IOException e) {
e.printStackTrace();
- super.exportDiagramGraphic(ug);
+ super.exportDiagramGraphic(ug, fileFormatOption);
}
}
diff --git a/src/net/sourceforge/plantuml/SourceStringReader.java b/src/net/sourceforge/plantuml/SourceStringReader.java
index 32e7f5ace..34f9f713e 100644
--- a/src/net/sourceforge/plantuml/SourceStringReader.java
+++ b/src/net/sourceforge/plantuml/SourceStringReader.java
@@ -54,6 +54,7 @@ import net.sourceforge.plantuml.klimt.shape.GraphicStrings;
import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.preproc.Defines;
import net.sourceforge.plantuml.security.SFile;
+import net.sourceforge.plantuml.text.StringLocated;
import net.sourceforge.plantuml.utils.Log;
public class SourceStringReader {
@@ -106,6 +107,9 @@ public class SourceStringReader {
}
}
+ /**
+ * @deprecated Use {@link #outputImage(OutputStream)} instead
+ */
@Deprecated
public String generateImage(OutputStream os) throws IOException {
return outputImage(os).getDescription();
@@ -116,6 +120,9 @@ public class SourceStringReader {
}
// ::comment when __CORE__
+ /**
+ * @deprecated Use {@link #outputImage(SFile)} instead
+ */
@Deprecated
public String generateImage(SFile f) throws IOException {
return outputImage(f).getDescription();
@@ -128,6 +135,9 @@ public class SourceStringReader {
}
// ::done
+ /**
+ * @deprecated Use {@link #outputImage(OutputStream, FileFormatOption)} instead
+ */
@Deprecated
public String generateImage(OutputStream os, FileFormatOption fileFormatOption) throws IOException {
return outputImage(os, fileFormatOption).getDescription();
@@ -137,6 +147,9 @@ public class SourceStringReader {
return outputImage(os, 0, fileFormatOption);
}
+ /**
+ * @deprecated Use {@link #outputImage(OutputStream, int)} instead
+ */
@Deprecated
public String generateImage(OutputStream os, int numImage) throws IOException {
return outputImage(os, numImage).getDescription();
@@ -146,6 +159,9 @@ public class SourceStringReader {
return outputImage(os, numImage, new FileFormatOption(FileFormat.PNG));
}
+ /**
+ * @deprecated Use {@link #outputImage(OutputStream, int, FileFormatOption)} instead
+ */
@Deprecated
public String generateImage(OutputStream os, int numImage, FileFormatOption fileFormatOption) throws IOException {
return outputImage(os, numImage, fileFormatOption).getDescription();
@@ -157,6 +173,14 @@ public class SourceStringReader {
noValidStartFound(os, fileFormatOption);
return null;
}
+ if (fileFormatOption.getFileFormat() == FileFormat.PREPROC) {
+ final BlockUml first = blocks.get(0);
+ for (StringLocated s : first.getData()) {
+ os.write(s.getString().getBytes(UTF_8));
+ os.write("\n".getBytes(UTF_8));
+ }
+ return new DiagramDescription("PREPROC");
+ }
for (BlockUml b : blocks) {
final Diagram system = b.getDiagram();
final int nbInSystem = system.getNbImages();
@@ -231,7 +255,8 @@ public class SourceStringReader {
}
public ImageData noValidStartFound(OutputStream os, FileFormatOption fileFormatOption) throws IOException {
- final TextBlock error = GraphicStrings.createForError(Arrays.asList("No valid @start/@end found, please check the version"),
+ final TextBlock error = GraphicStrings.createForError(
+ Arrays.asList("No valid @start/@end found, please check the version"),
fileFormatOption.isUseRedForError());
return plainImageBuilder(error, fileFormatOption).write(os);
diff --git a/src/net/sourceforge/plantuml/TitledDiagram.java b/src/net/sourceforge/plantuml/TitledDiagram.java
index f5faeba59..9f365f86c 100644
--- a/src/net/sourceforge/plantuml/TitledDiagram.java
+++ b/src/net/sourceforge/plantuml/TitledDiagram.java
@@ -253,11 +253,11 @@ public abstract class TitledDiagram extends AbstractPSystem implements Diagram,
}
- protected abstract TextBlock getTextBlock();
+ protected abstract TextBlock getTextMainBlock(FileFormatOption fileFormatOption);
@Override
- public void exportDiagramGraphic(UGraphic ug) {
- final TextBlock textBlock = getTextBlock();
+ public void exportDiagramGraphic(UGraphic ug, FileFormatOption fileFormatOption) {
+ final TextBlock textBlock = getTextMainBlock(fileFormatOption);
textBlock.drawU(ug);
}
diff --git a/src/net/sourceforge/plantuml/acearth/PSystemXearth.java b/src/net/sourceforge/plantuml/acearth/PSystemXearth.java
index a809b3719..15df082ce 100644
--- a/src/net/sourceforge/plantuml/acearth/PSystemXearth.java
+++ b/src/net/sourceforge/plantuml/acearth/PSystemXearth.java
@@ -47,9 +47,9 @@ import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
-import ext.plantuml.com.ctreber.acearth.ACearth;
-import ext.plantuml.com.ctreber.acearth.ConfigurationACearth;
-import ext.plantuml.com.ctreber.acearth.plugins.markers.Marker;
+import zext.plantuml.com.ctreber.acearth.ACearth;
+import zext.plantuml.com.ctreber.acearth.ConfigurationACearth;
+import zext.plantuml.com.ctreber.acearth.plugins.markers.Marker;
import net.sourceforge.plantuml.AbstractPSystem;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.api.ImageDataSimple;
diff --git a/src/net/sourceforge/plantuml/acearth/PSystemXearthFactory.java b/src/net/sourceforge/plantuml/acearth/PSystemXearthFactory.java
index aa19bba56..d7a8e9ad9 100644
--- a/src/net/sourceforge/plantuml/acearth/PSystemXearthFactory.java
+++ b/src/net/sourceforge/plantuml/acearth/PSystemXearthFactory.java
@@ -40,7 +40,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import ext.plantuml.com.ctreber.acearth.plugins.markers.Marker;
+import zext.plantuml.com.ctreber.acearth.plugins.markers.Marker;
import net.sourceforge.plantuml.command.PSystemBasicFactory;
import net.sourceforge.plantuml.core.UmlSource;
import net.sourceforge.plantuml.log.Logme;
diff --git a/src/net/sourceforge/plantuml/acearth/package-info.java b/src/net/sourceforge/plantuml/acearth/package-info.java
index ff8536d87..26683cf61 100644
--- a/src/net/sourceforge/plantuml/acearth/package-info.java
+++ b/src/net/sourceforge/plantuml/acearth/package-info.java
@@ -3,6 +3,6 @@
*
* XEarth Image.
*
- * @see ext.plantuml.com.ctreber.acearth
+ * @see zext.plantuml.com.ctreber.acearth
*/
package net.sourceforge.plantuml.acearth;
diff --git a/src/net/sourceforge/plantuml/acearth/readme.md b/src/net/sourceforge/plantuml/acearth/readme.md
index a369bb7a5..e5d8f1c1a 100644
--- a/src/net/sourceforge/plantuml/acearth/readme.md
+++ b/src/net/sourceforge/plantuml/acearth/readme.md
@@ -3,7 +3,7 @@
## Description
This package provides classes used to generate [XEarth Image](https://plantuml.com/xearth).
-The Java port of `XEarth` used in `PlantUML` is the [`AC.earth` of Christian Treber](../../../../ext/plantuml/com/ctreber/acearth/).
+The Java port of `XEarth` used in `PlantUML` is the [`AC.earth` of Christian Treber](../../../../zext/plantuml/com/ctreber/acearth/).
## Link
- [XEarth Image _(on `PlantUML`)_](https://plantuml.com/xearth)
@@ -13,7 +13,7 @@ The Java port of `XEarth` used in `PlantUML` is the [`AC.earth` of Christian Tre
- [`xearth` for Windows of Greg Hewgill](https://hewgill.com/xearth/)
## Credit
-- [`AC.earth` of Christian Treber](../../../../ext/plantuml/com/ctreber/acearth/)
+- [`AC.earth` of Christian Treber](../../../../zext/plantuml/com/ctreber/acearth/)
- [AC Earth _(on Web Archive)_](https://web.archive.org/web/20180428011447/http://www.acproductions.de/acearth)
## Misc.
diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java
index 6daa6844e..143b3225d 100644
--- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java
+++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java
@@ -61,6 +61,7 @@ import net.sourceforge.plantuml.regex.RegexOr;
import net.sourceforge.plantuml.regex.RegexPartialMatch;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -81,9 +82,7 @@ public class CommandLinkActivity extends SingleLineCommand2 {
new RegexLeaf("CODE", "([%pLN][%pLN_.]*)"), //
new RegexLeaf("BAR", "(?:==+)[%s]*([%pLN_.]+)[%s]*(?:==+)"), //
new RegexLeaf("QUOTED", "[%g]([^%g]+)[%g](?:[%s]+as[%s]+([%pLN_.]+))?"))), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE"), //
ColorParser.exp2(), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
@@ -105,9 +104,7 @@ public class CommandLinkActivity extends SingleLineCommand2 {
new RegexLeaf("BAR2", "(?:==+)[%s]*([%pLN_.]+)[%s]*(?:==+)"), //
new RegexLeaf("QUOTED2", "[%g]([^%g]+)[%g](?:[%s]+as[%s]+([%pLN][%pLN_.]*))?"), //
new RegexLeaf("QUOTED_INVISIBLE2", "(\\w.*?)")), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE2", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE2"), //
new RegexOptional( //
new RegexConcat( //
new RegexLeaf("in"), //
diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java
index 4e008bac8..75d2551e1 100644
--- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java
+++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java
@@ -64,6 +64,7 @@ import net.sourceforge.plantuml.regex.RegexOptional;
import net.sourceforge.plantuml.regex.RegexOr;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.text.BackSlash;
import net.sourceforge.plantuml.text.StringLocated;
import net.sourceforge.plantuml.url.Url;
@@ -91,9 +92,7 @@ public class CommandLinkLongActivity extends CommandMultilines2
new RegexLeaf("CODE", "([%pLN][%pLN_.]*)"), //
new RegexLeaf("BAR", "(?:==+)[%s]*([%pLN_.]+)[%s]*(?:==+)"), //
new RegexLeaf("QUOTED", "[%g]([^%g]+)[%g](?:[%s]+as[%s]+([%pLN_.]+))?"))), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE"), //
new RegexLeaf("BACKCOLOR", "(#\\w+)?"), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java
index 488cff81b..cef3f0753 100644
--- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java
+++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java
@@ -52,6 +52,7 @@ import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexOr;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.utils.LineLocation;
public class CommandPartition extends SingleLineCommand2 {
@@ -69,9 +70,7 @@ public class CommandPartition extends SingleLineCommand2 {
new RegexOr(//
color().getRegex(), //
new RegexLeaf("LEGACYCOLORIGNORED", "(#[0-9a-fA-F]{6}|#?\\w+)?")), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE"), //
new RegexLeaf("\\{?"), //
RegexLeaf.end());
}
@@ -89,12 +88,10 @@ public class CommandPartition extends SingleLineCommand2 {
final Entity p = diagram.getCurrentGroup();
final Colors colors = color().getColor(arg, diagram.getSkinParam().getIHtmlColorSet());
- if (colors.isEmpty() == false) {
+ if (colors.isEmpty() == false)
p.setColors(colors);
- }
- if (arg.get("STEREOTYPE", 0) != null) {
- p.setStereotype(Stereotype.build(arg.get("STEREOTYPE", 0)));
- }
+
+ p.setStereotype(Stereotype.build(arg.get("STEREOTYPE", 0)));
return CommandExecutionResult.ok();
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java
index 009bed4dc..281e6c6ce 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java
@@ -40,7 +40,6 @@ import java.io.OutputStream;
import java.util.Map;
import java.util.Objects;
-import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.UmlDiagram;
import net.sourceforge.plantuml.activitydiagram3.ftile.BoxStyle;
@@ -109,11 +108,11 @@ public class ActivityDiagram3 extends UmlDiagram {
return swinlanes.nextLinkRenderer();
}
- public CommandExecutionResult addActivity(Display activity, BoxStyle style, Url url, Colors colors,
+ public CommandExecutionResult addActivity(Display activity, BoxStyle boxStyle, Url url, Colors colors,
Stereotype stereotype) {
manageSwimlaneStrategy();
final InstructionSimple ins = new InstructionSimple(activity, nextLinkRenderer(),
- swinlanes.getCurrentSwimlane(), style, url, colors, stereotype);
+ swinlanes.getCurrentSwimlane(), boxStyle, url, colors, stereotype);
final CommandExecutionResult added = current().add(ins);
if (added.isOk() == false)
return added;
@@ -208,8 +207,7 @@ public class ActivityDiagram3 extends UmlDiagram {
}
@Override
- protected TextBlock getTextBlock() {
- final FileFormatOption fileFormatOption = new FileFormatOption(FileFormat.PNG);
+ protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
final StringBounder stringBounder = fileFormatOption.getDefaultStringBounder(getSkinParam());
return getTextBlock(stringBounder);
}
@@ -318,10 +316,10 @@ public class ActivityDiagram3 extends UmlDiagram {
return CommandExecutionResult.error("Cannot find switch");
}
- public void startIf(Display test, Display whenThen, HColor color, Url url) {
+ public void startIf(Display test, Display whenThen, HColor color, Url url, Stereotype stereotype) {
manageSwimlaneStrategy();
final InstructionIf instructionIf = new InstructionIf(swinlanes.getCurrentSwimlane(), current(), test,
- LinkRendering.none().withDisplay(whenThen), nextLinkRenderer(), color, getSkinParam(), url);
+ LinkRendering.none().withDisplay(whenThen), nextLinkRenderer(), color, getSkinParam(), url, stereotype);
current().add(instructionIf);
setNextLinkRendererInternal(LinkRendering.none());
setCurrent(instructionIf);
@@ -392,12 +390,13 @@ public class ActivityDiagram3 extends UmlDiagram {
manageSwimlaneStrategy();
if (current() instanceof InstructionRepeat) {
final InstructionRepeat instructionRepeat = (InstructionRepeat) current();
- instructionRepeat.setBackward(label, swinlanes.getCurrentSwimlane(), boxStyle, incoming1, incoming2, stereotype);
+ instructionRepeat.setBackward(label, swinlanes.getCurrentSwimlane(), boxStyle, incoming1, incoming2,
+ stereotype);
return CommandExecutionResult.ok();
}
if (current() instanceof InstructionWhile) {
final InstructionWhile instructionWhile = (InstructionWhile) current();
- instructionWhile.setBackward(label, swinlanes.getCurrentSwimlane(), boxStyle, incoming1, incoming2);
+ instructionWhile.setBackward(label, boxStyle, incoming1, incoming2, stereotype);
return CommandExecutionResult.ok();
}
return CommandExecutionResult.error("Cannot find repeat");
@@ -407,7 +406,7 @@ public class ActivityDiagram3 extends UmlDiagram {
public void doWhile(Display test, Display yes, HColor color) {
manageSwimlaneStrategy();
final InstructionWhile instructionWhile = new InstructionWhile(swinlanes.getCurrentSwimlane(), current(), test,
- nextLinkRenderer(), yes, color, getSkinParam());
+ nextLinkRenderer(), yes, color, getSkinParam().getCurrentStyleBuilder());
current().add(instructionWhile);
setCurrent(instructionWhile);
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/Branch.java b/src/net/sourceforge/plantuml/activitydiagram3/Branch.java
index 0a25a1dc9..35270db4d 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/Branch.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/Branch.java
@@ -57,6 +57,7 @@ import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.klimt.shape.TextBlockUtils;
import net.sourceforge.plantuml.sequencediagram.NotePosition;
import net.sourceforge.plantuml.sequencediagram.NoteType;
+import net.sourceforge.plantuml.stereo.Stereotype;
import net.sourceforge.plantuml.style.ISkinParam;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName;
@@ -95,12 +96,12 @@ public class Branch {
}
public Branch(StyleBuilder styleBuilder, Swimlane swimlane, LinkRendering labelPositive, Display labelTest,
- HColor color, LinkRendering inlabel) {
+ HColor color, LinkRendering inlabel, Stereotype stereotype) {
this.inlabel = Objects.requireNonNull(inlabel);
this.labelTest = Objects.requireNonNull(labelTest);
this.labelPositive = Objects.requireNonNull(labelPositive);
- final Style style = getDefaultStyleDefinitionDiamond().getMergedStyle(styleBuilder);
+ final Style style = getDefaultStyleDefinitionDiamond().withTOBECHANGED(stereotype).getMergedStyle(styleBuilder);
this.color = color == null
? style.value(PName.BackGroundColor).asColor(styleBuilder.getSkinParam().getIHtmlColorSet())
: color;
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionIf.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionIf.java
index 23ddbae23..49e136308 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionIf.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionIf.java
@@ -47,7 +47,6 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.FtileDecorateWelding;
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileFactory;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
import net.sourceforge.plantuml.activitydiagram3.ftile.WeldingPoint;
-import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.FtileWithNoteOpale;
import net.sourceforge.plantuml.activitydiagram3.gtile.Gtile;
import net.sourceforge.plantuml.activitydiagram3.gtile.GtileIfAlone;
import net.sourceforge.plantuml.activitydiagram3.gtile.GtileIfHexagon;
@@ -56,10 +55,11 @@ import net.sourceforge.plantuml.klimt.color.Colors;
import net.sourceforge.plantuml.klimt.color.HColor;
import net.sourceforge.plantuml.klimt.creole.Display;
import net.sourceforge.plantuml.klimt.font.StringBounder;
-import net.sourceforge.plantuml.klimt.geom.VerticalAlignment;
import net.sourceforge.plantuml.sequencediagram.NotePosition;
import net.sourceforge.plantuml.sequencediagram.NoteType;
+import net.sourceforge.plantuml.stereo.Stereotype;
import net.sourceforge.plantuml.style.ISkinParam;
+import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.url.Url;
public class InstructionIf extends WithNote implements Instruction, InstructionCollection {
@@ -75,8 +75,10 @@ public class InstructionIf extends WithNote implements Instruction, InstructionC
private Branch current;
private final LinkRendering topInlinkRendering;
private LinkRendering outColor = LinkRendering.none();
+ private final Stereotype stereotype;
private final Swimlane swimlane;
+ private final StyleBuilder currentStyleBuilder;
@Override
public boolean containsBreak() {
@@ -91,14 +93,16 @@ public class InstructionIf extends WithNote implements Instruction, InstructionC
}
public InstructionIf(Swimlane swimlane, Instruction parent, Display labelTest, LinkRendering whenThen,
- LinkRendering inlinkRendering, HColor color, ISkinParam skinParam, Url url) {
+ LinkRendering inlinkRendering, HColor color, ISkinParam skinParam, Url url, Stereotype stereotype) {
this.url = url;
+ this.stereotype = stereotype;
this.parent = parent;
this.skinParam = skinParam;
this.topInlinkRendering = Objects.requireNonNull(inlinkRendering);
this.swimlane = swimlane;
- this.thens.add(new Branch(skinParam.getCurrentStyleBuilder(), swimlane, whenThen, labelTest, color,
- LinkRendering.none()));
+ this.currentStyleBuilder = skinParam.getCurrentStyleBuilder();
+ this.thens.add(new Branch(currentStyleBuilder, swimlane, whenThen, labelTest, color, LinkRendering.none(),
+ stereotype));
this.current = this.thens.get(0);
}
@@ -137,12 +141,12 @@ public class InstructionIf extends WithNote implements Instruction, InstructionC
branch.updateFtile(factory);
if (elseBranch == null)
- this.elseBranch = new Branch(skinParam.getCurrentStyleBuilder(), swimlane, LinkRendering.none(),
- Display.NULL, null, LinkRendering.none());
+ this.elseBranch = new Branch(currentStyleBuilder, swimlane, LinkRendering.none(),
+ Display.NULL, null, LinkRendering.none(), stereotype);
elseBranch.updateFtile(factory);
Ftile result = factory.createIf(swimlane, thens, elseBranch, outColor, topInlinkRendering, url,
- getPositionedNotes());
+ getPositionedNotes(), stereotype, currentStyleBuilder);
// if (getPositionedNotes().size() > 0)
// result = FtileWithNoteOpale.create(result, getPositionedNotes(), false, VerticalAlignment.CENTER);
@@ -169,7 +173,7 @@ public class InstructionIf extends WithNote implements Instruction, InstructionC
this.current.setInlinkRendering(nextLinkRenderer);
this.elseBranch = new Branch(skinParam.getCurrentStyleBuilder(), swimlane, whenElse, Display.NULL, null,
- LinkRendering.none());
+ LinkRendering.none(), stereotype);
this.current = elseBranch;
return true;
}
@@ -180,7 +184,8 @@ public class InstructionIf extends WithNote implements Instruction, InstructionC
return false;
this.current.setSpecial(nextLinkRenderer);
- this.current = new Branch(skinParam.getCurrentStyleBuilder(), swimlane, whenThen, test, color, inlabel);
+ this.current = new Branch(skinParam.getCurrentStyleBuilder(), swimlane, whenThen, test, color, inlabel,
+ stereotype);
this.thens.add(current);
return true;
@@ -190,7 +195,7 @@ public class InstructionIf extends WithNote implements Instruction, InstructionC
endifCalled = true;
if (elseBranch == null)
this.elseBranch = new Branch(skinParam.getCurrentStyleBuilder(), swimlane, LinkRendering.none(),
- Display.NULL, null, LinkRendering.none());
+ Display.NULL, null, LinkRendering.none(), stereotype);
this.elseBranch.setSpecial(nextLinkRenderer);
this.current.setInlinkRendering(nextLinkRenderer);
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java
index 7bec98e0d..d8362f656 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java
@@ -129,8 +129,13 @@ public class InstructionList extends WithNote implements Instruction, Instructio
@Override
public Ftile createFtile(FtileFactory factory) {
- if (all.size() == 0)
- return new FtileEmpty(factory.skinParam(), defaultSwimlane);
+ if (all.size() == 0) {
+ Ftile result = new FtileEmpty(factory.skinParam(), defaultSwimlane);
+ // Not a typo, in that case, we decide to decorate the entry link.
+ if (outlinkRendering != null)
+ result = factory.decorateIn(result, outlinkRendering);
+ return result;
+ }
final List breaks = new ArrayList<>();
Ftile result = eventuallyAddNote(factory, null, getSwimlaneIn(), VerticalAlignment.CENTER);
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java
index 287b84a21..1680f463f 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionRepeat.java
@@ -59,6 +59,7 @@ import net.sourceforge.plantuml.sequencediagram.NotePosition;
import net.sourceforge.plantuml.sequencediagram.NoteType;
import net.sourceforge.plantuml.stereo.Stereotype;
import net.sourceforge.plantuml.style.ISkinParam;
+import net.sourceforge.plantuml.style.StyleBuilder;
public class InstructionRepeat extends AbstractInstruction implements Instruction {
@@ -87,6 +88,7 @@ public class InstructionRepeat extends AbstractInstruction implements Instructio
private LinkRendering endRepeatLinkRendering = LinkRendering.none();
private final Colors colors;
+ private final StyleBuilder currentStyleBuilder;
public boolean containsBreak() {
return repeatList.containsBreak();
@@ -94,6 +96,7 @@ public class InstructionRepeat extends AbstractInstruction implements Instructio
public InstructionRepeat(Swimlanes swimlanes, Instruction parent, LinkRendering nextLinkRenderer, HColor color,
Display startLabel, BoxStyle boxStyleIn, Colors colors) {
+ this.currentStyleBuilder = swimlanes.getCurrentStyleBuilder();
this.swimlanes = swimlanes;
this.swimlane = swimlanes.getCurrentSwimlane();
this.repeatList = new InstructionList(this.swimlane);
@@ -158,7 +161,7 @@ public class InstructionRepeat extends AbstractInstruction implements Instructio
if (this.testCalled == false && incoming1.isNone())
incoming1 = swimlanes.nextLinkRenderer();
final Ftile result = factory.repeat(boxStyleIn, swimlane, swimlaneOut, startLabel, decorateOut, test, yes, out,
- colors, back, isLastOfTheParent(), incoming1, incoming2);
+ colors, back, isLastOfTheParent(), incoming1, incoming2, currentStyleBuilder);
if (killed)
return new FtileKilled(result);
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSimple.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSimple.java
index 901b55ce5..d6886bd0b 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSimple.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSimple.java
@@ -62,7 +62,7 @@ public class InstructionSimple extends MonoSwimable implements Instruction {
private final Display label;
private final Colors colors;
private final LinkRendering inlinkRendering;
- private final BoxStyle style;
+ private final BoxStyle boxStyle;
private final Url url;
private final Stereotype stereotype;
@@ -71,12 +71,12 @@ public class InstructionSimple extends MonoSwimable implements Instruction {
return false;
}
- public InstructionSimple(Display label, LinkRendering inlinkRendering, Swimlane swimlane, BoxStyle style, Url url,
- Colors colors, Stereotype stereotype) {
+ public InstructionSimple(Display label, LinkRendering inlinkRendering, Swimlane swimlane, BoxStyle boxStyle,
+ Url url, Colors colors, Stereotype stereotype) {
super(swimlane);
this.stereotype = stereotype;
this.url = url;
- this.style = style;
+ this.boxStyle = boxStyle;
this.label = label;
this.inlinkRendering = Objects.requireNonNull(inlinkRendering);
this.colors = Objects.requireNonNull(colors);
@@ -85,7 +85,7 @@ public class InstructionSimple extends MonoSwimable implements Instruction {
// ::comment when __CORE__
@Override
public Gtile createGtile(ISkinParam skinParam, StringBounder stringBounder) {
- GtileBox result = GtileBox.create(stringBounder, colors.mute(skinParam), label, getSwimlaneIn(), style,
+ GtileBox result = GtileBox.create(stringBounder, colors.mute(skinParam), label, getSwimlaneIn(), boxStyle,
stereotype);
if (hasNotes()) {
final Collection notes = getPositionedNotes();
@@ -103,7 +103,7 @@ public class InstructionSimple extends MonoSwimable implements Instruction {
@Override
public Ftile createFtile(FtileFactory factory) {
- Ftile result = factory.activity(label, getSwimlaneIn(), style, colors, stereotype);
+ Ftile result = factory.activity(label, getSwimlaneIn(), boxStyle, colors, stereotype);
if (url != null) {
result = factory.addUrl(result, url);
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSwitch.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSwitch.java
index 9ed4ddb98..dc9efedc6 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionSwitch.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionSwitch.java
@@ -58,7 +58,7 @@ import net.sourceforge.plantuml.sequencediagram.NoteType;
import net.sourceforge.plantuml.style.ISkinParam;
public class InstructionSwitch extends WithNote implements Instruction, InstructionCollection {
- // ::remove folder when __HAXE__
+ // ::remove folder when __HAXE__
private final List switches = new ArrayList<>();
private final ISkinParam skinParam;
@@ -166,7 +166,7 @@ public class InstructionSwitch extends WithNote implements Instruction, Instruct
this.current.setSpecial(nextLinkRenderer);
this.current = new Branch(skinParam.getCurrentStyleBuilder(), swimlane,
LinkRendering.none().withDisplay(labelCase), labelCase, null,
- LinkRendering.none().withDisplay(labelCase));
+ LinkRendering.none().withDisplay(labelCase), null);
this.switches.add(this.current);
return true;
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/InstructionWhile.java b/src/net/sourceforge/plantuml/activitydiagram3/InstructionWhile.java
index 554510da7..721f882d0 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionWhile.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionWhile.java
@@ -55,7 +55,9 @@ import net.sourceforge.plantuml.klimt.font.StringBounder;
import net.sourceforge.plantuml.klimt.geom.VerticalAlignment;
import net.sourceforge.plantuml.sequencediagram.NotePosition;
import net.sourceforge.plantuml.sequencediagram.NoteType;
+import net.sourceforge.plantuml.stereo.Stereotype;
import net.sourceforge.plantuml.style.ISkinParam;
+import net.sourceforge.plantuml.style.StyleBuilder;
public class InstructionWhile extends WithNote implements Instruction, InstructionCollection {
@@ -72,30 +74,32 @@ public class InstructionWhile extends WithNote implements Instruction, Instructi
private LinkRendering outColor = LinkRendering.none();
private final Swimlane swimlane;
- private final ISkinParam skinParam;
private Instruction specialOut;
private BoxStyle boxStyle;
- private Swimlane swimlaneOut;
+
private Display backward = Display.NULL;
+ private Stereotype stereotype;
+
private LinkRendering incoming1 = LinkRendering.none();
private LinkRendering incoming2 = LinkRendering.none();
private boolean backwardCalled;
+ private final StyleBuilder currentStyleBuilder;
public void overwriteYes(Display yes) {
this.yes = yes;
}
public InstructionWhile(Swimlane swimlane, Instruction parent, Display test, LinkRendering nextLinkRenderer,
- Display yes, HColor color, ISkinParam skinParam) {
+ Display yes, HColor color, StyleBuilder currentStyleBuilder) {
this.parent = parent;
this.test = Objects.requireNonNull(test);
this.nextLinkRenderer = Objects.requireNonNull(nextLinkRenderer);
this.yes = Objects.requireNonNull(yes);
this.swimlane = swimlane;
+ this.currentStyleBuilder = currentStyleBuilder;
this.color = color;
- this.skinParam = skinParam;
}
@Override
@@ -116,9 +120,10 @@ public class InstructionWhile extends WithNote implements Instruction, Instructi
@Override
public Ftile createFtile(FtileFactory factory) {
final Ftile back = Display.isNull(backward) ? null
- : factory.activity(backward, swimlane, boxStyle, Colors.empty(), null);
+ : factory.activity(backward, swimlane, boxStyle, Colors.empty(), stereotype);
Ftile tmp = repeatList.createFtile(factory);
- tmp = factory.createWhile(outColor, swimlane, tmp, test, yes, color, specialOut, back, incoming1, incoming2);
+ tmp = factory.createWhile(outColor, swimlane, tmp, test, yes, color, specialOut, back, incoming1, incoming2,
+ currentStyleBuilder);
if (getPositionedNotes().size() > 0)
tmp = FtileWithNoteOpale.create(tmp, getPositionedNotes(), false, VerticalAlignment.CENTER);
@@ -191,14 +196,14 @@ public class InstructionWhile extends WithNote implements Instruction, Instructi
return repeatList.containsBreak();
}
- public void setBackward(Display label, Swimlane swimlaneOut, BoxStyle boxStyle, LinkRendering incoming1,
- LinkRendering incoming2) {
+ public void setBackward(Display label, BoxStyle boxStyle, LinkRendering incoming1, LinkRendering incoming2,
+ Stereotype stereotype) {
this.backward = label;
- this.swimlaneOut = swimlaneOut;
this.boxStyle = boxStyle;
this.incoming1 = incoming1;
this.incoming2 = incoming2;
this.backwardCalled = true;
+ this.stereotype = stereotype;
}
public void incoming(LinkRendering incoming) {
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivity3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivity3.java
index 183d130ed..4a38e0c61 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivity3.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivity3.java
@@ -52,6 +52,7 @@ import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.skin.ColorParam;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -61,7 +62,7 @@ public class CommandActivity3 extends SingleLineCommand2 {
public static final String endingGroup() {
return "(" //
- + ";(?:[%s]*(\\<\\<\\w+\\>\\>))?" //
+ + ";[%s]*(\\<\\<\\w+\\>\\>(?:[%s]*\\<\\<\\w+\\>\\>)*)?" //
+ "|" //
+ Matcher.quoteReplacement("\\\\") // that is simply \ character
+ "|" //
@@ -77,7 +78,7 @@ public class CommandActivity3 extends SingleLineCommand2 {
private static final String endingGroupShort() {
return "(" //
- + ";(?:[%s]*(\\<\\<\\w+\\>\\>))?" //
+ + ";[%s]*(\\<\\<\\w+\\>\\>(?:[%s]*\\<\\<\\w+\\>\\>)*)?" //
+ "|" //
+ Matcher.quoteReplacement("\\\\") // that is simply \ character
+ "|" //
@@ -104,9 +105,7 @@ public class CommandActivity3 extends SingleLineCommand2 {
return RegexConcat.build(CommandActivity3.class.getName(), RegexLeaf.start(), //
UrlBuilder.OPTIONAL, //
color().getRegex(), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
new RegexLeaf(":"), //
new RegexLeaf("LABEL", "(.*?)"), //
new RegexLeaf("STYLE", endingGroupShort()), //
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java
index 397f6f977..530e1f43e 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java
@@ -49,6 +49,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
+import net.sourceforge.plantuml.stereo.Stereotype;
import net.sourceforge.plantuml.utils.BlocLines;
public class CommandActivityLong3 extends CommandMultilines3 {
@@ -84,10 +85,16 @@ public class CommandActivityLong3 extends CommandMultilines3 {
final Colors colors = color().getColor(line0, diagram.getSkinParam().getIHtmlColorSet());
final RegexResult lineLast = getPatternEnd2().matcher(lines.getLast().getString());
+
final String end = lineLast.get("END", 0);
+ Stereotype stereotype = null;
+ String stereo = lineLast.get("END", 1);
+ if (stereo != null)
+ stereotype = Stereotype.build(stereo);
+
final BoxStyle style = BoxStyle.fromString(end);
lines = lines.removeStartingAndEnding(line0.get("DATA", 0), end.length());
- return diagram.addActivity(lines.toDisplay(), style, null, colors, null);
+ return diagram.addActivity(lines.toDisplay(), style, null, colors, stereotype);
}
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrow3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrow3.java
index 6f7f93d18..643717928 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrow3.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrow3.java
@@ -78,9 +78,8 @@ public class CommandArrow3 extends SingleLineCommand2 {
diagram.setColorNextArrow(rainbow);
}
final String label = arg.get("LABEL", 0);
- if (label != null && label.length() > 0) {
+ if (label != null && label.length() > 0)
diagram.setLabelNextArrow(Display.getWithNewlines(label));
- }
return CommandExecutionResult.ok();
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf2.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf2.java
index efd28fb28..fca210ab9 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf2.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf2.java
@@ -47,6 +47,8 @@ import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexOptional;
import net.sourceforge.plantuml.regex.RegexResult;
+import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -63,7 +65,7 @@ public class CommandIf2 extends SingleLineCommand2 {
UrlBuilder.OPTIONAL, //
ColorParser.exp4(), //
new RegexLeaf("if"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
new RegexLeaf("\\("), //
new RegexLeaf("TEST", "(.*?)"), //
new RegexLeaf("\\)"), //
@@ -85,9 +87,8 @@ public class CommandIf2 extends SingleLineCommand2 {
final HColor color = s == null ? null : diagram.getSkinParam().getIHtmlColorSet().getColor(s);
String test = arg.get("TEST", 0);
- if (test.length() == 0) {
+ if (test.length() == 0)
test = null;
- }
final Url url;
if (arg.get("URL", 0) == null) {
@@ -96,8 +97,9 @@ public class CommandIf2 extends SingleLineCommand2 {
final UrlBuilder urlBuilder = new UrlBuilder(diagram.getSkinParam().getValue("topurl"), UrlMode.STRICT);
url = urlBuilder.getUrl(arg.get("URL", 0));
}
+ final Stereotype stereotype = Stereotype.build(arg.get("STEREO", 0));
- diagram.startIf(Display.getWithNewlines(test), Display.getWithNewlines(arg.get("WHEN", 0)), color, url);
+ diagram.startIf(Display.getWithNewlines(test), Display.getWithNewlines(arg.get("WHEN", 0)), color, url, stereotype);
return CommandExecutionResult.ok();
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf4.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf4.java
index 926746f8e..331389707 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf4.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf4.java
@@ -82,10 +82,10 @@ public class CommandIf4 extends SingleLineCommand2 {
final HColor color = s == null ? null : diagram.getSkinParam().getIHtmlColorSet().getColor(s);
String test = arg.get("TEST", 0);
- if (test.length() == 0) {
+ if (test.length() == 0)
test = null;
- }
- diagram.startIf(Display.getWithNewlines(test), Display.getWithNewlines(arg.get("WHEN", 0)), color, null);
+
+ diagram.startIf(Display.getWithNewlines(test), Display.getWithNewlines(arg.get("WHEN", 0)), color, null, null);
return CommandExecutionResult.ok();
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIfLegacy1.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIfLegacy1.java
index 7f1b9a30d..78f120eaa 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIfLegacy1.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIfLegacy1.java
@@ -72,7 +72,7 @@ public class CommandIfLegacy1 extends SingleLineCommand2 {
protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocation location, RegexResult arg) {
diagram.startIf(Display.getWithNewlines(arg.get("TEST", 0)), Display.getWithNewlines(arg.get("WHEN", 0)), null,
- null);
+ null, null);
return CommandExecutionResult.ok();
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandPartition3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandPartition3.java
index 63132a782..3e7dcc420 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandPartition3.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandPartition3.java
@@ -54,6 +54,7 @@ import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexOptional;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.utils.LineLocation;
@@ -77,9 +78,7 @@ public class CommandPartition3 extends SingleLineCommand2 {
new RegexConcat( //
RegexLeaf.spaceOneOrMore(), //
color("BACK2").getRegex())), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
new RegexLeaf("\\{?"), //
RegexLeaf.end());
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java
index 6289d2b60..82170a3e8 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeat3.java
@@ -52,6 +52,7 @@ import net.sourceforge.plantuml.regex.RegexOptional;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.skin.ColorParam;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.utils.LineLocation;
public class CommandRepeat3 extends SingleLineCommand2 {
@@ -62,7 +63,7 @@ public class CommandRepeat3 extends SingleLineCommand2 {
static IRegex getRegexConcat() {
return RegexConcat.build(CommandRepeat3.class.getName(), RegexLeaf.start(), //
- new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), //
+ StereotypePattern.optional("STEREO"), //
ColorParser.exp4(), //
new RegexLeaf("repeat"), //
RegexLeaf.spaceZeroOrMore(), //
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/BoxStyle.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/BoxStyle.java
index d2e6a70a3..f803285e7 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/BoxStyle.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/BoxStyle.java
@@ -160,11 +160,12 @@ public enum BoxStyle {
if (bs.style == style.charAt(0))
return bs;
- style = style.replaceAll("\\W", "");
-
- for (BoxStyle bs : BoxStyle.values())
- if (style.equalsIgnoreCase(bs.stereotype))
- return bs;
+ for (String s : style.split("\\s")) {
+ s = s.replaceAll("\\W", "");
+ for (BoxStyle bs : BoxStyle.values())
+ if (s.equalsIgnoreCase(bs.stereotype))
+ return bs;
+ }
}
return PLAIN;
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/EntityImageLegend.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/EntityImageLegend.java
index 75a603cd2..ba8ae42b9 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/EntityImageLegend.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/EntityImageLegend.java
@@ -49,7 +49,9 @@ public class EntityImageLegend {
final Style style = StyleSignatureBasic
.of(SName.root, SName.root, SName.document, skinParam.getUmlDiagramType().getStyleName(), SName.legend)
.getMergedStyle(skinParam.getCurrentStyleBuilder());
- return style.createTextBlockBordered(note, skinParam.getIHtmlColorSet(), skinParam, Style.ID_LEGEND);
+
+ return style.createTextBlockBordered(note, skinParam.getIHtmlColorSet(), skinParam, Style.ID_LEGEND,
+ style.wrapWidth());
}
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java
index 897491f1b..f7cabc662 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java
@@ -52,6 +52,7 @@ import net.sourceforge.plantuml.klimt.geom.VerticalAlignment;
import net.sourceforge.plantuml.stereo.Stereotype;
import net.sourceforge.plantuml.style.ISkinParam;
import net.sourceforge.plantuml.style.Style;
+import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.url.Url;
public interface FtileFactory {
@@ -83,13 +84,15 @@ public interface FtileFactory {
public Ftile repeat(BoxStyle boxStyleIn, Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat,
Display test, Display yes, Display out, Colors colors, Ftile backward, boolean noOut,
- LinkRendering incoming1, LinkRendering incoming2);
+ LinkRendering incoming1, LinkRendering incoming2, StyleBuilder currentStyleBuilder);
public Ftile createWhile(LinkRendering outColor, Swimlane swimlane, Ftile whileBlock, Display test, Display yes,
- HColor color, Instruction specialOut, Ftile backward, LinkRendering incoming1, LinkRendering incoming2);
+ HColor color, Instruction specialOut, Ftile backward, LinkRendering incoming1, LinkRendering incoming2,
+ StyleBuilder currentStyleBuilder);
public Ftile createIf(Swimlane swimlane, List thens, Branch elseBranch, LinkRendering outColor,
- LinkRendering topInlinkRendering, Url url, Collection notes);
+ LinkRendering topInlinkRendering, Url url, Collection notes, Stereotype stereotype,
+ StyleBuilder currentStyleBuilder);
public Ftile createSwitch(Swimlane swimlane, List branches, LinkRendering afterEndwhile,
LinkRendering topInlinkRendering, Display labelTest);
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactoryDelegator.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactoryDelegator.java
index 5969966ce..b39f1ad2e 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactoryDelegator.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactoryDelegator.java
@@ -60,6 +60,7 @@ import net.sourceforge.plantuml.stereo.Stereotype;
import net.sourceforge.plantuml.style.ISkinParam;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
+import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.url.Url;
@@ -174,22 +175,25 @@ public class FtileFactoryDelegator implements FtileFactory {
@Override
public Ftile repeat(BoxStyle boxStyleIn, Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat,
Display test, Display yes, Display out, Colors colors, Ftile backward, boolean noOut,
- LinkRendering incoming1, LinkRendering incoming2) {
+ LinkRendering incoming1, LinkRendering incoming2, StyleBuilder currentStyleBuilder) {
return factory.repeat(boxStyleIn, swimlane, swimlaneOut, startLabel, repeat, test, yes, out, colors, backward,
- noOut, incoming1, incoming2);
+ noOut, incoming1, incoming2, currentStyleBuilder);
}
@Override
public Ftile createWhile(LinkRendering outColor, Swimlane swimlane, Ftile whileBlock, Display test, Display yes,
- HColor color, Instruction specialOut, Ftile back, LinkRendering incoming1, LinkRendering incoming2) {
+ HColor color, Instruction specialOut, Ftile back, LinkRendering incoming1, LinkRendering incoming2,
+ StyleBuilder styleBuilder) {
return factory.createWhile(outColor, swimlane, whileBlock, test, yes, color, specialOut, back, incoming1,
- incoming2);
+ incoming2, styleBuilder);
}
@Override
public Ftile createIf(Swimlane swimlane, List thens, Branch elseBranch, LinkRendering afterEndwhile,
- LinkRendering topInlinkRendering, Url url, Collection notes) {
- return factory.createIf(swimlane, thens, elseBranch, afterEndwhile, topInlinkRendering, url, notes);
+ LinkRendering topInlinkRendering, Url url, Collection notes, Stereotype stereotype,
+ StyleBuilder currentStyleBuilder) {
+ return factory.createIf(swimlane, thens, elseBranch, afterEndwhile, topInlinkRendering, url, notes, stereotype,
+ currentStyleBuilder);
}
@Override
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java
index 1d5bebdd7..0df019d31 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java
@@ -82,6 +82,7 @@ import net.sourceforge.plantuml.style.ISkinParam;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
+import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.style.Styleable;
import net.sourceforge.plantuml.svek.UGraphicForSnake;
@@ -127,9 +128,9 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock, Styleable
}
protected Style getStyle() {
- if (style == null) {
+ if (style == null)
this.style = getStyleSignature().getMergedStyle(skinParam.getCurrentStyleBuilder());
- }
+
return style;
}
@@ -455,4 +456,8 @@ public class Swimlanes extends AbstractTextBlock implements TextBlock, Styleable
return cachedMinMax;
}
+ public StyleBuilder getCurrentStyleBuilder() {
+ return skinParam.getCurrentStyleBuilder();
+ }
+
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorIf.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorIf.java
index 4330e476b..92eda31fe 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorIf.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorIf.java
@@ -48,8 +48,10 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
import net.sourceforge.plantuml.activitydiagram3.ftile.vcompact.cond.ConditionalBuilder;
import net.sourceforge.plantuml.klimt.color.HColor;
import net.sourceforge.plantuml.skin.Pragma;
+import net.sourceforge.plantuml.stereo.Stereotype;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.Style;
+import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.svek.ConditionEndStyle;
import net.sourceforge.plantuml.svek.ConditionStyle;
import net.sourceforge.plantuml.url.Url;
@@ -65,15 +67,16 @@ public class FtileFactoryDelegatorIf extends FtileFactoryDelegator {
@Override
public Ftile createIf(Swimlane swimlane, List thens, Branch elseBranch, LinkRendering afterEndwhile,
- LinkRendering topInlinkRendering, Url url, Collection notes) {
+ LinkRendering topInlinkRendering, Url url, Collection notes, Stereotype stereotype,
+ StyleBuilder currentStyleBuilder) {
final ConditionStyle conditionStyle = skinParam().getConditionStyle();
final ConditionEndStyle conditionEndStyle = skinParam().getConditionEndStyle();
final Branch branch0 = thens.get(0);
- final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(skinParam().getCurrentStyleBuilder());
- final Style styleDiamond = getDefaultStyleDefinitionDiamond()
- .getMergedStyle(skinParam().getCurrentStyleBuilder());
+ final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(currentStyleBuilder);
+ final Style styleDiamond = getDefaultStyleDefinitionDiamond().withTOBECHANGED(stereotype)
+ .getMergedStyle(currentStyleBuilder);
final HColor backColor = branch0.getColor() == null
? styleDiamond.value(PName.BackGroundColor).asColor(skinParam().getIHtmlColorSet())
: branch0.getColor();
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorRepeat.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorRepeat.java
index a289a153d..140845b0a 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorRepeat.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorRepeat.java
@@ -62,6 +62,7 @@ import net.sourceforge.plantuml.klimt.font.FontConfiguration;
import net.sourceforge.plantuml.klimt.geom.XDimension2D;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.Style;
+import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.svek.ConditionStyle;
public class FtileFactoryDelegatorRepeat extends FtileFactoryDelegator {
@@ -73,13 +74,12 @@ public class FtileFactoryDelegatorRepeat extends FtileFactoryDelegator {
@Override
public Ftile repeat(BoxStyle boxStyleIn, Swimlane swimlane, Swimlane swimlaneOut, Display startLabel,
final Ftile repeat, Display test, Display yes, Display out, Colors colors, Ftile backward, boolean noOut,
- LinkRendering incoming1, LinkRendering incoming2) {
+ LinkRendering incoming1, LinkRendering incoming2, StyleBuilder currentStyleBuilder) {
final ConditionStyle conditionStyle = skinParam().getConditionStyle();
- final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(skinParam().getCurrentStyleBuilder());
- final Style styleDiamond = getDefaultStyleDefinitionDiamond()
- .getMergedStyle(skinParam().getCurrentStyleBuilder());
+ final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(currentStyleBuilder);
+ final Style styleDiamond = getDefaultStyleDefinitionDiamond().getMergedStyle(currentStyleBuilder);
final HColor borderColor = styleDiamond.value(PName.LineColor).asColor(skinParam().getIHtmlColorSet());
final HColor diamondColor = styleDiamond.value(PName.BackGroundColor).asColor(skinParam().getIHtmlColorSet());
final Rainbow arrowColor = Rainbow.build(styleArrow, skinParam().getIHtmlColorSet());
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorWhile.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorWhile.java
index 510a8df34..09e28adbc 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorWhile.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileFactoryDelegatorWhile.java
@@ -58,6 +58,7 @@ import net.sourceforge.plantuml.klimt.drawing.UGraphic;
import net.sourceforge.plantuml.klimt.font.FontConfiguration;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.Style;
+import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.svek.ConditionStyle;
public class FtileFactoryDelegatorWhile extends FtileFactoryDelegator {
@@ -68,13 +69,13 @@ public class FtileFactoryDelegatorWhile extends FtileFactoryDelegator {
@Override
public Ftile createWhile(LinkRendering outColor, Swimlane swimlane, Ftile whileBlock, Display test, Display yes,
- HColor color, Instruction specialOut, Ftile backward, LinkRendering incoming1, LinkRendering incoming2) {
+ HColor color, Instruction specialOut, Ftile backward, LinkRendering incoming1, LinkRendering incoming2,
+ StyleBuilder currentStyleBuilder) {
final ConditionStyle conditionStyle = skinParam().getConditionStyle();
- final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(skinParam().getCurrentStyleBuilder());
- final Style styleDiamond = getDefaultStyleDefinitionDiamond()
- .getMergedStyle(skinParam().getCurrentStyleBuilder());
+ final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(currentStyleBuilder);
+ final Style styleDiamond = getDefaultStyleDefinitionDiamond().getMergedStyle(currentStyleBuilder);
final HColor borderColor = styleDiamond.value(PName.LineColor).asColor(skinParam().getIHtmlColorSet());
final HColor backColor = styleDiamond.value(PName.BackGroundColor).asColor(skinParam().getIHtmlColorSet());
final Rainbow arrowColor = Rainbow.build(styleArrow, skinParam().getIHtmlColorSet());
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileForkInner.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileForkInner.java
index fd6a1a7cb..924829dd3 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileForkInner.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileForkInner.java
@@ -81,9 +81,9 @@ class FtileForkInner extends AbstractFtile {
public static Set mergeSwimlanes(List tiles) {
final Set result = new HashSet<>();
- for (Ftile tile : tiles) {
+ for (Ftile tile : tiles)
result.addAll(tile.getSwimlanes());
- }
+
return Collections.unmodifiableSet(result);
}
@@ -105,9 +105,9 @@ class FtileForkInner extends AbstractFtile {
for (Ftile ftile : forks) {
final XDimension2D dim = ftile.calculateDimension(stringBounder);
width += dim.getWidth();
- if (dim.getHeight() > height) {
+ if (dim.getHeight() > height)
height = dim.getHeight();
- }
+
}
final XDimension2D dimTotal = new XDimension2D(width, height);
return new FtileGeometry(dimTotal, dimTotal.getWidth() / 2, 0, dimTotal.getHeight());
@@ -116,9 +116,9 @@ class FtileForkInner extends AbstractFtile {
public UTranslate getTranslateFor(Ftile searched, StringBounder stringBounder) {
double xpos = 0;
for (Ftile ftile : forks) {
- if (ftile == searched) {
+ if (ftile == searched)
return UTranslate.dx(xpos);
- }
+
final XDimension2D dim = ftile.calculateDimension(stringBounder);
xpos += dim.getWidth();
}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/ParallelBuilderFork.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/ParallelBuilderFork.java
index 053470efe..90ce41f44 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/ParallelBuilderFork.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/ParallelBuilderFork.java
@@ -85,7 +85,7 @@ public class ParallelBuilderFork extends AbstractParallelFtilesBuilder {
Ftile result = middle;
final List conns = new ArrayList<>();
final Swimlane swimlaneBlack = in;
- final Style style = getStyleSignature().getMergedStyle(skinParam().getCurrentStyleBuilder());
+ final Style style = getStyleSignatureArrow().getMergedStyle(skinParam().getCurrentStyleBuilder());
final Ftile black = new FtileBlackBlock(skinParam(), swimlaneBlack);
double x = 0;
for (Ftile tmp : list99) {
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/VCompactFactory.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/VCompactFactory.java
index 267511711..743936057 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/VCompactFactory.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/VCompactFactory.java
@@ -156,20 +156,21 @@ public class VCompactFactory implements FtileFactory {
@Override
public Ftile repeat(BoxStyle boxStyleIn, Swimlane swimlane, Swimlane swimlaneOut, Display startLabel, Ftile repeat,
Display test, Display yes, Display out, Colors colors, Ftile backward, boolean noOut,
- LinkRendering incoming1, LinkRendering incoming2) {
+ LinkRendering incoming1, LinkRendering incoming2, StyleBuilder currentStyleBuilder) {
return repeat;
}
@Override
public Ftile createWhile(LinkRendering afterEndwhile, Swimlane swimlane, Ftile whileBlock, Display test,
Display yes, HColor color, Instruction specialOut, Ftile back, LinkRendering incoming1,
- LinkRendering incoming2) {
+ LinkRendering incoming2, StyleBuilder styleBuilder) {
return whileBlock;
}
@Override
public Ftile createIf(Swimlane swimlane, List thens, Branch elseBranch, LinkRendering afterEndwhile,
- LinkRendering topInlinkRendering, Url url, Collection notes) {
+ LinkRendering topInlinkRendering, Url url, Collection notes, Stereotype stereotype,
+ StyleBuilder currentStyleBuilder) {
final List ftiles = new ArrayList<>();
for (Branch branch : thens)
ftiles.add(branch.getFtile());
diff --git a/src/net/sourceforge/plantuml/board/BoardDiagram.java b/src/net/sourceforge/plantuml/board/BoardDiagram.java
index 266c7cb8f..f7fc67e1b 100644
--- a/src/net/sourceforge/plantuml/board/BoardDiagram.java
+++ b/src/net/sourceforge/plantuml/board/BoardDiagram.java
@@ -73,11 +73,11 @@ public class BoardDiagram extends UmlDiagram {
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {
- return createImageBuilder(fileFormatOption).drawable(getTextBlock()).write(os);
+ return createImageBuilder(fileFormatOption).drawable(getTextMainBlock(fileFormatOption)).write(os);
}
@Override
- protected TextBlock getTextBlock() {
+ protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
diff --git a/src/net/sourceforge/plantuml/bpm/BpmDiagram.java b/src/net/sourceforge/plantuml/bpm/BpmDiagram.java
index 2cbc3663e..c568879e4 100644
--- a/src/net/sourceforge/plantuml/bpm/BpmDiagram.java
+++ b/src/net/sourceforge/plantuml/bpm/BpmDiagram.java
@@ -194,7 +194,7 @@ public class BpmDiagram extends UmlDiagram {
}
@Override
- protected TextBlock getTextBlock() {
+ protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
throw new UnsupportedOperationException();
}
}
diff --git a/src/net/sourceforge/plantuml/chronology/ChronologyDiagram.java b/src/net/sourceforge/plantuml/chronology/ChronologyDiagram.java
new file mode 100644
index 000000000..9731c3506
--- /dev/null
+++ b/src/net/sourceforge/plantuml/chronology/ChronologyDiagram.java
@@ -0,0 +1,853 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.chronology;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+
+import net.sourceforge.plantuml.FileFormatOption;
+import net.sourceforge.plantuml.TitledDiagram;
+import net.sourceforge.plantuml.WithSprite;
+import net.sourceforge.plantuml.command.CommandExecutionResult;
+import net.sourceforge.plantuml.core.DiagramDescription;
+import net.sourceforge.plantuml.core.ImageData;
+import net.sourceforge.plantuml.core.UmlSource;
+import net.sourceforge.plantuml.klimt.UTranslate;
+import net.sourceforge.plantuml.klimt.color.HColorSet;
+import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
+import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
+import net.sourceforge.plantuml.klimt.geom.XDimension2D;
+import net.sourceforge.plantuml.klimt.shape.AbstractTextBlock;
+import net.sourceforge.plantuml.klimt.shape.TextBlock;
+import net.sourceforge.plantuml.project.GanttStyle;
+import net.sourceforge.plantuml.project.LabelPosition;
+import net.sourceforge.plantuml.project.LabelStrategy;
+import net.sourceforge.plantuml.project.LoadPlanable;
+import net.sourceforge.plantuml.project.TimeHeaderParameters;
+import net.sourceforge.plantuml.project.ToTaskDraw;
+import net.sourceforge.plantuml.project.core.PrintScale;
+import net.sourceforge.plantuml.project.core.Task;
+import net.sourceforge.plantuml.project.core.TaskCode;
+import net.sourceforge.plantuml.project.core.TaskGroup;
+import net.sourceforge.plantuml.project.draw.TaskDraw;
+import net.sourceforge.plantuml.project.draw.TaskDrawDiamond;
+import net.sourceforge.plantuml.project.draw.TimeHeader;
+import net.sourceforge.plantuml.project.time.Day;
+import net.sourceforge.plantuml.project.timescale.TimeScale;
+import net.sourceforge.plantuml.real.Real;
+import net.sourceforge.plantuml.real.RealOrigin;
+import net.sourceforge.plantuml.real.RealUtils;
+import net.sourceforge.plantuml.skin.UmlDiagramType;
+import net.sourceforge.plantuml.style.SName;
+import net.sourceforge.plantuml.style.Style;
+import net.sourceforge.plantuml.style.StyleSignatureBasic;
+
+public class ChronologyDiagram extends TitledDiagram implements ToTaskDraw, WithSprite, GanttStyle {
+
+ private final Map draws = new LinkedHashMap();
+ private final Map tasks = new LinkedHashMap();
+ private final Map byShortName = new HashMap();
+// private final List constraints = new ArrayList<>();
+ private final HColorSet colorSet = HColorSet.instance();
+//
+// private final OpenClose openClose = new OpenClose();
+//
+// private final Map resources = new LinkedHashMap();
+// private final Map colorDaysToday = new HashMap();
+// private final Map colorDaysInternal = new HashMap();
+// private final Map colorDaysOfWeek = new HashMap();
+// private final Map nameDays = new HashMap();
+ private LabelStrategy labelStrategy = new LabelStrategy(LabelPosition.LEGACY, HorizontalAlignment.LEFT);
+//
+// // Let's follow ISO-8601 rules
+// private WeekNumberStrategy weekNumberStrategy = new WeekNumberStrategy(DayOfWeek.MONDAY, 4);
+//
+// private PrintScale printScale = PrintScale.DAILY;
+// private double factorScale = 1.0;
+ private Locale locale = Locale.ENGLISH;
+//
+// private Day today;
+// private double totalHeightWithoutFooter;
+ private Day min;
+ private Day max;
+ private TimeScaleChronology timeScale;
+//
+// private Day printStart;
+// private Day printEnd;
+//
+ private final RealOrigin origin = RealUtils.createOrigin();
+//
+// private int defaultCompletion = 100;
+//
+// private Task it;
+// private Resource they;
+
+ public CommandExecutionResult changeLanguage(String lang) {
+ this.locale = new Locale(lang);
+ return CommandExecutionResult.ok();
+ }
+
+ public DiagramDescription getDescription() {
+ return new DiagramDescription("(Chronology)");
+ }
+
+// public void setWeekNumberStrategy(DayOfWeek firstDayOfWeek, int minimalDaysInFirstWeek) {
+// this.weekNumberStrategy = new WeekNumberStrategy(firstDayOfWeek, minimalDaysInFirstWeek);
+// }
+
+ public ChronologyDiagram(UmlSource source) {
+ super(source, UmlDiagramType.CHRONOLOGY, null);
+ }
+
+// public final int getDpi(FileFormatOption fileFormatOption) {
+// return 96;
+// }
+
+ @Override
+ protected ImageData exportDiagramNow(OutputStream os, int index, FileFormatOption fileFormatOption)
+ throws IOException {
+ return createImageBuilder(fileFormatOption).drawable(getTextMainBlock(fileFormatOption)).write(os);
+ }
+
+// public void setPrintScale(PrintScale printScale) {
+// this.printScale = printScale;
+// }
+//
+// public void setFactorScale(double factorScale) {
+// this.factorScale = factorScale;
+// }
+//
+// private double getFactorScale() {
+// return this.printScale.getDefaultScale() * this.factorScale;
+// }
+//
+// private boolean isHidden(Task task) {
+// if (printStart == null || task instanceof TaskSeparator)
+// return false;
+//
+// if (task.getEnd().compareTo(min) < 0)
+// return true;
+//
+// if (task.getStart().compareTo(max) > 0)
+// return true;
+//
+// return false;
+// }
+//
+// @Override
+// public String checkFinalError() {
+// try {
+// initMinMax();
+// } catch (ImpossibleSolvingException ex) {
+// return ex.getMessage();
+// }
+// return null;
+// }
+
+ @Override
+ protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
+ final StringBounder stringBounder = fileFormatOption.getDefaultStringBounder(getSkinParam());
+ initMinMax();
+
+ final TimeHeader timeHeader = new TimeHeaderChronology(stringBounder, thParam(), PrintScale.DAILY,
+ this.timeScale);
+ initTaskAndResourceDraws(timeHeader.getTimeScale(), timeHeader.getFullHeaderHeight(stringBounder),
+ stringBounder);
+
+ return new AbstractTextBlock() {
+ public XDimension2D calculateDimension(StringBounder stringBounder) {
+ return new XDimension2D(1000, 1000);
+ }
+
+ @Override
+ public void drawU(UGraphic ug) {
+ timeHeader.drawTimeHeader(ug, 200);
+ drawTasksRect(ug);
+ drawTasksTitle(ug, 0, 0);
+ }
+ };
+
+ }
+
+//
+// private double getTitlesColumnWidth(StringBounder stringBounder) {
+// if (labelStrategy.titleInside())
+// return 0;
+//
+// double width = 0;
+// for (Task task : tasks.values()) {
+// if (isHidden(task))
+// continue;
+//
+// width = Math.max(width, draws.get(task).getTitleWidth(stringBounder));
+// }
+// return width;
+// }
+//
+// public XDimension2D calculateDimension(StringBounder stringBounder) {
+// return new XDimension2D(getTitlesColumnWidth(stringBounder) + getBarsColumnWidth(timeHeader),
+// getTotalHeight(stringBounder, timeHeader));
+// }
+//
+// private double getBarsColumnWidth(final TimeHeader timeHeader) {
+// final double xmin = timeHeader.getTimeScale().getStartingPosition(min);
+// final double xmax = timeHeader.getTimeScale().getEndingPosition(max);
+// return xmax - xmin;
+// }
+//
+// };
+// }
+//
+// private TimeHeader getTimeHeader(StringBounder stringBounder) {
+// if (openClose.getStartingDay() == null)
+// return new TimeHeaderSimple(stringBounder, thParam(), printScale);
+// else if (printScale == PrintScale.DAILY)
+// return new TimeHeaderDaily(stringBounder, thParam(), nameDays, printStart, printEnd);
+// else if (printScale == PrintScale.WEEKLY)
+// return new TimeHeaderWeekly(stringBounder, thParam(), weekNumberStrategy, withCalendarDate);
+// else if (printScale == PrintScale.MONTHLY)
+// return new TimeHeaderMonthly(stringBounder, thParam());
+// else if (printScale == PrintScale.QUARTERLY)
+// return new TimeHeaderQuarterly(stringBounder, thParam());
+// else if (printScale == PrintScale.YEARLY)
+// return new TimeHeaderYearly(stringBounder, thParam());
+// else
+// throw new IllegalStateException();
+//
+// }
+
+ private TimeHeaderParameters thParam() {
+ return new TimeHeaderParameters(null, 1, min, max, getIHtmlColorSet(), locale, null, null, null, this);
+ }
+
+// private Map colorDays() {
+// colorDaysInternal.putAll(colorDaysToday);
+// return Collections.unmodifiableMap(colorDaysInternal);
+// }
+
+ @Override
+ public final Style getStyle(SName param) {
+ return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, param)
+ .getMergedStyle(getCurrentStyleBuilder());
+ }
+
+ @Override
+ public final Style getStyle(SName param1, SName param2) {
+ return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, param1, param2)
+ .getMergedStyle(getCurrentStyleBuilder());
+ }
+
+// private double getTotalHeight(StringBounder stringBounder, TimeHeader timeHeader) {
+// if (showFootbox)
+// return totalHeightWithoutFooter + timeHeader.getTimeFooterHeight(stringBounder);
+//
+// return totalHeightWithoutFooter;
+// }
+
+ private void drawTasksRect(UGraphic ug) {
+ for (Task task : tasks.values()) {
+// if (isHidden(task))
+// continue;
+
+ final TaskDraw draw = draws.get(task);
+ final UTranslate move = UTranslate.dy(draw.getY(ug.getStringBounder()).getCurrentValue());
+ draw.drawU(ug.apply(move));
+ }
+ }
+
+// private void drawConstraints(final UGraphic ug, TimeScale timeScale) {
+// for (GanttConstraint constraint : constraints) {
+// if (printStart != null && constraint.isHidden(min, max))
+// continue;
+//
+// constraint.getUDrawable(timeScale, this).drawU(ug);
+// }
+//
+// }
+//
+// public StyleSignatureBasic getDefaultStyleDefinitionArrow() {
+// return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, SName.arrow);
+// }
+
+ private void drawTasksTitle(UGraphic ug, double colTitles, double colBars) {
+ for (Task task : tasks.values()) {
+// if (isHidden(task))
+// continue;
+
+ final TaskDraw draw = draws.get(task);
+ final UTranslate move = UTranslate.dy(draw.getY(ug.getStringBounder()).getCurrentValue());
+ draw.drawTitle(ug.apply(move), labelStrategy, colTitles, colBars);
+ }
+ }
+
+// private void drawResources(UGraphic ug) {
+// for (Resource res : resources.values()) {
+// final ResourceDraw draw = res.getResourceDraw();
+// final UTranslate move = UTranslate.dy(draw.getY());
+// draw.drawU(ug.apply(move));
+// }
+// }
+//
+// public void closeDayOfWeek(DayOfWeek day, String task) {
+// openClose.close(day);
+// }
+//
+// public void openDayOfWeek(DayOfWeek day, String task) {
+// if (task.length() == 0)
+// openClose.open(day);
+// else
+// getOpenCloseForTask(task).open(day);
+// }
+//
+// public void closeDayAsDate(Day day, String task) {
+// if (task.length() == 0)
+// openClose.close(day);
+// else
+// getOpenCloseForTask(task).close(day);
+//
+// }
+//
+// public void openDayAsDate(Day day, String task) {
+// if (task.length() == 0)
+// openClose.open(day);
+// else
+// getOpenCloseForTask(task).open(day);
+//
+// }
+//
+// private OpenClose getOpenCloseForTask(String task) {
+// OpenClose except = openCloseForTask.get(task);
+// if (except == null) {
+// except = new OpenClose();
+// openCloseForTask.put(task, except);
+// }
+// return except;
+// }
+//
+// private final Map openCloseForTask = new HashMap<>();
+//
+ private void initTaskAndResourceDraws(TimeScale timeScale, double headerHeight, StringBounder stringBounder) {
+ Real y = origin;
+ y = y.addFixed(headerHeight);
+ for (Task task : tasks.values()) {
+ final TaskDraw draw;
+ final String disp = task.getCode().getSimpleDisplay();
+ draw = new TaskDrawDiamond(timeScale, y, disp, task.getStart(), task, this, task.getStyleBuilder());
+ final double height = draw.getFullHeightTask(stringBounder);
+ y = y.addAtLeast(height);
+// if (task instanceof TaskSeparator) {
+// final TaskSeparator taskSeparator = (TaskSeparator) task;
+// draw = new TaskDrawSeparator(taskSeparator.getName(), timeScale, y, min, max, task.getStyleBuilder(),
+// getSkinParam().getIHtmlColorSet());
+// } else if (task instanceof TaskGroup) {
+// final TaskGroup taskGroup = (TaskGroup) task;
+// draw = new TaskDrawGroup(timeScale, y, taskGroup.getCode().getSimpleDisplay(), getStart(taskGroup),
+// getEnd(taskGroup), task, this, task.getStyleBuilder());
+// } else {
+// final TaskImpl tmp = (TaskImpl) task;
+// final String disp = hideResourceName ? tmp.getCode().getSimpleDisplay() : tmp.getPrettyDisplay();
+// if (tmp.isDiamond()) {
+// draw = new TaskDrawDiamond(timeScale, y, disp, getStart(tmp), task, this, task.getStyleBuilder());
+// } else {
+// final boolean oddStart = printStart != null && min.compareTo(getStart(tmp)) == 0;
+// final boolean oddEnd = printStart != null && max.compareTo(getEnd(tmp)) == 0;
+// draw = new TaskDrawRegular(timeScale, y, disp, getStart(tmp), getEnd(tmp), oddStart, oddEnd,
+// getSkinParam(), task, this, getConstraints(task), task.getStyleBuilder());
+// }
+// draw.setColorsAndCompletion(tmp.getColors(), tmp.getCompletion(), tmp.getUrl(), tmp.getNote());
+// }
+// if (task.getRow() == null)
+// y = y.addAtLeast(draw.getFullHeightTask(stringBounder));
+//
+ draws.put(task, draw);
+ }
+// origin.compileNow();
+// magicPush(stringBounder);
+// double yy = lastY(stringBounder);
+// if (yy == 0) {
+// yy = headerHeight;
+// } else if (this.hideResourceFoobox == false)
+// for (Resource res : resources.values()) {
+// final ResourceDraw draw = buildResourceDraw(this, res, timeScale, yy, min, max);
+// res.setTaskDraw(draw);
+// yy += draw.getHeight(stringBounder);
+// }
+//
+// this.totalHeightWithoutFooter = yy;
+ }
+
+//
+// private ResourceDraw buildResourceDraw(ChronologyDiagram gantt, Resource res, TimeScale timeScale, double y, Day min,
+// Day max) {
+// return new ResourceDrawBasic(gantt, res, timeScale, y, min, max);
+// // return new ResourceDrawVersion2(gantt, res, timeScale, y, min, max);
+// }
+//
+// private Collection getConstraints(Task task) {
+// final List result = new ArrayList<>();
+// for (GanttConstraint constraint : constraints) {
+// if (constraint.isOn(task))
+// result.add(constraint);
+//
+// }
+// return Collections.unmodifiableCollection(result);
+// }
+//
+// private double lastY(StringBounder stringBounder) {
+// double result = 0;
+// for (TaskDraw td : draws.values())
+// result = Math.max(result, td.getY(stringBounder).getCurrentValue() + td.getHeightMax(stringBounder));
+//
+// return result;
+// }
+//
+// private void magicPush(StringBounder stringBounder) {
+// final List notes = new ArrayList<>();
+// for (TaskDraw td : draws.values()) {
+// final FingerPrint taskPrint = td.getFingerPrint(stringBounder);
+// final FingerPrint fingerPrintNote = td.getFingerPrintNote(stringBounder);
+//
+// if (td.getTrueRow() == null)
+// for (TaskDraw note : notes) {
+// final FingerPrint otherNote = note.getFingerPrintNote(stringBounder);
+// final double deltaY = otherNote.overlap(taskPrint);
+// if (deltaY > 0) {
+// final Real bottom = note.getY(stringBounder).addAtLeast(note.getHeightMax(stringBounder));
+// td.getY(stringBounder).ensureBiggerThan(bottom);
+// origin.compileNow();
+// }
+//
+// }
+//
+// if (fingerPrintNote != null)
+// notes.add(td);
+//
+// }
+// }
+//
+// private Day getStart(final Task tmp) {
+// if (printStart == null)
+// return tmp.getStart();
+//
+// return Day.max(min, tmp.getStart());
+// }
+//
+// private Day getEnd(final Task tmp) {
+// if (printStart == null)
+// return tmp.getEnd();
+//
+// return Day.min(max, tmp.getEnd());
+// }
+//
+ private void initMinMax() {
+ if (tasks.size() == 0) {
+ throw new IllegalStateException();
+ }
+ for (Task task : tasks.values()) {
+ if (this.min == null || this.max == null) {
+ this.min = task.getStart();
+ this.max = task.getEnd();
+ continue;
+
+ }
+ if (this.min.compareTo(task.getStart()) > 0)
+ this.min = task.getStart();
+ if (this.max.compareTo(task.getEnd()) < 0)
+ this.max = task.getEnd();
+ }
+
+ this.min = this.min.roundDayDown();
+ this.max = this.max.roundDayUp();
+
+ this.timeScale = new TimeScaleChronology(1000);
+ this.timeScale.setMin(this.min.getMillis());
+ this.timeScale.setMax(this.max.getMillis());
+ }
+
+// public Day getThenDate() {
+// Day result = getStartingDate();
+// for (Day d : colorDays().keySet())
+// if (d.compareTo(result) > 0)
+// result = d;
+//
+// for (Day d : nameDays.keySet())
+// if (d.compareTo(result) > 0)
+// result = d;
+//
+// return result;
+// }
+//
+// public Task getExistingTask(String id) {
+// final Task result = byShortName.get(Objects.requireNonNull(id));
+// if (result != null)
+// return result;
+//
+// final TaskCode code = new TaskCode(id);
+// return tasks.get(code);
+// }
+//
+// public GanttConstraint forceTaskOrder(Task task1, Task task2) {
+// final TaskInstant end1 = new TaskInstant(task1, TaskAttribute.END);
+// task2.setStart(end1.getInstantPrecise());
+// final GanttConstraint result = new GanttConstraint(this.getIHtmlColorSet(),
+// getSkinParam().getCurrentStyleBuilder(), end1, new TaskInstant(task2, TaskAttribute.START));
+// addContraint(result);
+// return result;
+// }
+
+ public Task getOrCreateTask(String codeOrShortName, String shortName, boolean linkedToPrevious) {
+ Objects.requireNonNull(codeOrShortName);
+ Task result = shortName == null ? null : byShortName.get(shortName);
+ if (result != null)
+ return result;
+
+ result = byShortName.get(codeOrShortName);
+ if (result != null)
+ return result;
+
+ final TaskCode code = new TaskCode(codeOrShortName);
+ result = tasks.get(code);
+ if (result == null) {
+
+ result = new TaskChronology(getSkinParam().getCurrentStyleBuilder(), code);
+ if (currentGroup != null)
+ currentGroup.addTask(result);
+
+ tasks.put(code, result);
+ if (byShortName != null)
+ byShortName.put(shortName, result);
+
+ }
+ return result;
+ }
+
+// private Task getLastCreatedTask() {
+// final List all = new ArrayList<>(tasks.values());
+// for (int i = all.size() - 1; i >= 0; i--)
+// if (all.get(i) instanceof TaskImpl)
+// return all.get(i);
+//
+// return null;
+// }
+//
+// public void addSeparator(String comment) {
+// TaskSeparator separator = new TaskSeparator(getSkinParam().getCurrentStyleBuilder(), comment, tasks.size());
+// tasks.put(separator.getCode(), separator);
+// }
+//
+ private TaskGroup currentGroup = null;
+//
+// public CommandExecutionResult addGroup(String name) {
+// TaskGroup group = new TaskGroup(this.currentGroup, getSkinParam().getCurrentStyleBuilder(), name);
+//
+// if (this.currentGroup != null)
+// this.currentGroup.addTask(group);
+//
+// this.currentGroup = group;
+// tasks.put(group.getCode(), group);
+// return CommandExecutionResult.ok();
+// }
+//
+// public CommandExecutionResult endGroup() {
+// if (this.currentGroup == null)
+// return CommandExecutionResult.error("No group to be closed");
+//
+// this.currentGroup = this.currentGroup.getParent();
+//
+// return CommandExecutionResult.ok();
+// }
+//
+// public void addContraint(GanttConstraint constraint) {
+// constraints.add(constraint);
+// }
+//
+// public HColorSet getIHtmlColorSet() {
+// return colorSet;
+// }
+//
+// public void setProjectStartingDate(Day start) {
+// openClose.setStartingDay(start);
+// this.min = start;
+// }
+//
+// public Day getStartingDate() {
+// if (openClose.getStartingDay() == null)
+// return min;
+//
+// return openClose.getStartingDay();
+// }
+//
+// public Day getEndingDate() {
+// initMinMax();
+// return max;
+// }
+//
+// public int daysInWeek() {
+// return openClose.daysInWeek();
+// }
+//
+// public boolean isOpen(Day day) {
+// return openClose.getLoadAt(day) > 0;
+// }
+//
+// public boolean affectResource(Task result, String description) {
+// final Pattern p = Pattern.compile("([^:]+)(:(\\d+))?");
+// final Matcher m = p.matcher(description);
+// if (m.find() == false)
+// throw new IllegalArgumentException();
+//
+// final Resource resource = getResource(m.group(1));
+// int percentage = 100;
+// if (m.group(3) != null)
+// percentage = Integer.parseInt(m.group(3));
+//
+// if (percentage == 0)
+// return false;
+//
+// result.addResource(resource, percentage);
+// return true;
+// }
+//
+// public Resource getResource(String resourceName) {
+// Resource resource = resources.get(resourceName);
+// if (resource == null)
+// resource = new Resource(resourceName);
+//
+// resources.put(resourceName, resource);
+// return resource;
+// }
+//
+// public int getLoadForResource(Resource res, Day i) {
+// int result = 0;
+// for (Task task : tasks.values()) {
+// if (task instanceof TaskSeparator)
+// continue;
+//
+// final TaskImpl task2 = (TaskImpl) task;
+// result += task2.loadForResource(res, i);
+// }
+// return result;
+// }
+//
+// public Moment getExistingMoment(String id) {
+// Moment result = getExistingTask(id);
+// if (result == null) {
+// Day start = null;
+// Day end = null;
+// for (Map.Entry ent : nameDays.entrySet()) {
+// if (ent.getValue().equalsIgnoreCase(id) == false)
+// continue;
+//
+// start = min(start, ent.getKey());
+// end = max(end, ent.getKey());
+// }
+// if (start != null)
+// result = new MomentImpl(start, end);
+//
+// }
+// return result;
+// }
+//
+// private Day min(Day d1, Day d2) {
+// if (d1 == null)
+// return d2;
+//
+// if (d1.compareTo(d2) > 0)
+// return d2;
+//
+// return d1;
+// }
+//
+// private Day max(Day d1, Day d2) {
+// if (d1 == null)
+// return d2;
+//
+// if (d1.compareTo(d2) < 0)
+// return d2;
+//
+// return d1;
+// }
+//
+// public void colorDay(Day day, HColor color) {
+// colorDaysInternal.put(day, color);
+// }
+//
+// public void colorDay(DayOfWeek day, HColor color) {
+// colorDaysOfWeek.put(day, color);
+// }
+//
+// public void nameDay(Day day, String name) {
+// nameDays.put(day, name);
+// }
+//
+// public Day getToday() {
+// if (today == null)
+// this.today = Day.today();
+//
+// return today;
+// }
+//
+// public void setTodayColors(CenterBorderColor colors) {
+// if (today == null)
+// this.today = Day.today();
+//
+// colorDaysToday.put(today, colors.getCenter());
+// }
+//
+// public CommandExecutionResult setToday(Day date) {
+// this.today = date;
+// return CommandExecutionResult.ok();
+// }
+//
+// public CommandExecutionResult deleteTask(Task task) {
+// task.setColors(new CenterBorderColor(HColors.WHITE, HColors.BLACK));
+// return CommandExecutionResult.ok();
+// }
+//
+// public void setPrintInterval(Day start, Day end) {
+// this.printStart = start;
+// this.printEnd = end;
+// }
+//
+// public TaskDraw getTaskDraw(Task task) {
+// return draws.get(task);
+// }
+//
+// public CommandExecutionResult addNote(Display note) {
+// Task last = null;
+// for (Task current : tasks.values())
+// last = current;
+// if (last == null)
+// return CommandExecutionResult.error("No task defined");
+//
+// last.setNote(note);
+// return CommandExecutionResult.ok();
+// }
+
+ public LoadPlanable getDefaultPlan() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TaskDraw getTaskDraw(Task task) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public HColorSet getIHtmlColorSet() {
+ return colorSet;
+ }
+
+// private boolean showFootbox = true;
+//
+// public void setShowFootbox(boolean footbox) {
+// this.showFootbox = footbox;
+//
+// }
+//
+// @Override
+// public ClockwiseTopRightBottomLeft getDefaultMargins() {
+// return ClockwiseTopRightBottomLeft.none();
+// }
+//
+// public void setLabelStrategy(LabelStrategy strategy) {
+// this.labelStrategy = strategy;
+// }
+//
+// private boolean withCalendarDate;
+//
+// public void setWithCalendarDate(boolean withCalendarDate) {
+// this.withCalendarDate = withCalendarDate;
+// }
+//
+// private boolean hideResourceName;
+// private boolean hideResourceFoobox;
+//
+// public CommandExecutionResult hideResourceName() {
+// this.hideResourceName = true;
+// return CommandExecutionResult.ok();
+// }
+//
+// public CommandExecutionResult hideResourceFootbox() {
+// this.hideResourceFoobox = true;
+// return CommandExecutionResult.ok();
+// }
+//
+// private final Set verticalSeparatorBefore = new HashSet<>();
+//
+// public void addVerticalSeparatorBefore(Day day) {
+// verticalSeparatorBefore.add(day);
+// }
+//
+// public void setTaskDefaultCompletion(int defaultCompletion) {
+// this.defaultCompletion = defaultCompletion;
+// }
+//
+// public List getAllTasksForResource(Resource res) {
+// final List result = new ArrayList();
+// for (Task task : tasks.values())
+// if (task.isAssignedTo(res)) {
+// final TaskDrawRegular draw = (TaskDrawRegular) draws.get(task);
+// result.add(draw);
+// }
+//
+// return Collections.unmodifiableList(result);
+// }
+//
+// public void setIt(Task result) {
+// this.it = result;
+// }
+//
+// public Task getIt() {
+// return it;
+// }
+//
+// public final Resource getThey() {
+// return they;
+// }
+//
+// public final void setThey(Resource they) {
+// this.they = they;
+// }
+
+}
diff --git a/src/net/sourceforge/plantuml/chronology/ChronologyDiagramFactory.java b/src/net/sourceforge/plantuml/chronology/ChronologyDiagramFactory.java
new file mode 100644
index 000000000..063b908f9
--- /dev/null
+++ b/src/net/sourceforge/plantuml/chronology/ChronologyDiagramFactory.java
@@ -0,0 +1,126 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.chronology;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.plantuml.command.Command;
+import net.sourceforge.plantuml.command.CommonCommands;
+import net.sourceforge.plantuml.command.PSystemCommandFactory;
+import net.sourceforge.plantuml.core.DiagramType;
+import net.sourceforge.plantuml.core.UmlSource;
+import net.sourceforge.plantuml.project.command.NaturalCommand;
+import net.sourceforge.plantuml.project.lang.SentenceAnd;
+import net.sourceforge.plantuml.project.lang.SentenceAndAnd;
+import net.sourceforge.plantuml.project.lang.SentenceSimple;
+import net.sourceforge.plantuml.project.lang.Subject;
+
+public class ChronologyDiagramFactory extends PSystemCommandFactory {
+
+ static private final List> subjects() {
+ return Arrays.asList(SubjectTask.ME);
+ }
+
+ public ChronologyDiagramFactory() {
+ super(DiagramType.CHRONOLOGY);
+ }
+
+ @Override
+ protected void initCommandsList(List cmds) {
+ CommonCommands.addTitleCommands(cmds);
+ CommonCommands.addCommonCommands2(cmds);
+
+// cmds.add(CommandStyleMultilinesCSS.ME);
+// cmds.add(CommandStyleImport.ME);
+//
+// cmds.add(CommandNope.ME);
+
+ addLanguageCommands(cmds);
+
+// cmds.add(new CommandGanttArrow());
+// cmds.add(new CommandGanttArrow2());
+// cmds.add(new CommandColorTask());
+// cmds.add(new CommandSeparator());
+// cmds.add(new CommandWeekNumberStrategy());
+// cmds.add(new CommandGroupStart());
+// cmds.add(new CommandGroupEnd());
+//
+// cmds.add(new CommandLanguage());
+// cmds.add(new CommandPrintScale());
+// cmds.add(new CommandPrintBetween());
+// cmds.add(new CommandNoteBottom());
+// cmds.add(new CommandFootbox());
+// cmds.add(new CommandLabelOnColumn());
+// cmds.add(new CommandHideResourceName());
+// cmds.add(new CommandHideResourceFootbox());
+// cmds.add(new CommandTaskCompleteDefault());
+ }
+
+ private void addLanguageCommands(List cmd) {
+ for (Subject subject : subjects())
+ for (SentenceSimple sentenceA : subject.getSentences()) {
+ cmd.add(NaturalCommand.create(sentenceA));
+ for (SentenceSimple sentenceB : subject.getSentences()) {
+ final String signatureA = sentenceA.getSignature();
+ final String signatureB = sentenceB.getSignature();
+ if (signatureA.equals(signatureB) == false)
+ cmd.add(NaturalCommand.create(new SentenceAnd(sentenceA, sentenceB)));
+
+ }
+ }
+
+ for (Subject subject : subjects())
+ for (SentenceSimple sentenceA : subject.getSentences())
+ for (SentenceSimple sentenceB : subject.getSentences())
+ for (SentenceSimple sentenceC : subject.getSentences()) {
+ final String signatureA = sentenceA.getSignature();
+ final String signatureB = sentenceB.getSignature();
+ final String signatureC = sentenceC.getSignature();
+ if (signatureA.equals(signatureB) == false && signatureA.equals(signatureC) == false
+ && signatureC.equals(signatureB) == false)
+ cmd.add(NaturalCommand
+ .create(new SentenceAndAnd(sentenceA, sentenceB, sentenceC)));
+ }
+ }
+
+ @Override
+ public ChronologyDiagram createEmptyDiagram(UmlSource source, Map skinParam) {
+ return new ChronologyDiagram(source);
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/chronology/ComplementAnything.java b/src/net/sourceforge/plantuml/chronology/ComplementAnything.java
new file mode 100644
index 000000000..436232f47
--- /dev/null
+++ b/src/net/sourceforge/plantuml/chronology/ComplementAnything.java
@@ -0,0 +1,54 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.chronology;
+
+import net.sourceforge.plantuml.project.Failable;
+import net.sourceforge.plantuml.project.lang.Something;
+import net.sourceforge.plantuml.regex.IRegex;
+import net.sourceforge.plantuml.regex.RegexLeaf;
+import net.sourceforge.plantuml.regex.RegexResult;
+
+public class ComplementAnything implements Something {
+
+ public IRegex toRegex(String suffix) {
+ return new RegexLeaf("ANYTHING" + suffix, "(.*?)");
+ }
+
+ public Failable getMe(ChronologyDiagram system, RegexResult arg, String suffix) {
+ final String value = arg.get("ANYTHING" + suffix, 0);
+ return Failable.ok(value);
+ }
+}
diff --git a/src/net/sourceforge/plantuml/chronology/ComplementHour.java b/src/net/sourceforge/plantuml/chronology/ComplementHour.java
new file mode 100644
index 000000000..d45338571
--- /dev/null
+++ b/src/net/sourceforge/plantuml/chronology/ComplementHour.java
@@ -0,0 +1,84 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.chronology;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import net.sourceforge.plantuml.project.Failable;
+import net.sourceforge.plantuml.project.lang.Something;
+import net.sourceforge.plantuml.project.time.Day;
+import net.sourceforge.plantuml.regex.IRegex;
+import net.sourceforge.plantuml.regex.RegexConcat;
+import net.sourceforge.plantuml.regex.RegexLeaf;
+import net.sourceforge.plantuml.regex.RegexOptional;
+import net.sourceforge.plantuml.regex.RegexResult;
+
+public class ComplementHour implements Something {
+
+ // [Task1] starts at 2023-11-28 15:41:21, ends at 2023-11-28 19:40:00
+
+ static private final SimpleDateFormat inputFormat;
+ static private final SimpleDateFormat inputFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+ static {
+ inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ inputFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
+
+ }
+
+ public IRegex toRegex(String suffix) {
+ return new RegexConcat( //
+ new RegexLeaf("TIME", "(\\d+-\\d+-\\d+ \\d+:\\d+:\\d+)"), //
+ new RegexOptional(new RegexLeaf("MS", "\\.(\\d+)")) //
+ ); //
+ }
+
+ public Failable getMe(ChronologyDiagram system, RegexResult arg, String suffix) {
+ final String value = arg.get("TIME", 0);
+ System.err.println("value=" + value);
+ try {
+ final Date date = inputFormat.parse(value);
+ return Failable.ok(Day.create(date.getTime()));
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ throw new IllegalStateException();
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/chronology/HourPattern.java b/src/net/sourceforge/plantuml/chronology/HourPattern.java
new file mode 100644
index 000000000..f34c49290
--- /dev/null
+++ b/src/net/sourceforge/plantuml/chronology/HourPattern.java
@@ -0,0 +1,136 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.chronology;
+
+import net.sourceforge.plantuml.project.time.Day;
+import net.sourceforge.plantuml.project.time.Month;
+import net.sourceforge.plantuml.regex.IRegex;
+import net.sourceforge.plantuml.regex.RegexConcat;
+import net.sourceforge.plantuml.regex.RegexLeaf;
+import net.sourceforge.plantuml.regex.RegexOr;
+import net.sourceforge.plantuml.regex.RegexResult;
+
+public class HourPattern {
+
+ private final String id;
+ private final String yearKeyA;
+ private final String yearKeyB;
+ private final String yearKeyC;
+ private final String monthKeyA;
+ private final String monthKeyB;
+ private final String monthKeyC;
+ private final String dayKeyA;
+ private final String dayKeyB;
+ private final String dayKeyC;
+
+ public HourPattern(String id) {
+ this.id = id;
+ this.yearKeyA = "AYEAR" + id;
+ this.yearKeyB = "BYEAR" + id;
+ this.yearKeyC = "CYEAR" + id;
+ this.monthKeyA = "AMONTH" + id;
+ this.monthKeyB = "BMONTH" + id;
+ this.monthKeyC = "CMONTH" + id;
+ this.dayKeyA = "ADAY" + id;
+ this.dayKeyB = "BDAY" + id;
+ this.dayKeyC = "CDAY" + id;
+ }
+
+ public IRegex toRegex() {
+ return new RegexOr(toRegexA_DD_MONTH_YYYY(), toRegexB_YYYY_MM_DD(), toRegexC_MONTH_DD_YYYY());
+ }
+
+ public Day getDay(RegexResult arg) {
+ if (arg.get(dayKeyA, 0) != null)
+ return resultA(arg);
+
+ if (arg.get(dayKeyB, 0) != null)
+ return resultB(arg);
+
+ if (arg.get(dayKeyC, 0) != null)
+ return resultC(arg);
+ return null;
+ }
+
+ private IRegex toRegexA_DD_MONTH_YYYY() {
+ return new RegexConcat( //
+ new RegexLeaf(dayKeyA, "([\\d]{1,2})"), //
+ new RegexLeaf("[\\w, ]*?"), //
+ new RegexLeaf(monthKeyA, "(" + Month.getRegexString() + ")"), //
+ new RegexLeaf("[\\w, ]*?"), //
+ new RegexLeaf(yearKeyA, "([\\d]{1,4})"));
+ }
+
+ private Day resultA(RegexResult arg) {
+ final int day = Integer.parseInt(arg.get(dayKeyA, 0));
+ final String month = arg.get(monthKeyA, 0);
+ final int year = Integer.parseInt(arg.get(yearKeyA, 0));
+ return Day.create(year, month, day);
+ }
+
+ private IRegex toRegexB_YYYY_MM_DD() {
+ return new RegexConcat( //
+ new RegexLeaf(yearKeyB, "([\\d]{1,4})"), //
+ new RegexLeaf("\\D"), //
+ new RegexLeaf(monthKeyB, "([\\d]{1,2})"), //
+ new RegexLeaf("\\D"), //
+ new RegexLeaf(dayKeyB, "([\\d]{1,2})"));
+ }
+
+ private Day resultB(RegexResult arg) {
+ final int day = Integer.parseInt(arg.get(dayKeyB, 0));
+ final int month = Integer.parseInt(arg.get(monthKeyB, 0));
+ final int year = Integer.parseInt(arg.get(yearKeyB, 0));
+ return Day.create(year, month, day);
+ }
+
+ private IRegex toRegexC_MONTH_DD_YYYY() {
+ return new RegexConcat( //
+ new RegexLeaf(monthKeyC, "(" + Month.getRegexString() + ")"), //
+ new RegexLeaf("[\\w, ]*?"), //
+ new RegexLeaf(dayKeyC, "([\\d]{1,2})"), //
+ new RegexLeaf("[\\w, ]*?"), //
+ new RegexLeaf(yearKeyC, "([\\d]{1,4})"));
+ }
+
+ private Day resultC(RegexResult arg) {
+ final int day = Integer.parseInt(arg.get(dayKeyC, 0));
+ final String month = arg.get(monthKeyC, 0);
+ final int year = Integer.parseInt(arg.get(yearKeyC, 0));
+ return Day.create(year, month, day);
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/chronology/SentenceHappensChronology.java b/src/net/sourceforge/plantuml/chronology/SentenceHappensChronology.java
new file mode 100644
index 000000000..2cfb488db
--- /dev/null
+++ b/src/net/sourceforge/plantuml/chronology/SentenceHappensChronology.java
@@ -0,0 +1,60 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.chronology;
+
+import net.sourceforge.plantuml.command.CommandExecutionResult;
+import net.sourceforge.plantuml.project.core.Task;
+import net.sourceforge.plantuml.project.lang.SentenceSimple;
+import net.sourceforge.plantuml.project.lang.Verbs;
+import net.sourceforge.plantuml.project.lang.Words;
+import net.sourceforge.plantuml.project.time.Day;
+
+public class SentenceHappensChronology extends SentenceSimple {
+
+ public SentenceHappensChronology() {
+ super(SubjectTask.ME, Verbs.happens, Words.zeroOrMore(Words.THE, Words.ON, Words.AT), new ComplementHour());
+ }
+
+ @Override
+ public CommandExecutionResult execute(ChronologyDiagram project, Object subject, Object complement) {
+ final Task task = (Task) subject;
+ final Day start = (Day) complement;
+ task.setStart(start);
+ task.setEnd(start);
+ return CommandExecutionResult.ok();
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/chronology/SubjectTask.java b/src/net/sourceforge/plantuml/chronology/SubjectTask.java
new file mode 100644
index 000000000..cd5eeb396
--- /dev/null
+++ b/src/net/sourceforge/plantuml/chronology/SubjectTask.java
@@ -0,0 +1,92 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.chronology;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import net.sourceforge.plantuml.project.Failable;
+import net.sourceforge.plantuml.project.core.Task;
+import net.sourceforge.plantuml.project.lang.SentenceSimple;
+import net.sourceforge.plantuml.project.lang.Subject;
+import net.sourceforge.plantuml.project.lang.Words;
+import net.sourceforge.plantuml.regex.IRegex;
+import net.sourceforge.plantuml.regex.RegexConcat;
+import net.sourceforge.plantuml.regex.RegexLeaf;
+import net.sourceforge.plantuml.regex.RegexOptional;
+import net.sourceforge.plantuml.regex.RegexOr;
+import net.sourceforge.plantuml.regex.RegexResult;
+import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
+
+public class SubjectTask implements Subject {
+
+ public static final Subject ME = new SubjectTask();
+
+ private SubjectTask() {
+ }
+
+ public Failable getMe(ChronologyDiagram chronology, RegexResult arg) {
+ final Task result;
+
+ final String subject = arg.get("SUBJECT", 0);
+ final String shortName = arg.get("SHORTNAME", 0);
+ final String stereotype = arg.get("STEREOTYPE", 0);
+
+ result = chronology.getOrCreateTask(subject, shortName, false);
+
+ if (stereotype != null)
+ result.setStereotype(Stereotype.build(arg.get("STEREOTYPE", 0)));
+
+ return Failable.ok(result);
+ }
+
+ public Collection extends SentenceSimple> getSentences() {
+ return Arrays.asList(new SentenceHappensChronology());
+ }
+
+ public IRegex toRegex() {
+ return new RegexOr( //
+ new RegexLeaf("SUBJECT", "\\[([^\\[\\]]+?)\\]"), //
+ StereotypePattern.optional("STEREOTYPE"), //
+ new RegexOptional(new RegexConcat(//
+ Words.exactly(Words.AS), //
+ RegexLeaf.spaceOneOrMore(), //
+ new RegexLeaf("SHORTNAME", "\\[([^\\[\\]]+?)\\]"))) //
+ );
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/chronology/TaskChronology.java b/src/net/sourceforge/plantuml/chronology/TaskChronology.java
new file mode 100644
index 000000000..20d877c1e
--- /dev/null
+++ b/src/net/sourceforge/plantuml/chronology/TaskChronology.java
@@ -0,0 +1,372 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.chronology;
+
+import net.sourceforge.plantuml.klimt.creole.Display;
+import net.sourceforge.plantuml.project.Load;
+import net.sourceforge.plantuml.project.core.AbstractTask;
+import net.sourceforge.plantuml.project.core.Resource;
+import net.sourceforge.plantuml.project.core.Task;
+import net.sourceforge.plantuml.project.core.TaskCode;
+import net.sourceforge.plantuml.project.lang.CenterBorderColor;
+import net.sourceforge.plantuml.project.time.Day;
+import net.sourceforge.plantuml.project.time.DayOfWeek;
+import net.sourceforge.plantuml.style.StyleBuilder;
+import net.sourceforge.plantuml.url.Url;
+
+public class TaskChronology extends AbstractTask implements Task {
+
+ private Display note;
+
+ private Url url;
+ private CenterBorderColor[] colors;
+
+ private Day start;
+ private Day end;
+
+ public void setUrl(Url url) {
+ this.url = url;
+ }
+
+ public TaskChronology(StyleBuilder styleBuilder, TaskCode code) {
+ super(styleBuilder, code);
+ }
+
+ @Override
+ public void setStart(Day start) {
+ this.start = start;
+
+ }
+
+ @Override
+ public Day getStart() {
+ return this.start;
+ }
+
+ @Override
+ public void setEnd(Day end) {
+ this.end = end;
+ }
+
+ @Override
+ public Day getEnd() {
+ return this.end;
+ }
+
+ @Override
+ public Load getLoad() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setLoad(Load load) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addResource(Resource resource, int percentage) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setDiamond(boolean diamond) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isDiamond() {
+ return false;
+ }
+
+ @Override
+ public void setCompletion(int completion) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addPause(Day pause) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addPause(DayOfWeek pause) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isAssignedTo(Resource res) {
+ throw new UnsupportedOperationException();
+ }
+
+// @Override
+// public int getLoadAt(Day instant) {
+// if (isPaused(instant))
+// return 0;
+//
+// LoadPlanable result = defaultPlan;
+// if (resources.size() > 0)
+// result = PlanUtils.multiply(defaultPlan, getResourcePlan());
+//
+// return result.getLoadAt(instant);
+// }
+//
+// private boolean isPaused(Day instant) {
+// if (pausedDay.contains(instant))
+// return true;
+//
+// if (pausedDayOfWeek(instant))
+// return true;
+//
+// return false;
+// }
+//
+// private boolean pausedDayOfWeek(Day instant) {
+// for (DayOfWeek dayOfWeek : pausedDayOfWeek)
+// if (instant.getDayOfWeek() == dayOfWeek)
+// return true;
+//
+// return false;
+// }
+//
+// public int loadForResource(Resource res, Day instant) {
+// if (resources.keySet().contains(res) && instant.compareTo(getStart()) >= 0
+// && instant.compareTo(getEnd()) <= 0) {
+// if (isPaused(instant))
+// return 0;
+//
+// if (res.isClosedAt(instant))
+// return 0;
+//
+// return resources.get(res);
+// }
+// return 0;
+// }
+//
+// @Override
+// public void addPause(Day pause) {
+// this.pausedDay.add(pause);
+// }
+//
+// @Override
+// public void addPause(DayOfWeek pause) {
+// this.pausedDayOfWeek.add(pause);
+// }
+//
+// private LoadPlanable getResourcePlan() {
+// if (resources.size() == 0)
+// throw new IllegalStateException();
+//
+// return new LoadPlanable() {
+// public int getLoadAt(Day instant) {
+// int result = 0;
+// for (Map.Entry ent : resources.entrySet()) {
+// final Resource res = ent.getKey();
+// if (res.isClosedAt(instant))
+// continue;
+//
+// final int percentage = ent.getValue();
+// result += percentage;
+// }
+// return result;
+// }
+//
+// @Override
+// public Day getLastDayIfAny() {
+// return TaskChronology.this.getLastDayIfAny();
+// }
+// };
+// }
+//
+// @Override
+// public Day getLastDayIfAny() {
+// Day result = null;
+//
+// for (Resource res : resources.keySet()) {
+// if (res.getLastDayIfAny() == null)
+// return null;
+//
+// if (result == null || result.compareTo(res.getLastDayIfAny()) < 0)
+// result = res.getLastDayIfAny();
+// }
+//
+// return result;
+// }
+//
+// public String getPrettyDisplay() {
+// if (resources.size() > 0) {
+// final StringBuilder result = new StringBuilder(getCode().getSimpleDisplay());
+// result.append(" ");
+// for (Iterator> it = resources.entrySet().iterator(); it.hasNext();) {
+// final Map.Entry ent = it.next();
+// result.append("{");
+// result.append(ent.getKey().getName());
+// final int percentage = ent.getValue();
+// if (percentage != 100)
+// result.append(":" + percentage + "%");
+//
+// result.append("}");
+// if (it.hasNext())
+// result.append(" ");
+//
+// }
+// return result.toString();
+// }
+// return getCode().getSimpleDisplay();
+// }
+//
+// @Override
+// public String toString() {
+// return getCode().toString();
+// }
+//
+// public String debug() {
+// return "" + getStart() + " ---> " + getEnd() + " [" + getLoad() + "]";
+// }
+//
+// @Override
+// public Day getStart() {
+// Day result = (Day) solver.getData(TaskAttribute.START);
+// if (diamond == false)
+// while (getLoadAt(result) == 0)
+// result = result.increment();
+//
+// return result;
+// }
+//
+// @Override
+// public Day getEnd() {
+// return (Day) solver.getData(TaskAttribute.END);
+// }
+//
+// @Override
+// public Load getLoad() {
+// return (Load) solver.getData(TaskAttribute.LOAD);
+// }
+//
+// @Override
+// public void setLoad(Load load) {
+// solver.setData(TaskAttribute.LOAD, load);
+// }
+//
+// @Override
+// public void setStart(Day start) {
+// solver.setData(TaskAttribute.START, start);
+// }
+//
+// @Override
+// public void setEnd(Day end) {
+// solver.setData(TaskAttribute.END, end);
+// }
+
+ @Override
+ public void setColors(CenterBorderColor... colors) {
+ this.colors = colors;
+ }
+
+// @Override
+// public void addResource(Resource resource, int percentage) {
+// this.resources.put(resource, percentage);
+// }
+//
+// @Override
+// public void setDiamond(boolean diamond) {
+// this.diamond = diamond;
+// }
+//
+// @Override
+// public boolean isDiamond() {
+// return this.diamond;
+// }
+//
+// @Override
+// public void setCompletion(int completion) {
+// this.completion = completion;
+// }
+//
+// public final Url getUrl() {
+// return url;
+// }
+//
+// public final CenterBorderColor getColors() {
+// if (colors == null)
+// return null;
+//
+// if (colors.length == 1)
+// return colors[0];
+//
+// return colors[0].unlinearTo(colors[1], completion);
+// }
+//
+// public final int getCompletion() {
+// return completion;
+// }
+//
+// public final Collection getAllPaused() {
+// final SortedSet result = new TreeSet<>(pausedDay);
+// for (DayOfWeek dayOfWeek : pausedDayOfWeek)
+// addAll(result, dayOfWeek);
+//
+// return Collections.unmodifiableCollection(result);
+// }
+//
+// private void addAll(SortedSet result, DayOfWeek dayOfWeek) {
+// final Day start = getStart();
+// final Day end = getEnd();
+// for (Day current = start; current.compareTo(end) <= 0; current = current.increment())
+// if (current.getDayOfWeek() == dayOfWeek)
+// result.add(current);
+//
+// }
+
+ @Override
+ public void setNote(Display note) {
+ this.note = note;
+ }
+
+ public Display getNote() {
+ return note;
+ }
+
+// public LoadPlanable getDefaultPlan() {
+// return defaultPlan;
+// }
+//
+// @Override
+// public boolean isAssignedTo(Resource res) {
+// return resources.containsKey(res);
+// }
+
+}
diff --git a/src/net/sourceforge/plantuml/chronology/TimeHeaderChronology.java b/src/net/sourceforge/plantuml/chronology/TimeHeaderChronology.java
new file mode 100644
index 000000000..fca77fb27
--- /dev/null
+++ b/src/net/sourceforge/plantuml/chronology/TimeHeaderChronology.java
@@ -0,0 +1,197 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.chronology;
+
+import net.sourceforge.plantuml.klimt.UTranslate;
+import net.sourceforge.plantuml.klimt.color.HColor;
+import net.sourceforge.plantuml.klimt.creole.Display;
+import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.FontConfiguration;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
+import net.sourceforge.plantuml.klimt.font.UFont;
+import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
+import net.sourceforge.plantuml.klimt.shape.TextBlock;
+import net.sourceforge.plantuml.klimt.shape.ULine;
+import net.sourceforge.plantuml.klimt.sprite.SpriteContainerEmpty;
+import net.sourceforge.plantuml.project.TimeHeaderParameters;
+import net.sourceforge.plantuml.project.core.PrintScale;
+import net.sourceforge.plantuml.project.draw.TimeHeader;
+import net.sourceforge.plantuml.project.time.Day;
+import net.sourceforge.plantuml.project.timescale.TimeScale;
+import net.sourceforge.plantuml.style.PName;
+import net.sourceforge.plantuml.style.SName;
+
+public class TimeHeaderChronology extends TimeHeader {
+
+ private final PrintScale printScale;
+
+ @Override
+ public double getFullHeaderHeight(StringBounder stringBounder) {
+ return getTimeHeaderHeight(stringBounder) + getHeaderNameDayHeight();
+ }
+
+ @Override
+ public double getTimeHeaderHeight(StringBounder stringBounder) {
+ final double h = thParam.getStyle(SName.timeline, SName.day).value(PName.FontSize).asDouble();
+ return h + 6;
+ }
+
+ @Override
+ public double getTimeFooterHeight(StringBounder stringBounder) {
+ final double h = thParam.getStyle(SName.timeline, SName.day).value(PName.FontSize).asDouble();
+ return h + 6;
+ }
+
+ private double getHeaderNameDayHeight() {
+ return 0;
+ }
+
+ public TimeHeaderChronology(StringBounder stringBounder, TimeHeaderParameters thParam, PrintScale printScale,
+ TimeScaleChronology timeScale) {
+ super(thParam, timeScale);
+ this.printScale = printScale;
+ }
+
+ private void drawSmallVlinesDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) {
+ ug = ug.apply(getLineColor());
+ ug = ug.apply(UTranslate.dy(6));
+ final ULine vbar = ULine.vline(totalHeightWithoutFooter + 2);
+ for (Day i = getMin(); i.compareTo(getMax().increment()) < 0; i = i.increment(printScale)) {
+ final double x1 = timeScale.getStartingPosition(i);
+ ug.apply(UTranslate.dx(x1)).draw(vbar);
+ }
+ }
+
+ private void drawSimpleDayCounter(UGraphic ug, TimeScale timeScale) {
+ for (Day i = getMin(); i.compareTo(getMax().increment()) < 0; i = i.increment(printScale)) {
+ final UFont font = thParam.getStyle(SName.timeline, SName.day).getUFont();
+ final FontConfiguration fontConfiguration = getFontConfiguration(font, false, openFontColor());
+ final TextBlock num = Display.getWithNewlines(i.toStringShort(thParam.getLocale()))
+ .create(fontConfiguration, HorizontalAlignment.LEFT, new SpriteContainerEmpty());
+ final double x1 = timeScale.getStartingPosition(i);
+ final double x2;
+ if (printScale == PrintScale.WEEKLY)
+ x2 = timeScale.getEndingPosition(i.addDays(6));
+ else
+ x2 = timeScale.getEndingPosition(i);
+ final double width = num.calculateDimension(ug.getStringBounder()).getWidth();
+ final double delta = (x2 - x1) - width;
+ if (i.compareTo(getMax().increment()) < 0)
+ num.drawU(ug.apply(UTranslate.dx(x1 + delta / 2)));
+
+ }
+ }
+
+ @Override
+ public void drawTimeHeader(UGraphic ug, double totalHeightWithoutFooter) {
+ // drawTextsBackground(ug.apply(UTranslate.dy(-3)), totalHeightWithoutFooter +
+ // 6);
+ final double xmin = getTimeScale().getStartingPosition(getMin());
+ final double xmax = getTimeScale().getEndingPosition(getMax());
+ drawSmallVlinesDay(ug, getTimeScale(), totalHeightWithoutFooter);
+ // printVerticalSeparators(ug, totalHeightWithoutFooter);
+ drawSimpleDayCounter(ug, getTimeScale());
+ // ug = ug.apply(getLineColor());
+ // ug.draw(ULine.hline(xmax - xmin));
+ // ug.apply(UTranslate.dy(getFullHeaderHeight(ug.getStringBounder()) -
+ // 3)).draw(ULine.hline(xmax - xmin));
+
+ }
+
+ @Override
+ public void drawTimeFooter(UGraphic ug) {
+ final double xmin = getTimeScale().getStartingPosition(getMin());
+ final double xmax = getTimeScale().getEndingPosition(getMax());
+ ug = ug.apply(UTranslate.dy(3));
+ // drawSmallVlinesDay(ug, getTimeScale(),
+ // getTimeFooterHeight(ug.getStringBounder()) - 3);
+ drawSimpleDayCounter(ug, getTimeScale());
+ // ug.apply(getLineColor()).draw(ULine.hline(xmax - xmin));
+ }
+
+ // Duplicate in TimeHeaderDaily
+ class Pending {
+ final double x1;
+ double x2;
+ final HColor color;
+
+ Pending(HColor color, double x1, double x2) {
+ this.x1 = x1;
+ this.x2 = x2;
+ this.color = color;
+ }
+
+ public void draw(UGraphic ug, double height) {
+ drawRectangle(ug.apply(color.bg()), height, x1, x2);
+ }
+ }
+
+ protected final void drawTextsBackground(UGraphic ug, double totalHeightWithoutFooter) {
+
+ final double height = totalHeightWithoutFooter - getFullHeaderHeight(ug.getStringBounder());
+ Pending pending = null;
+
+ for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment()) {
+ final double x1 = getTimeScale().getStartingPosition(wink);
+ final double x2 = getTimeScale().getEndingPosition(wink);
+ HColor back = thParam.getColor(wink);
+// // Day of week should be stronger than period of time (back color).
+// final HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek());
+// if (backDoW != null) {
+// back = backDoW;
+// }
+// if (back == null && defaultPlan.getLoadAt(wink) == 0) {
+// back = closedBackgroundColor();
+// }
+ if (back == null) {
+ if (pending != null)
+ pending.draw(ug, height);
+ pending = null;
+ } else {
+ if (pending != null && pending.color.equals(back) == false) {
+ pending.draw(ug, height);
+ pending = null;
+ }
+ if (pending == null)
+ pending = new Pending(back, x1, x2);
+ else
+ pending.x2 = x2;
+
+ }
+ }
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/chronology/TimeScaleChronology.java b/src/net/sourceforge/plantuml/chronology/TimeScaleChronology.java
new file mode 100644
index 000000000..b77f714cd
--- /dev/null
+++ b/src/net/sourceforge/plantuml/chronology/TimeScaleChronology.java
@@ -0,0 +1,81 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.chronology;
+
+import net.sourceforge.plantuml.project.time.Day;
+import net.sourceforge.plantuml.project.timescale.TimeScale;
+
+public class TimeScaleChronology implements TimeScale {
+
+ private final double fullWidth;
+ private long min;
+ private long max;
+
+ public TimeScaleChronology(double fullWidth) {
+ this.fullWidth = fullWidth;
+ }
+
+ public double getStartingPosition(Day instant) {
+ final long wink = instant.getMillis();
+ if (wink < min)
+ throw new IllegalArgumentException();
+ if (wink > max)
+ throw new IllegalArgumentException();
+
+ return fullWidth * (wink - min) / (max - min);
+ }
+
+ public double getEndingPosition(Day instant) {
+ return getStartingPosition(instant);
+ }
+
+ public double getWidth(Day instant) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isBreaking(Day instant) {
+ throw new UnsupportedOperationException();
+ }
+
+ public final void setMin(long min) {
+ this.min = min;
+ }
+
+ public final void setMax(long max) {
+ this.max = max;
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/chronology/package-info.java b/src/net/sourceforge/plantuml/chronology/package-info.java
new file mode 100644
index 000000000..297264f3b
--- /dev/null
+++ b/src/net/sourceforge/plantuml/chronology/package-info.java
@@ -0,0 +1,9 @@
+/**
+ * Provides classes used to manage
+ *
+ * Chronology Diagram.
+ *
+ * @see net.sourceforge.plantuml.project
+ *
+ */
+package net.sourceforge.plantuml.chronology;
diff --git a/src/net/sourceforge/plantuml/chronology/readme.md b/src/net/sourceforge/plantuml/chronology/readme.md
new file mode 100644
index 000000000..59ffb89f4
--- /dev/null
+++ b/src/net/sourceforge/plantuml/chronology/readme.md
@@ -0,0 +1,10 @@
+# Directory Documentation for `chronology`
+
+## Description
+This package provides classes used to manage [Chronology Diagram](https://plantuml.com/chronology-diagram).
+
+## Link
+- [Chronology Diagram](https://plantuml.com/chronology-diagram)
+
+## Reference
+- [Gantt Diagram](https://plantuml.com/gantt-diagram)
diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java
index 7f42d13f0..0b5c8cd73 100644
--- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java
+++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java
@@ -58,6 +58,7 @@ import net.sourceforge.plantuml.regex.RegexOr;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotag;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -101,9 +102,7 @@ public class CommandCreateClass extends SingleLineCommand2 {
new RegexLeaf("GENERIC", "\\<(" + GenericRegexProducer.PATTERN + ")\\>"))), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java
index 2ddf84b86..ac36c3685 100644
--- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java
+++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java
@@ -65,6 +65,7 @@ import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.skin.VisibilityModifier;
import net.sourceforge.plantuml.stereo.Stereotag;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.text.StringLocated;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
@@ -115,9 +116,7 @@ public class CommandCreateClassMultilines extends CommandMultilines2"))), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.+\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
@@ -128,10 +127,16 @@ public class CommandCreateClassMultilines extends CommandMultilines2"))) //
+ )), //
new RegexOptional(new RegexConcat(RegexLeaf.spaceOneOrMore(),
new RegexLeaf("IMPLEMENTS",
- "(implements)[%s]+(" + CommandCreateClassMultilines.CODES + "|[%g]([^%g]+)[%g])"))), //
+ "(implements)[%s]+(" + CommandCreateClassMultilines.CODES + "|[%g]([^%g]+)[%g])"),
+ new RegexOptional(new RegexConcat(RegexLeaf.spaceZeroOrMore(),
+ new RegexLeaf("\\<(" + GenericRegexProducer.PATTERN + ")\\>"))) //
+ )), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("\\{"), //
RegexLeaf.spaceZeroOrMore(), //
diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateElementFull2.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateElementFull2.java
index 906f0d877..cb1a677e8 100644
--- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateElementFull2.java
+++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateElementFull2.java
@@ -53,11 +53,11 @@ import net.sourceforge.plantuml.klimt.font.FontParam;
import net.sourceforge.plantuml.plasma.Quark;
import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
-import net.sourceforge.plantuml.regex.RegexOptional;
import net.sourceforge.plantuml.regex.RegexOr;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotag;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -88,21 +88,14 @@ public class CommandCreateElementFull2 extends SingleLineCommand2
new RegexLeaf("CODE1", CommandCreateElementFull.CODE_WITH_QUOTE), //
new RegexConcat(//
new RegexLeaf("DISPLAY2", CommandCreateElementFull.DISPLAY), //
- new RegexOptional( //
- new RegexConcat( //
- RegexLeaf.spaceOneOrMore(), //
- new RegexLeaf("STEREOTYPE2", "(\\<\\<.+\\>\\>)") //
- )), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE2"), //
new RegexLeaf("as"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("CODE2", CommandCreateElementFull.CODE)) //
), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE", "(\\<\\<.+\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE"), //
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
@@ -118,21 +111,14 @@ public class CommandCreateElementFull2 extends SingleLineCommand2
new RegexLeaf("CODE1", CommandCreateElementFull.CODE_WITH_QUOTE), //
new RegexConcat(//
new RegexLeaf("DISPLAY2", CommandCreateElementFull.DISPLAY), //
- new RegexOptional( //
- new RegexConcat( //
- RegexLeaf.spaceOneOrMore(), //
- new RegexLeaf("STEREOTYPE2", "(\\<\\<.+\\>\\>)") //
- )), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE2"), //
new RegexLeaf("as"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("CODE2", CommandCreateElementFull.CODE)) //
), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE", "(\\<\\<.+\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE"), //
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandStereotype.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandStereotype.java
index d4b8686b5..4d762c4f8 100644
--- a/src/net/sourceforge/plantuml/classdiagram/command/CommandStereotype.java
+++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandStereotype.java
@@ -47,6 +47,7 @@ import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.utils.LineLocation;
public class CommandStereotype extends SingleLineCommand2 {
@@ -60,7 +61,8 @@ public class CommandStereotype extends SingleLineCommand2 {
RegexLeaf.start(), //
new RegexLeaf("NAME", "([%pLN_.]+|[%g][^%g]+[%g])"), //
RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)"), RegexLeaf.end()); //
+ StereotypePattern.mandatory("STEREO"), //
+ RegexLeaf.end()); //
}
@Override
diff --git a/src/net/sourceforge/plantuml/code/CompressionGZip.java b/src/net/sourceforge/plantuml/code/CompressionGZip.java
new file mode 100644
index 000000000..0f87d56ef
--- /dev/null
+++ b/src/net/sourceforge/plantuml/code/CompressionGZip.java
@@ -0,0 +1,71 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.code;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.GZIPInputStream;
+
+public class CompressionGZip implements Compression {
+ // ::remove file when __CORE__
+
+ public byte[] compress(byte[] in) {
+ throw new UnsupportedOperationException();
+ }
+
+ public ByteArray decompress(byte[] input) throws NoPlantumlCompressionException {
+ try {
+ try (final GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(input))) {
+ final byte[] buffer = new byte[10_000];
+
+ try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+ int len;
+ while ((len = gzip.read(buffer)) > 0) {
+ baos.write(buffer, 0, len);
+ if (baos.size() > 200_000)
+ throw new NoPlantumlCompressionException("Gzip error");
+ }
+ return ByteArray.from(baos.toByteArray());
+ }
+ }
+ } catch (IOException e) {
+ throw new NoPlantumlCompressionException(e);
+ }
+
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/code/TranscoderSmart.java b/src/net/sourceforge/plantuml/code/TranscoderSmart.java
index 072bbd27c..dbf5a2bb2 100644
--- a/src/net/sourceforge/plantuml/code/TranscoderSmart.java
+++ b/src/net/sourceforge/plantuml/code/TranscoderSmart.java
@@ -49,6 +49,8 @@ public class TranscoderSmart implements Transcoder {
new CompressionHuffman());
private final Transcoder zip = TranscoderImpl.utf8(new AsciiEncoder(), new ArobaseStringCompressor(),
new CompressionZip());
+ private final Transcoder gzip = TranscoderImpl.utf8(new AsciiEncoder(), new ArobaseStringCompressor(),
+ new CompressionGZip());
// ::done
public String decode(String code) throws NoPlantumlCompressionException {
@@ -66,6 +68,9 @@ public class TranscoderSmart implements Transcoder {
if (code.startsWith("~h"))
return hexOnly.decode(code.substring(2));
+ if (code.startsWith("~g"))
+ return gzip.decode(code.substring(2));
+
// ::comment when __CORE__
if (code.startsWith("~zip~"))
return zip.decode(code.substring(5));
diff --git a/src/net/sourceforge/plantuml/code/TranscoderSmartProtected.java b/src/net/sourceforge/plantuml/code/TranscoderSmartProtected.java
index f0b2dc7ca..61aefd6df 100644
--- a/src/net/sourceforge/plantuml/code/TranscoderSmartProtected.java
+++ b/src/net/sourceforge/plantuml/code/TranscoderSmartProtected.java
@@ -49,6 +49,8 @@ public class TranscoderSmartProtected implements Transcoder {
new CompressionNone());
private final Transcoder zip = TranscoderImpl.utf8(new AsciiEncoder(), new ArobaseStringCompressor(),
new CompressionZip());
+ private final Transcoder gzip = TranscoderImpl.utf8(new AsciiEncoder(), new ArobaseStringCompressor(),
+ new CompressionGZip());
public String decode(String code) throws NoPlantumlCompressionException {
// Work in progress
@@ -63,6 +65,9 @@ public class TranscoderSmartProtected implements Transcoder {
if (code.startsWith("~h"))
return hexOnly.decode(code.substring(2));
+ if (code.startsWith("~g"))
+ return gzip.decode(code.substring(2));
+
if (code.startsWith("~zip~"))
return zip.decode(code.substring(5));
diff --git a/src/net/sourceforge/plantuml/command/CommandNamespace.java b/src/net/sourceforge/plantuml/command/CommandNamespace.java
index 67cf02b22..9404cd513 100644
--- a/src/net/sourceforge/plantuml/command/CommandNamespace.java
+++ b/src/net/sourceforge/plantuml/command/CommandNamespace.java
@@ -50,6 +50,7 @@ import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -68,9 +69,7 @@ public class CommandNamespace extends SingleLineCommand2 {
new RegexLeaf("namespace"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("NAME", NAMESPACE_REGEX), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE"), //
UrlBuilder.OPTIONAL, //
RegexLeaf.spaceZeroOrMore(), //
ColorParser.exp1(), //
diff --git a/src/net/sourceforge/plantuml/command/CommandNamespace2.java b/src/net/sourceforge/plantuml/command/CommandNamespace2.java
index 768b1a181..f32845c77 100644
--- a/src/net/sourceforge/plantuml/command/CommandNamespace2.java
+++ b/src/net/sourceforge/plantuml/command/CommandNamespace2.java
@@ -48,6 +48,7 @@ import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -72,9 +73,7 @@ public class CommandNamespace2 extends SingleLineCommand2 {
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("NAME", CommandNamespace.NAMESPACE_REGEX), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE"), //
UrlBuilder.OPTIONAL, //
RegexLeaf.spaceZeroOrMore(), //
ColorParser.exp1(), //
diff --git a/src/net/sourceforge/plantuml/command/CommandNamespaceEmpty.java b/src/net/sourceforge/plantuml/command/CommandNamespaceEmpty.java
index 6e9e9c81b..00a0ab641 100644
--- a/src/net/sourceforge/plantuml/command/CommandNamespaceEmpty.java
+++ b/src/net/sourceforge/plantuml/command/CommandNamespaceEmpty.java
@@ -48,6 +48,7 @@ import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -64,9 +65,7 @@ public class CommandNamespaceEmpty extends SingleLineCommand2 {
new RegexLeaf("namespace"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("NAME", CommandNamespace.NAMESPACE_REGEX), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE"), //
UrlBuilder.OPTIONAL, //
RegexLeaf.spaceZeroOrMore(), //
ColorParser.exp1(), //
diff --git a/src/net/sourceforge/plantuml/command/CommandPackage.java b/src/net/sourceforge/plantuml/command/CommandPackage.java
index d0d64c477..934bd4020 100644
--- a/src/net/sourceforge/plantuml/command/CommandPackage.java
+++ b/src/net/sourceforge/plantuml/command/CommandPackage.java
@@ -55,6 +55,7 @@ import net.sourceforge.plantuml.regex.RegexOptional;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotag;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -80,9 +81,7 @@ public class CommandPackage extends SingleLineCommand2 {
)), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE"), //
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
diff --git a/src/net/sourceforge/plantuml/command/note/CommandFactoryNote.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryNote.java
index 65a763e9b..bc89bf64a 100644
--- a/src/net/sourceforge/plantuml/command/note/CommandFactoryNote.java
+++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryNote.java
@@ -55,6 +55,7 @@ import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotag;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.utils.BlocLines;
import net.sourceforge.plantuml.utils.LineLocation;
@@ -70,9 +71,7 @@ public final class CommandFactoryNote implements SingleMultiFactoryCommand\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
ColorParser.exp1(), //
RegexLeaf.end() //
);
@@ -91,9 +90,7 @@ public final class CommandFactoryNote implements SingleMultiFactoryCommand\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
ColorParser.exp1(), //
RegexLeaf.end() //
);
diff --git a/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnEntity.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnEntity.java
index 363f8809e..f3d7f37ea 100644
--- a/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnEntity.java
+++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryNoteOnEntity.java
@@ -63,6 +63,7 @@ import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.skin.ColorParam;
import net.sourceforge.plantuml.stereo.Stereotag;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -92,9 +93,7 @@ public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryComma
new RegexLeaf("")), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
RegexLeaf.spaceZeroOrMore(), //
color().getRegex(), //
@@ -127,9 +126,7 @@ public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryComma
new RegexLeaf("")), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
RegexLeaf.spaceZeroOrMore(), //
color().getRegex(), //
@@ -153,9 +150,7 @@ public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryComma
new RegexLeaf("")), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
RegexLeaf.spaceZeroOrMore(), //
color().getRegex(), //
diff --git a/src/net/sourceforge/plantuml/command/note/CommandFactoryTipOnEntity.java b/src/net/sourceforge/plantuml/command/note/CommandFactoryTipOnEntity.java
index bdfac6571..edfb84034 100644
--- a/src/net/sourceforge/plantuml/command/note/CommandFactoryTipOnEntity.java
+++ b/src/net/sourceforge/plantuml/command/note/CommandFactoryTipOnEntity.java
@@ -61,6 +61,7 @@ import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.skin.ColorParam;
import net.sourceforge.plantuml.stereo.Stereotag;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -89,9 +90,7 @@ public final class CommandFactoryTipOnEntity implements SingleMultiFactoryComman
partialPattern, //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
RegexLeaf.spaceZeroOrMore(), //
ColorParser.exp1(), //
@@ -112,9 +111,7 @@ public final class CommandFactoryTipOnEntity implements SingleMultiFactoryComman
partialPattern, //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
RegexLeaf.spaceZeroOrMore(), //
ColorParser.exp1(), //
diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteAcrossCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteAcrossCommand.java
index ccbbfb5ad..a93e0bafe 100644
--- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteAcrossCommand.java
+++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteAcrossCommand.java
@@ -57,6 +57,7 @@ import net.sourceforge.plantuml.sequencediagram.Participant;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagram;
import net.sourceforge.plantuml.skin.ColorParam;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -70,13 +71,9 @@ public final class FactorySequenceNoteAcrossCommand implements SingleMultiFactor
new RegexLeaf("VMERGE", "(/)?"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("STYLE", "(note|hnote|rnote)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO1", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO1"), //
new RegexLeaf("ACROSS", "(accross|across)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO2", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO2"), //
color().getRegex(), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
@@ -89,13 +86,9 @@ public final class FactorySequenceNoteAcrossCommand implements SingleMultiFactor
new RegexLeaf("VMERGE", "(/)?"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("STYLE", "(note|hnote|rnote)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO1", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO1"), //
new RegexLeaf("ACROSS", "(accross|across)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO2", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO2"), //
color().getRegex(), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java
index fb6a746fb..c5a0d4596 100644
--- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java
+++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java
@@ -59,6 +59,7 @@ import net.sourceforge.plantuml.sequencediagram.Participant;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagram;
import net.sourceforge.plantuml.skin.ColorParam;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -66,7 +67,7 @@ import net.sourceforge.plantuml.utils.BlocLines;
import net.sourceforge.plantuml.utils.LineLocation;
public final class FactorySequenceNoteCommand implements SingleMultiFactoryCommand {
- // ::remove folder when __HAXE__
+ // ::remove folder when __HAXE__
private IRegex getRegexConcatMultiLine() {
return RegexConcat.build(FactorySequenceNoteCommand.class.getName() + "multi", RegexLeaf.start(), //
@@ -74,15 +75,11 @@ public final class FactorySequenceNoteCommand implements SingleMultiFactoryComma
new RegexLeaf("VMERGE", "(/)?"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("STYLE", "(note|hnote|rnote)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO1", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO1"), //
new RegexLeaf("POSITION", "(right|left|over)"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("PARTICIPANT", "(?:of[%s]+)?([%pLN_.@]+|[%g][^%g]+[%g])"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO2", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO2"), //
color().getRegex(), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
@@ -95,15 +92,11 @@ public final class FactorySequenceNoteCommand implements SingleMultiFactoryComma
new RegexLeaf("VMERGE", "(/)?"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("STYLE", "(note|hnote|rnote)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO1", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO1"), //
new RegexLeaf("POSITION", "(right|left|over)"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("PARTICIPANT", "(?:of[%s])?([%pLN_.@]+|[%g][^%g]+[%g])"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO2", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO2"), //
color().getRegex(), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java
index f886d749f..556b146da 100644
--- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java
+++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java
@@ -60,6 +60,7 @@ import net.sourceforge.plantuml.sequencediagram.NoteStyle;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagram;
import net.sourceforge.plantuml.skin.ColorParam;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -72,13 +73,9 @@ public final class FactorySequenceNoteOnArrowCommand implements SingleMultiFacto
return RegexConcat.build(FactorySequenceNoteOnArrowCommand.class.getName() + "multi", RegexLeaf.start(), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("STYLE", "(note|hnote|rnote)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO1", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceOneOrMore(), //
+ StereotypePattern.optional("STEREO1"), //
new RegexLeaf("POSITION", "(right|left|bottom|top)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO2", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO2"), //
ColorParser.exp1(), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
@@ -89,13 +86,9 @@ public final class FactorySequenceNoteOnArrowCommand implements SingleMultiFacto
return RegexConcat.build(FactorySequenceNoteOnArrowCommand.class.getName() + "single", RegexLeaf.start(), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("STYLE", "(note|hnote|rnote)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO1", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceOneOrMore(), //
+ StereotypePattern.optional("STEREO1"), //
new RegexLeaf("POSITION", "(right|left|bottom|top)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO2", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO2"), //
ColorParser.exp1(), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java
index 52154e96e..a2ceee953 100644
--- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java
+++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java
@@ -58,6 +58,7 @@ import net.sourceforge.plantuml.sequencediagram.Participant;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagram;
import net.sourceforge.plantuml.skin.ColorParam;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -72,9 +73,7 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF
new RegexLeaf("VMERGE", "(/)?"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("STYLE", "(note|hnote|rnote)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO1", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO1"), //
new RegexLeaf("over"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("P1", "([%pLN_.@]+|[%g][^%g]+[%g])"), //
@@ -82,9 +81,7 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF
new RegexLeaf(","), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("P2", "([%pLN_.@]+|[%g][^%g]+[%g])"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO2", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO2"), //
color().getRegex(), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
@@ -98,9 +95,7 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF
new RegexLeaf("VMERGE", "(/)?"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("STYLE", "(note|hnote|rnote)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO1", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO1"), //
new RegexLeaf("over"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("P1", "([%pLN_.@]+|[%g][^%g]+[%g])"), //
@@ -108,9 +103,7 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF
new RegexLeaf(","), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("P2", "([%pLN_.@]+|[%g][^%g]+[%g])"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO2", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO2"), //
color().getRegex(), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
diff --git a/src/net/sourceforge/plantuml/core/Diagram.java b/src/net/sourceforge/plantuml/core/Diagram.java
index 368d0b926..18ce748ff 100644
--- a/src/net/sourceforge/plantuml/core/Diagram.java
+++ b/src/net/sourceforge/plantuml/core/Diagram.java
@@ -68,7 +68,7 @@ public interface Diagram {
*/
ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException;
- void exportDiagramGraphic(UGraphic ug);
+ void exportDiagramGraphic(UGraphic ug, FileFormatOption fileFormat);
/**
* Number of images in this diagram (usually, 1)
diff --git a/src/net/sourceforge/plantuml/core/DiagramType.java b/src/net/sourceforge/plantuml/core/DiagramType.java
index 3b6ae6270..24a92b7e3 100644
--- a/src/net/sourceforge/plantuml/core/DiagramType.java
+++ b/src/net/sourceforge/plantuml/core/DiagramType.java
@@ -38,9 +38,9 @@ package net.sourceforge.plantuml.core;
import net.sourceforge.plantuml.utils.StartUtils;
public enum DiagramType {
- // ::remove folder when __HAXE__
- UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, MATH, LATEX, DEFINITION, GANTT, NW,
- MINDMAP, WBS, WIRE, JSON, GIT, BOARD, YAML, HCL, EBNF, REGEX, FILES, CHEN_EER, UNKNOWN;
+ // ::remove folder when __HAXE__
+ UML, BPM, DITAA, DOT, PROJECT, JCCKIT, SALT, FLOW, CREOLE, MATH, LATEX, DEFINITION, GANTT, CHRONOLOGY, NW, MINDMAP,
+ WBS, WIRE, JSON, GIT, BOARD, YAML, HCL, EBNF, REGEX, FILES, CHEN_EER, UNKNOWN;
static public DiagramType getTypeFromArobaseStart(String s) {
s = s.toLowerCase();
@@ -59,7 +59,8 @@ public enum DiagramType {
if (StartUtils.startsWithSymbolAnd("startdot", s))
return DOT;
- // ::comment when __CORE__ or __MIT__ or __EPL__ or __BSD__ or __ASL__ or __LGPL__
+ // ::comment when __CORE__ or __MIT__ or __EPL__ or __BSD__ or __ASL__ or
+ // __LGPL__
if (StartUtils.startsWithSymbolAnd("startjcckit", s))
return JCCKIT;
// ::done
@@ -126,9 +127,6 @@ public enum DiagramType {
if (StartUtils.startsWithSymbolAnd("startfiles", s))
return FILES;
- if (StartUtils.startsWithSymbolAnd("startchen", s))
- return CHEN_EER;
-
return UNKNOWN;
}
}
diff --git a/src/net/sourceforge/plantuml/core/UmlSource.java b/src/net/sourceforge/plantuml/core/UmlSource.java
index 97b5ccc7b..0dacdc5ef 100755
--- a/src/net/sourceforge/plantuml/core/UmlSource.java
+++ b/src/net/sourceforge/plantuml/core/UmlSource.java
@@ -158,7 +158,10 @@ final public class UmlSource {
// return Collections.unmodifiableCollection(rawSource).iterator();
// }
-
+ /**
+ * @deprecated Use {@link #getPlainString(String)} instead,
+ * like getPlainString("\n")
+ */
@Deprecated()
public String getPlainString() {
return getPlainString("\n");
diff --git a/src/net/sourceforge/plantuml/cucadiagram/DisplaySection.java b/src/net/sourceforge/plantuml/cucadiagram/DisplaySection.java
index 6f4328614..c3248e6b6 100644
--- a/src/net/sourceforge/plantuml/cucadiagram/DisplaySection.java
+++ b/src/net/sourceforge/plantuml/cucadiagram/DisplaySection.java
@@ -38,6 +38,7 @@ package net.sourceforge.plantuml.cucadiagram;
import java.util.EnumMap;
import java.util.Map;
+import net.sourceforge.plantuml.klimt.LineBreakStrategy;
import net.sourceforge.plantuml.klimt.creole.Display;
import net.sourceforge.plantuml.klimt.font.FontConfiguration;
import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
@@ -96,7 +97,8 @@ public class DisplaySection {
return null;
if (style != null)
- return style.createTextBlockBordered(display, spriteContainer.getIHtmlColorSet(), spriteContainer, null);
+ return style.createTextBlockBordered(display, spriteContainer.getIHtmlColorSet(), spriteContainer, null,
+ LineBreakStrategy.NONE);
return display.create(fontConfiguration, getHorizontalAlignment(), spriteContainer);
}
diff --git a/src/net/sourceforge/plantuml/decoration/symbol/USymbolAction.java b/src/net/sourceforge/plantuml/decoration/symbol/USymbolAction.java
new file mode 100644
index 000000000..7ee042799
--- /dev/null
+++ b/src/net/sourceforge/plantuml/decoration/symbol/USymbolAction.java
@@ -0,0 +1,145 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.decoration.symbol;
+
+import net.sourceforge.plantuml.klimt.Fashion;
+import net.sourceforge.plantuml.klimt.Shadowable;
+import net.sourceforge.plantuml.klimt.UPath;
+import net.sourceforge.plantuml.klimt.UTranslate;
+import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.drawing.UGraphicStencil;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
+import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
+import net.sourceforge.plantuml.klimt.geom.XDimension2D;
+import net.sourceforge.plantuml.klimt.shape.AbstractTextBlock;
+import net.sourceforge.plantuml.klimt.shape.TextBlock;
+import net.sourceforge.plantuml.klimt.shape.TextBlockUtils;
+import net.sourceforge.plantuml.klimt.shape.UPolygon;
+import net.sourceforge.plantuml.klimt.shape.URectangle;
+import net.sourceforge.plantuml.style.SName;
+
+class USymbolAction extends USymbol {
+
+ private final SName sname;
+
+ public USymbolAction(SName sname) {
+ this.sname = sname;
+ }
+
+ @Override
+ public SName getSName() {
+ return sname;
+ }
+
+ private void drawAction(UGraphic ug, double width, double height, double shadowing, double roundCorner,
+ double diagonalCorner) {
+ final UPolygon shape = new UPolygon();
+ shape.addPoint(0, 0);
+ shape.addPoint(width - 10, 0);
+ shape.addPoint(width, height / 2);
+ shape.addPoint(width - 10, height);
+ shape.addPoint(0, height);
+ ug.draw(shape);
+ }
+
+ private Margin getMargin() {
+ return new Margin(10, 20, 10, 10);
+ }
+
+ @Override
+ public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype,
+ final Fashion symbolContext, final HorizontalAlignment stereoAlignment) {
+ return new AbstractTextBlock() {
+
+ public void drawU(UGraphic ug) {
+ final XDimension2D dim = calculateDimension(ug.getStringBounder());
+ ug = UGraphicStencil.create(ug, dim);
+ ug = symbolContext.apply(ug);
+ drawAction(ug, dim.getWidth(), dim.getHeight(), symbolContext.getDeltaShadow(),
+ symbolContext.getRoundCorner(), symbolContext.getDiagonalCorner());
+ final Margin margin = getMargin();
+ final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, stereoAlignment);
+ tb.drawU(ug.apply(new UTranslate(margin.getX1(), margin.getY1())));
+ }
+
+ public XDimension2D calculateDimension(StringBounder stringBounder) {
+ final XDimension2D dimLabel = label.calculateDimension(stringBounder);
+ final XDimension2D dimStereo = stereotype.calculateDimension(stringBounder);
+ return getMargin().addDimension(dimStereo.mergeTB(dimLabel));
+ }
+ };
+ }
+
+ private double getHTitle(XDimension2D dimTitle) {
+ final double htitle;
+ if (dimTitle.getWidth() == 0)
+ htitle = 10;
+ else
+ htitle = dimTitle.getHeight();
+
+ return htitle;
+ }
+
+
+
+ @Override
+ public TextBlock asBig(final TextBlock title, final HorizontalAlignment labelAlignment, final TextBlock stereotype,
+ final double width, final double height, final Fashion symbolContext,
+ final HorizontalAlignment stereoAlignment) {
+ return new AbstractTextBlock() {
+
+ public void drawU(UGraphic ug) {
+ final StringBounder stringBounder = ug.getStringBounder();
+ final XDimension2D dim = calculateDimension(stringBounder);
+ ug = symbolContext.apply(ug);
+ final XDimension2D dimTitle = title.calculateDimension(stringBounder);
+ drawAction(ug, dim.getWidth(), dim.getHeight(), symbolContext.getDeltaShadow(),
+ symbolContext.getRoundCorner(), symbolContext.getDiagonalCorner());
+ final double posTitle = (width - dimTitle.getWidth()) / 2;
+ title.drawU(ug.apply(new UTranslate(posTitle, 2)));
+ final XDimension2D dimStereo = stereotype.calculateDimension(stringBounder);
+ final double posStereo = (width - dimStereo.getWidth()) / 2;
+
+ stereotype.drawU(ug.apply(new UTranslate(4 + posStereo, 2 + getHTitle(dimTitle))));
+ }
+
+ public XDimension2D calculateDimension(StringBounder stringBounder) {
+ return new XDimension2D(width, height);
+ }
+ };
+ }
+
+}
\ No newline at end of file
diff --git a/src/net/sourceforge/plantuml/decoration/symbol/USymbolProcess.java b/src/net/sourceforge/plantuml/decoration/symbol/USymbolProcess.java
new file mode 100644
index 000000000..e8bcb9315
--- /dev/null
+++ b/src/net/sourceforge/plantuml/decoration/symbol/USymbolProcess.java
@@ -0,0 +1,144 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.decoration.symbol;
+
+import net.sourceforge.plantuml.klimt.Fashion;
+import net.sourceforge.plantuml.klimt.Shadowable;
+import net.sourceforge.plantuml.klimt.UPath;
+import net.sourceforge.plantuml.klimt.UTranslate;
+import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.drawing.UGraphicStencil;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
+import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
+import net.sourceforge.plantuml.klimt.geom.XDimension2D;
+import net.sourceforge.plantuml.klimt.shape.AbstractTextBlock;
+import net.sourceforge.plantuml.klimt.shape.TextBlock;
+import net.sourceforge.plantuml.klimt.shape.TextBlockUtils;
+import net.sourceforge.plantuml.klimt.shape.UPolygon;
+import net.sourceforge.plantuml.klimt.shape.URectangle;
+import net.sourceforge.plantuml.style.SName;
+
+class USymbolProcess extends USymbol {
+
+ private final SName sname;
+
+ public USymbolProcess(SName sname) {
+ this.sname = sname;
+ }
+
+ @Override
+ public SName getSName() {
+ return sname;
+ }
+
+ private void drawProcess(UGraphic ug, double width, double height, double shadowing, double roundCorner,
+ double diagonalCorner) {
+ final UPolygon shape = new UPolygon();
+ shape.addPoint(0, 0);
+ shape.addPoint(width - 10, 0);
+ shape.addPoint(width, height / 2);
+ shape.addPoint(width - 10, height);
+ shape.addPoint(0, height);
+ shape.addPoint(10, height / 2);
+ ug.draw(shape);
+ }
+
+ private Margin getMargin() {
+ return new Margin(20, 20, 10, 10);
+ }
+
+ @Override
+ public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype,
+ final Fashion symbolContext, final HorizontalAlignment stereoAlignment) {
+ return new AbstractTextBlock() {
+
+ public void drawU(UGraphic ug) {
+ final XDimension2D dim = calculateDimension(ug.getStringBounder());
+ ug = UGraphicStencil.create(ug, dim);
+ ug = symbolContext.apply(ug);
+ drawProcess(ug, dim.getWidth(), dim.getHeight(), symbolContext.getDeltaShadow(),
+ symbolContext.getRoundCorner(), symbolContext.getDiagonalCorner());
+ final Margin margin = getMargin();
+ final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, stereoAlignment);
+ tb.drawU(ug.apply(new UTranslate(margin.getX1(), margin.getY1())));
+ }
+
+ public XDimension2D calculateDimension(StringBounder stringBounder) {
+ final XDimension2D dimLabel = label.calculateDimension(stringBounder);
+ final XDimension2D dimStereo = stereotype.calculateDimension(stringBounder);
+ return getMargin().addDimension(dimStereo.mergeTB(dimLabel));
+ }
+ };
+ }
+
+ private double getHTitle(XDimension2D dimTitle) {
+ final double htitle;
+ if (dimTitle.getWidth() == 0)
+ htitle = 10;
+ else
+ htitle = dimTitle.getHeight();
+
+ return htitle;
+ }
+
+ @Override
+ public TextBlock asBig(final TextBlock title, final HorizontalAlignment labelAlignment, final TextBlock stereotype,
+ final double width, final double height, final Fashion symbolContext,
+ final HorizontalAlignment stereoAlignment) {
+ return new AbstractTextBlock() {
+
+ public void drawU(UGraphic ug) {
+ final StringBounder stringBounder = ug.getStringBounder();
+ final XDimension2D dim = calculateDimension(stringBounder);
+ ug = symbolContext.apply(ug);
+ final XDimension2D dimTitle = title.calculateDimension(stringBounder);
+ drawProcess(ug, dim.getWidth(), dim.getHeight(), symbolContext.getDeltaShadow(),
+ symbolContext.getRoundCorner(), symbolContext.getDiagonalCorner());
+ final double posTitle = (width - dimTitle.getWidth()) / 2;
+ title.drawU(ug.apply(new UTranslate(posTitle, 2)));
+ final XDimension2D dimStereo = stereotype.calculateDimension(stringBounder);
+ final double posStereo = (width - dimStereo.getWidth()) / 2;
+
+ stereotype.drawU(ug.apply(new UTranslate(4 + posStereo, 2 + getHTitle(dimTitle))));
+ }
+
+ public XDimension2D calculateDimension(StringBounder stringBounder) {
+ return new XDimension2D(width, height);
+ }
+ };
+ }
+
+}
\ No newline at end of file
diff --git a/src/net/sourceforge/plantuml/decoration/symbol/USymbols.java b/src/net/sourceforge/plantuml/decoration/symbol/USymbols.java
index b2f64a4a2..98758878f 100644
--- a/src/net/sourceforge/plantuml/decoration/symbol/USymbols.java
+++ b/src/net/sourceforge/plantuml/decoration/symbol/USymbols.java
@@ -70,6 +70,8 @@ public abstract class USymbols {
public final static USymbol FOLDER = record("FOLDER", new USymbolFolder(SName.folder, false));
public final static USymbol FILE = record("FILE", new USymbolFile());
public final static USymbol RECTANGLE = record("RECTANGLE", new USymbolRectangle(SName.rectangle));
+ public final static USymbol ACTION = record("ACTION", new USymbolAction(SName.action));
+ public final static USymbol PROCESS = record("PROCESS", new USymbolProcess(SName.process));
public final static USymbol HEXAGON = record("HEXAGON", new USymbolHexagon());
public final static USymbol PERSON = record("PERSON", new USymbolPerson());
public final static USymbol LABEL = record("LABEL", new USymbolLabel());
@@ -142,6 +144,10 @@ public abstract class USymbols {
usymbol = USymbols.FRAME;
else if (symbol.equalsIgnoreCase("cloud"))
usymbol = USymbols.CLOUD;
+ else if (symbol.equalsIgnoreCase("action"))
+ usymbol = USymbols.ACTION;
+ else if (symbol.equalsIgnoreCase("process"))
+ usymbol = USymbols.PROCESS;
else if (symbol.equalsIgnoreCase("database"))
usymbol = USymbols.DATABASE;
else if (symbol.equalsIgnoreCase("queue"))
diff --git a/src/net/sourceforge/plantuml/descdiagram/CommandCreateDomain.java b/src/net/sourceforge/plantuml/descdiagram/CommandCreateDomain.java
index 10e4f354c..43864b44d 100644
--- a/src/net/sourceforge/plantuml/descdiagram/CommandCreateDomain.java
+++ b/src/net/sourceforge/plantuml/descdiagram/CommandCreateDomain.java
@@ -53,6 +53,7 @@ import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -73,11 +74,11 @@ public class CommandCreateDomain extends SingleLineCommand2
new RegexLeaf("DISPLAY", DISPLAY_WITH_GENERIC), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("as"), //
- RegexLeaf.spaceOneOrMore(), new RegexLeaf("CODE", "([a-zA-Z0-9]+)"), RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.+\\>\\>)?"), //
+ RegexLeaf.spaceOneOrMore(), //
+ new RegexLeaf("CODE", "([a-zA-Z0-9]+)"), //
+ StereotypePattern.optional("STEREO"), //
// domain: lexical, causal, biddable
// requirement: FR, NFR, quality
- RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("GROUP", "(\\{)?"), RegexLeaf.end());
}
diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java
index 7bc02b008..cfa09179c 100644
--- a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java
+++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java
@@ -56,6 +56,7 @@ import net.sourceforge.plantuml.regex.RegexOptional;
import net.sourceforge.plantuml.regex.RegexOr;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.utils.LineLocation;
public class CommandArchimate extends SingleLineCommand2 {
@@ -74,44 +75,25 @@ public class CommandArchimate extends SingleLineCommand2 {
new RegexLeaf("CODE1", CommandCreateElementFull.CODE_WITH_QUOTE), //
new RegexConcat(//
new RegexLeaf("DISPLAY2", CommandCreateElementFull.DISPLAY), //
- new RegexOptional( //
- new RegexConcat( //
- RegexLeaf.spaceOneOrMore(), //
- new RegexLeaf("STEREOTYPE2", "(?:\\<\\<([-\\w]+)\\>\\>)") //
- )), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optionalArchimate("STEREOTYPE2"), //
new RegexLeaf("as"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("CODE2", CommandCreateElementFull.CODE)), //
new RegexConcat(//
new RegexLeaf("CODE3", CommandCreateElementFull.CODE), //
- new RegexOptional( //
- new RegexConcat( //
- RegexLeaf.spaceOneOrMore(), //
- new RegexLeaf("STEREOTYPE3", "(?:\\<\\<([-\\w]+)\\>\\>)") //
- )), //
- RegexLeaf.spaceOneOrMore(), //
+ StereotypePattern.optionalArchimate("STEREOTYPE3"), //
new RegexLeaf("as"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("DISPLAY3", CommandCreateElementFull.DISPLAY)), //
new RegexConcat(//
new RegexLeaf("DISPLAY4", CommandCreateElementFull.DISPLAY_WITHOUT_QUOTE), //
- new RegexOptional( //
- new RegexConcat( //
- RegexLeaf.spaceOneOrMore(), //
- new RegexLeaf("STEREOTYPE4", "(?:\\<\\<([-\\w]+)\\>\\>)") //
- )), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optionalArchimate("STEREOTYPE4"), //
new RegexLeaf("as"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("CODE4", CommandCreateElementFull.CODE)) //
), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexOptional( //
- new RegexConcat( //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE", "(?:\\<\\<([-\\w]+)\\>\\>)") //
- )), RegexLeaf.end());
+ StereotypePattern.optionalArchimate("STEREOTYPE"), //
+ RegexLeaf.end());
}
private static ColorParser color() {
@@ -134,7 +116,7 @@ public class CommandArchimate extends SingleLineCommand2 {
entity = diagram.reallyCreateLeaf(quark, Display.getWithNewlines(display), LeafType.DESCRIPTION,
USymbols.ARCHIMATE);
- final String icon = arg.getLazzy("STEREOTYPE", 0);
+ final String icon = StereotypePattern.removeChevronBrackets(arg.getLazzy("STEREOTYPE", 0));
entity.setDisplay(Display.getWithNewlines(display));
entity.setUSymbol(USymbols.ARCHIMATE);
diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java
index 11cccd9bc..5aa5f5012 100644
--- a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java
+++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java
@@ -56,6 +56,7 @@ import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexOptional;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.utils.BlocLines;
@@ -77,13 +78,7 @@ public class CommandArchimateMultilines extends CommandMultilines2\\>)") //
- )), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optionalArchimate("STEREOTYPE"), //
UrlBuilder.OPTIONAL, //
RegexLeaf.spaceZeroOrMore(), //
ColorParser.exp1(), //
@@ -108,7 +103,7 @@ public class CommandArchimateMultilines extends CommandMultilines2 {
- public static final String ALL_TYPES = "person|artifact|actor/|actor|folder|card|file|package|rectangle|hexagon|label|node|frame|cloud|database|queue|stack|storage|agent|usecase/|usecase|component|boundary|control|entity|interface|circle|collections|port|portin|portout";
+ public static final String ALL_TYPES = "person|artifact|actor/|actor|folder|card|file|package|rectangle|hexagon|label|node|frame|cloud|action|process|database|queue|stack|storage|agent|usecase/|usecase|component|boundary|control|entity|interface|circle|collections|port|portin|portout";
public CommandCreateElementFull() {
super(getRegexConcat());
@@ -84,43 +84,26 @@ public class CommandCreateElementFull extends SingleLineCommand2\\>)")//
- )), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE2"), //
new RegexLeaf("as"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("CODE2", CODE)), //
new RegexConcat(//
new RegexLeaf("CODE3", CODE), //
- new RegexOptional( //
- new RegexConcat( //
- RegexLeaf.spaceOneOrMore(), //
- new RegexLeaf("STEREOTYPE3", "(\\<\\<.+\\>\\>)") //
- )), //
- RegexLeaf.spaceOneOrMore(), //
+ StereotypePattern.optional("STEREOTYPE3"), //
new RegexLeaf("as"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("DISPLAY3", DISPLAY)), //
new RegexConcat(//
new RegexLeaf("DISPLAY4", DISPLAY_WITHOUT_QUOTE), //
- new RegexOptional( //
- new RegexConcat( //
- RegexLeaf.spaceOneOrMore(), //
- new RegexLeaf("STEREOTYPE4", "(\\<\\<.+\\>\\>)") //
- )), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE4"), //
new RegexLeaf("as"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("CODE4", CODE)) //
), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TAGS1", Stereotag.pattern() + "?"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE", "(\\<\\<.+\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE"), //
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java
index 3dc3a4665..eeba727d1 100644
--- a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java
+++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java
@@ -59,6 +59,7 @@ import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -93,9 +94,7 @@ public class CommandCreateElementMultilines extends CommandMultilines2\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
UrlBuilder.OPTIONAL, //
RegexLeaf.spaceZeroOrMore(), //
ColorParser.exp1(), //
@@ -110,9 +109,7 @@ public class CommandCreateElementMultilines extends CommandMultilines2\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
UrlBuilder.OPTIONAL, //
RegexLeaf.spaceZeroOrMore(), //
ColorParser.exp1(), //
diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java
index b607964eb..bbc59b124 100644
--- a/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java
+++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java
@@ -59,6 +59,7 @@ import net.sourceforge.plantuml.regex.RegexOptional;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.skin.ActorStyle;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.utils.Direction;
import net.sourceforge.plantuml.utils.LineLocation;
@@ -104,9 +105,7 @@ public class CommandLinkElement extends SingleLineCommand2 {
// RegexLeaf.spaceZeroOrMore(), //
color().getRegex(), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE"), //
new RegexLeaf("LABEL_LINK", "(?::[%s]*(.+))?"), //
RegexLeaf.end());
}
diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java
index 92a2e931a..bbe8fc65c 100644
--- a/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java
+++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java
@@ -57,6 +57,7 @@ import net.sourceforge.plantuml.regex.RegexOr;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotag;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
@@ -71,7 +72,7 @@ public class CommandPackageWithUSymbol extends SingleLineCommand2\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREOTYPE"), //
new RegexLeaf("TAGS2", Stereotag.pattern() + "?"), //
RegexLeaf.spaceZeroOrMore(), //
UrlBuilder.OPTIONAL, //
diff --git a/src/net/sourceforge/plantuml/ditaa/package-info.java b/src/net/sourceforge/plantuml/ditaa/package-info.java
index c2cbdbd4c..f0a3a50f5 100644
--- a/src/net/sourceforge/plantuml/ditaa/package-info.java
+++ b/src/net/sourceforge/plantuml/ditaa/package-info.java
@@ -3,7 +3,9 @@
*
* Ditaa Diagram.
*
+ * @see org.stathissideris.ascii2image.core
* @see org.stathissideris.ascii2image.graphics
+ * @see org.stathissideris.ascii2image.text
*
*/
package net.sourceforge.plantuml.ditaa;
diff --git a/src/net/sourceforge/plantuml/dot/GraphvizUtils.java b/src/net/sourceforge/plantuml/dot/GraphvizUtils.java
index 803023cbc..23261f328 100644
--- a/src/net/sourceforge/plantuml/dot/GraphvizUtils.java
+++ b/src/net/sourceforge/plantuml/dot/GraphvizUtils.java
@@ -197,7 +197,7 @@ public class GraphvizUtils {
if (s == null)
return -1;
- final Pattern p = Pattern.compile("\\s(\\d)\\.(\\d\\d?)\\D");
+ final Pattern p = Pattern.compile("\\s(\\d+)\\.(\\d\\d?)\\D");
final Matcher m = p.matcher(s);
if (m.find() == false)
return -1;
diff --git a/src/net/sourceforge/plantuml/dot/GraphvizVersionFinder.java b/src/net/sourceforge/plantuml/dot/GraphvizVersionFinder.java
index 8a58e7b25..706bb5f0a 100644
--- a/src/net/sourceforge/plantuml/dot/GraphvizVersionFinder.java
+++ b/src/net/sourceforge/plantuml/dot/GraphvizVersionFinder.java
@@ -73,7 +73,7 @@ public class GraphvizVersionFinder {
public GraphvizVersion getVersion() {
final String dotVersion = dotVersion();
- final Pattern p = Pattern.compile("(\\d)\\.(\\d\\d?)");
+ final Pattern p = Pattern.compile("(\\d+)\\.(\\d\\d?)");
final Matcher m = p.matcher(dotVersion);
final boolean find = m.find();
if (find == false)
diff --git a/src/net/sourceforge/plantuml/ebnf/ETileLookAheadOrBehind.java b/src/net/sourceforge/plantuml/ebnf/ETileLookAheadOrBehind.java
new file mode 100644
index 000000000..23a046faf
--- /dev/null
+++ b/src/net/sourceforge/plantuml/ebnf/ETileLookAheadOrBehind.java
@@ -0,0 +1,110 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2020, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.ebnf;
+
+import net.sourceforge.plantuml.klimt.UStroke;
+import net.sourceforge.plantuml.klimt.UTranslate;
+import net.sourceforge.plantuml.klimt.color.HColor;
+import net.sourceforge.plantuml.klimt.color.HColorSet;
+import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.FontConfiguration;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
+import net.sourceforge.plantuml.klimt.geom.XDimension2D;
+import net.sourceforge.plantuml.klimt.shape.URectangle;
+import net.sourceforge.plantuml.klimt.shape.UText;
+import net.sourceforge.plantuml.style.PName;
+import net.sourceforge.plantuml.style.Style;
+
+public class ETileLookAheadOrBehind extends ETile {
+
+ private final ETile orig;
+ private final HColorSet colorSet;
+ private final double deltax1 = 4;
+ private final double deltax2 = 8;
+ private final double deltay = 6;
+ private final Style style;
+ private final UText supText;
+
+ private final FontConfiguration fc;
+
+ public ETileLookAheadOrBehind(ETile orig, FontConfiguration fc, Style style, HColorSet colorSet, String type) {
+ this.style = style;
+ this.orig = orig;
+ this.fc = fc;
+ this.colorSet = colorSet;
+ this.supText = UText.build(type, fc);
+
+ }
+
+ @Override
+ public double getH1(StringBounder stringBounder) {
+ return deltay + orig.getH1(stringBounder);
+ }
+
+ @Override
+ public double getH2(StringBounder stringBounder) {
+ return orig.getH2(stringBounder) + deltay;
+ }
+
+ @Override
+ public double getWidth(StringBounder stringBounder) {
+ return orig.getWidth(stringBounder) + deltax1 + deltax2 + supText.calculateDimension(stringBounder).getWidth();
+ }
+
+ @Override
+ public void drawU(UGraphic ug) {
+ final StringBounder stringBounder = ug.getStringBounder();
+ final XDimension2D dim = calculateDimension(stringBounder);
+
+ final HColor lineColor = style.value(PName.LineColor).asColor(colorSet);
+
+ final URectangle rect = URectangle.build(dim).rounded(30);
+
+ ug.apply(lineColor).apply(new UStroke(2, 3, 1)).draw(rect);
+ final double posText = getH1(stringBounder) + supText.getDescent(stringBounder);
+
+ ug.apply(new UTranslate(4, 2 + posText)).draw(supText);
+
+ orig.drawU(ug.apply(new UTranslate(deltax1 + supText.calculateDimension(stringBounder).getWidth(), deltay)));
+
+ }
+
+ @Override
+ public void push(ETile tile) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/ebnf/ETileNamedGroup.java b/src/net/sourceforge/plantuml/ebnf/ETileNamedGroup.java
new file mode 100644
index 000000000..60927fa4c
--- /dev/null
+++ b/src/net/sourceforge/plantuml/ebnf/ETileNamedGroup.java
@@ -0,0 +1,143 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2020, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.ebnf;
+
+import net.sourceforge.plantuml.klimt.UTranslate;
+import net.sourceforge.plantuml.klimt.color.HColor;
+import net.sourceforge.plantuml.klimt.color.HColorSet;
+import net.sourceforge.plantuml.klimt.color.NoSuchColorException;
+import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.FontConfiguration;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
+import net.sourceforge.plantuml.klimt.geom.XDimension2D;
+import net.sourceforge.plantuml.klimt.shape.URectangle;
+import net.sourceforge.plantuml.klimt.shape.UText;
+import net.sourceforge.plantuml.style.ISkinParam;
+
+public class ETileNamedGroup extends ETile {
+
+ private final ETile orig;
+ private final ISkinParam skinParam;
+ private String commentAbove;
+ private String commentBelow;
+ private final HColorSet colorSet;
+ private final double deltax = 10;
+ private final double deltay1 = 10;
+ private final double deltay2 = 10;
+ private final UText groupName;
+
+ private final FontConfiguration fc;
+
+ public ETileNamedGroup(ETile orig, FontConfiguration fc, HColorSet colorSet, ISkinParam skinParam, String name) {
+ this.skinParam = skinParam;
+ this.orig = orig;
+ this.fc = fc;
+ this.colorSet = colorSet;
+ this.groupName = UText.build(name, fc);
+
+ }
+
+ @Override
+ public double getH1(StringBounder stringBounder) {
+ // final TextBlock note = getNoteAbove(stringBounder);
+ return deltay1 + orig.getH1(stringBounder);
+ }
+
+ @Override
+ public double getH2(StringBounder stringBounder) {
+ // final TextBlock note = getNoteBelow(stringBounder);
+ return orig.getH2(stringBounder) + deltay2;
+ }
+
+ @Override
+ public double getWidth(StringBounder stringBounder) {
+ return orig.getWidth(stringBounder) + 2 * deltax;
+ }
+
+ @Override
+ public void drawU(UGraphic ug) {
+ final StringBounder stringBounder = ug.getStringBounder();
+ final XDimension2D dim = calculateDimension(stringBounder);
+
+ try {
+ final HColor background = colorSet.getColor("#E8E8FF");
+ final UGraphic ugBack = ug.apply(background).apply(background.bg());
+ ugBack.draw(URectangle.build(dim));
+ final XDimension2D dimText = stringBounder.calculateDimension(fc.getFont(), groupName.getText());
+ ugBack.apply(UTranslate.dy(-dimText.getHeight())).draw(URectangle.build(dimText.delta(10, 0)));
+
+ } catch (NoSuchColorException e) {
+ e.printStackTrace();
+ }
+ final double linePos = getH1(stringBounder);
+ drawHline(ug, linePos, 0, deltax);
+ drawHline(ug, linePos, dim.getWidth() - deltax, dim.getWidth());
+
+ orig.drawU(ug.apply(new UTranslate(deltax, deltay1)));
+ ug.apply(UTranslate.dx(5)).draw(groupName);
+
+ }
+
+ @Override
+ public void push(ETile tile) {
+ throw new UnsupportedOperationException();
+ }
+
+// @Override
+// protected void addCommentAbove(String comment) {
+// this.commentAbove = comment;
+// }
+//
+// @Override
+// protected void addCommentBelow(String comment) {
+// this.commentBelow = comment;
+// }
+
+// private TextBlock getNoteAbove(StringBounder stringBounder) {
+// if (commentAbove == null)
+// return TextBlockUtils.EMPTY_TEXT_BLOCK;
+// final FloatingNote note = FloatingNote.create(Display.getWithNewlines(commentAbove), skinParam, SName.ebnf);
+// return TextBlockUtils.withMargin(note, 0, 0, 0, 10);
+// }
+//
+// private TextBlock getNoteBelow(StringBounder stringBounder) {
+// if (commentBelow == null)
+// return TextBlockUtils.EMPTY_TEXT_BLOCK;
+// final FloatingNote note = FloatingNote.create(Display.getWithNewlines(commentBelow), skinParam, SName.ebnf);
+// return TextBlockUtils.withMargin(note, 0, 0, 10, 0);
+// }
+
+}
diff --git a/src/net/sourceforge/plantuml/ebnf/PSystemEbnf.java b/src/net/sourceforge/plantuml/ebnf/PSystemEbnf.java
index 9604c7f74..ccf0e1649 100644
--- a/src/net/sourceforge/plantuml/ebnf/PSystemEbnf.java
+++ b/src/net/sourceforge/plantuml/ebnf/PSystemEbnf.java
@@ -97,11 +97,11 @@ public class PSystemEbnf extends TitledDiagram {
@Override
protected ImageData exportDiagramNow(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {
- return createImageBuilder(fileFormatOption).drawable(getTextBlock()).write(os);
+ return createImageBuilder(fileFormatOption).drawable(getTextMainBlock(fileFormatOption)).write(os);
}
@Override
- protected TextBlock getTextBlock() {
+ protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
if (expressions.size() == 0) {
final Style style = ETile.getStyleSignature().getMergedStyle(getSkinParam().getCurrentStyleBuilder());
final FontConfiguration fc = style.getFontConfiguration(getSkinParam().getIHtmlColorSet());
diff --git a/src/net/sourceforge/plantuml/elk/CucaDiagramFileMakerElk.java b/src/net/sourceforge/plantuml/elk/CucaDiagramFileMakerElk.java
index 0f94cb8fe..015879156 100644
--- a/src/net/sourceforge/plantuml/elk/CucaDiagramFileMakerElk.java
+++ b/src/net/sourceforge/plantuml/elk/CucaDiagramFileMakerElk.java
@@ -127,6 +127,7 @@ import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.svek.Bibliotekon;
import net.sourceforge.plantuml.svek.Cluster;
import net.sourceforge.plantuml.svek.ClusterDecoration;
+import net.sourceforge.plantuml.svek.ClusterHeader;
import net.sourceforge.plantuml.svek.CucaDiagramFileMaker;
import net.sourceforge.plantuml.svek.DotStringFactory;
import net.sourceforge.plantuml.svek.GeneralImageBuilder;
@@ -298,12 +299,12 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
// final double roundCorner = group.getUSymbol() == null ? 0
// : group.getUSymbol().getSkinParameter().getRoundCorner(skinParam, group.getStereotype());
- final TextBlock ztitle = getTitleBlock(group);
- final TextBlock zstereo = TextBlockUtils.empty(0, 0);
-
final RectangleArea rectangleArea = new RectangleArea(0, 0, elkNode.getWidth(), elkNode.getHeight());
- final ClusterDecoration decoration = new ClusterDecoration(packageStyle, group.getUSymbol(), ztitle,
- zstereo, rectangleArea, stroke);
+ final ClusterHeader clusterHeader = new ClusterHeader(group, diagram.getSkinParam(), diagram,
+ stringBounder);
+
+ final ClusterDecoration decoration = new ClusterDecoration(packageStyle, group.getUSymbol(),
+ clusterHeader.getTitle(), clusterHeader.getStereo(), rectangleArea, stroke);
final HColor borderColor = HColors.BLACK;
decoration.drawU(ug.apply(UTranslate.point(corner)), backColor, borderColor, shadowing, roundCorner,
@@ -314,16 +315,6 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
// ug.apply(HColorUtils.BLACK).apply(UStroke.withThickness(1.5)).apply(new UTranslate(corner)).draw(rect);
}
- private TextBlock getTitleBlock(Entity g) {
- final Display label = g.getDisplay();
- if (label == null)
- return TextBlockUtils.empty(0, 0);
-
- final ISkinParam skinParam = diagram.getSkinParam();
- final FontConfiguration fontConfiguration = g.getFontConfigurationForTitle(skinParam);
- return label.create(fontConfiguration, HorizontalAlignment.CENTER, skinParam);
- }
-
private HColor getBackColor(UmlDiagramType umlDiagramType) {
return null;
}
@@ -429,7 +420,14 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
// We create the "cluster" in ELK for this group
final ElkNode elkCluster = ElkGraphUtil.createNode(cluster);
elkCluster.setProperty(CoreOptions.DIRECTION, Direction.DOWN);
- elkCluster.setProperty(CoreOptions.PADDING, new ElkPadding(40, 15, 15, 15));
+
+ final ClusterHeader clusterHeader = new ClusterHeader(g, diagram.getSkinParam(), diagram,
+ stringBounder);
+
+ final int titleAndAttributeHeight = clusterHeader.getTitleAndAttributeHeight();
+
+ final double topPadding = Math.max(25, titleAndAttributeHeight) + 15;
+ elkCluster.setProperty(CoreOptions.PADDING, new ElkPadding(topPadding, 15, 15, 15));
// Not sure this is usefull to put a label on a "cluster"
final ElkLabel label = ElkGraphUtil.createLabel(elkCluster);
diff --git a/src/net/sourceforge/plantuml/filesdiagram/FEntry.java b/src/net/sourceforge/plantuml/filesdiagram/FEntry.java
index eefc7d18e..c48785d39 100644
--- a/src/net/sourceforge/plantuml/filesdiagram/FEntry.java
+++ b/src/net/sourceforge/plantuml/filesdiagram/FEntry.java
@@ -60,47 +60,48 @@ import net.sourceforge.plantuml.svek.image.Opale;
public class FEntry implements Iterable {
- private final ISkinParam skinParam;
+ private final FEntry parent;
private final List note;
private final String name;
private FilesType type;
private List children = new ArrayList<>();
- public static FEntry createRoot(ISkinParam skinParam) {
- return new FEntry(null, "", FilesType.FOLDER, skinParam);
+ public static FEntry createRoot() {
+ return new FEntry(null, FilesType.FOLDER, "", null);
}
- private FEntry(List note, String name, FilesType type, ISkinParam skinParam) {
+ private FEntry(FEntry parent, FilesType type, String name, List note) {
+ this.parent = parent;
this.note = note;
this.name = name;
this.type = type;
- this.skinParam = skinParam;
}
- public void addRawEntry(String raw, ISkinParam skinParam) {
+ public FEntry addRawEntry(String raw) {
final int x = raw.indexOf('/');
if (x == -1) {
- final FEntry result = new FEntry(null, raw, FilesType.DATA, skinParam);
+ final FEntry result = new FEntry(this, FilesType.DATA, raw, null);
children.add(result);
- return;
+ return result;
}
- final FEntry folder = getOrCreateFolder(raw.substring(0, x), skinParam);
+ final FEntry folder = getOrCreateFolder(raw.substring(0, x));
final String remain = raw.substring(x + 1);
if (remain.length() != 0)
- folder.addRawEntry(remain, skinParam);
+ return folder.addRawEntry(remain);
+ return null;
}
- public void addNote(List note, ISkinParam skinParam) {
- final FEntry result = new FEntry(note, "NONE", FilesType.NOTE, skinParam);
+ public void addNote(List note) {
+ final FEntry result = new FEntry(this, FilesType.NOTE, "NONE", note);
children.add(result);
}
- private FEntry getOrCreateFolder(String folderName, ISkinParam skinParam) {
+ private FEntry getOrCreateFolder(String folderName) {
for (FEntry child : children)
if (child.type == FilesType.FOLDER && child.getName().equals(folderName))
return child;
- final FEntry result = new FEntry(null, folderName, FilesType.FOLDER, skinParam);
+ final FEntry result = new FEntry(this, FilesType.FOLDER, folderName, null);
children.add(result);
return result;
}
@@ -110,6 +111,10 @@ public class FEntry implements Iterable {
return Collections.unmodifiableCollection(children).iterator();
}
+ public FEntry getParent() {
+ return parent;
+ }
+
public String getName() {
return name;
}
@@ -132,14 +137,15 @@ public class FEntry implements Iterable {
private TextBlock getTextBlock(FontConfiguration fontConfiguration, ISkinParam skinParam) {
if (type == FilesType.NOTE)
- return createOpale();
+ return createOpale(skinParam);
final Display display = Display.getWithNewlines(getEmoticon() + getName());
- TextBlock result = display.create(fontConfiguration, HorizontalAlignment.LEFT, skinParam);
+ TextBlock result = display.create7(fontConfiguration, HorizontalAlignment.LEFT, skinParam,
+ CreoleMode.NO_CREOLE);
return result;
}
- private Opale createOpale() {
+ private Opale createOpale(ISkinParam skinParam) {
final StyleSignatureBasic signature = StyleSignatureBasic.of(SName.root, SName.element, SName.timingDiagram,
SName.note);
diff --git a/src/net/sourceforge/plantuml/filesdiagram/FilesDiagram.java b/src/net/sourceforge/plantuml/filesdiagram/FilesDiagram.java
index b5142b7c0..891ad8940 100644
--- a/src/net/sourceforge/plantuml/filesdiagram/FilesDiagram.java
+++ b/src/net/sourceforge/plantuml/filesdiagram/FilesDiagram.java
@@ -89,11 +89,11 @@ public class FilesDiagram extends UmlDiagram {
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {
- return createImageBuilder(fileFormatOption).drawable(getTextBlock()).write(os);
+ return createImageBuilder(fileFormatOption).drawable(getTextMainBlock(fileFormatOption)).write(os);
}
@Override
- protected TextBlock getTextBlock() {
+ protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
return list;
}
diff --git a/src/net/sourceforge/plantuml/filesdiagram/FilesListing.java b/src/net/sourceforge/plantuml/filesdiagram/FilesListing.java
index 592a779a0..a90e78caf 100644
--- a/src/net/sourceforge/plantuml/filesdiagram/FilesListing.java
+++ b/src/net/sourceforge/plantuml/filesdiagram/FilesListing.java
@@ -49,10 +49,11 @@ public class FilesListing extends AbstractTextBlock {
private final ISkinParam skinParam;
private final FontConfiguration fontConfiguration = FontConfiguration.blackBlueTrue(UFont.courier(14));
private final FEntry root;
+ private FEntry lastCreated;
public FilesListing(ISkinParam skinParam) {
this.skinParam = skinParam;
- this.root = FEntry.createRoot(skinParam);
+ this.root = FEntry.createRoot();
}
@Override
@@ -67,11 +68,14 @@ public class FilesListing extends AbstractTextBlock {
}
public void addRawEntry(String raw) {
- root.addRawEntry(raw, skinParam);
+ lastCreated = root.addRawEntry(raw);
}
public void addNote(List note) {
- root.addNote(note, skinParam);
+ if (lastCreated == null)
+ root.addNote(note);
+ else
+ lastCreated.getParent().addNote(note);
}
}
diff --git a/src/net/sourceforge/plantuml/flashcode/FlashCodeUtilsZxing.java b/src/net/sourceforge/plantuml/flashcode/FlashCodeUtilsZxing.java
index f2058b5d2..902e27b8a 100644
--- a/src/net/sourceforge/plantuml/flashcode/FlashCodeUtilsZxing.java
+++ b/src/net/sourceforge/plantuml/flashcode/FlashCodeUtilsZxing.java
@@ -41,12 +41,12 @@ import java.util.Hashtable;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
-import ext.plantuml.com.google.zxing.BarcodeFormat;
-import ext.plantuml.com.google.zxing.EncodeHintType;
-import ext.plantuml.com.google.zxing.client.j2se.MatrixToImageWriter;
-import ext.plantuml.com.google.zxing.common.BitMatrix;
-import ext.plantuml.com.google.zxing.qrcode.QRCodeWriter;
-import ext.plantuml.com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+import zext.plantuml.com.google.zxing.BarcodeFormat;
+import zext.plantuml.com.google.zxing.EncodeHintType;
+import zext.plantuml.com.google.zxing.client.j2se.MatrixToImageWriter;
+import zext.plantuml.com.google.zxing.common.BitMatrix;
+import zext.plantuml.com.google.zxing.qrcode.QRCodeWriter;
+import zext.plantuml.com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import net.sourceforge.plantuml.utils.Log;
public class FlashCodeUtilsZxing implements FlashCodeUtils {
diff --git a/src/net/sourceforge/plantuml/flashcode/package-info.java b/src/net/sourceforge/plantuml/flashcode/package-info.java
index e016dc1c9..1d995313b 100644
--- a/src/net/sourceforge/plantuml/flashcode/package-info.java
+++ b/src/net/sourceforge/plantuml/flashcode/package-info.java
@@ -2,7 +2,7 @@
* Provides classes used to manage
* Flashcode especially QR Code (on PlantUML).
*
- * @see ext.plantuml.com.google.zxing
+ * @see zext.plantuml.com.google.zxing
* @see net.sourceforge.plantuml.klimt.creole.atom.AtomImg#createQrcode
*/
package net.sourceforge.plantuml.flashcode;
diff --git a/src/net/sourceforge/plantuml/flashcode/readme.md b/src/net/sourceforge/plantuml/flashcode/readme.md
index 5d49c3123..eac30f0ae 100644
--- a/src/net/sourceforge/plantuml/flashcode/readme.md
+++ b/src/net/sourceforge/plantuml/flashcode/readme.md
@@ -8,7 +8,7 @@ This package provides classes used to manage Flashcode especially QR Code (on Pl
- [QR code _(on Wikipedia)_](https://en.wikipedia.org/wiki/QR_code)
## Credit
-- [`com.google.zxing`](../../../../ext/plantuml/com/google/zxing/) _(included in PlantUML)_
+- [`com.google.zxing`](../../../../zext/plantuml/com/google/zxing/) _(included in PlantUML)_
- :octocat: [zxing/zxing](https://github.com/zxing/zxing)
## Misc.
diff --git a/src/net/sourceforge/plantuml/flowdiagram/FlowDiagram.java b/src/net/sourceforge/plantuml/flowdiagram/FlowDiagram.java
index 7d4b21638..5b4b4b125 100644
--- a/src/net/sourceforge/plantuml/flowdiagram/FlowDiagram.java
+++ b/src/net/sourceforge/plantuml/flowdiagram/FlowDiagram.java
@@ -230,7 +230,7 @@ public class FlowDiagram extends UmlDiagram implements TextBlock {
}
@Override
- protected TextBlock getTextBlock() {
+ protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
return this;
}
diff --git a/src/net/sourceforge/plantuml/flowdiagram/package-info.java b/src/net/sourceforge/plantuml/flowdiagram/package-info.java
new file mode 100644
index 000000000..c146b9255
--- /dev/null
+++ b/src/net/sourceforge/plantuml/flowdiagram/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Provides classes used to manage
+ *
+ * Flow Diagram.
+ *
+ */
+package net.sourceforge.plantuml.flowdiagram;
diff --git a/src/net/sourceforge/plantuml/flowdiagram/readme.md b/src/net/sourceforge/plantuml/flowdiagram/readme.md
new file mode 100644
index 000000000..720bea988
--- /dev/null
+++ b/src/net/sourceforge/plantuml/flowdiagram/readme.md
@@ -0,0 +1,11 @@
+# Directory Documentation for `flowdiagram`
+
+## Description
+This package provides classes used to manage [PlantUML Flow Diagram](http://alphadoc.plantuml.com/doc/markdown/en/flow-diagram).
+
+## Link
+- [Flow Diagram _(on Alpha-doc)_](http://alphadoc.plantuml.com/doc/markdown/en/flow-diagram)
+
+## Reference
+- [GH-501](https://github.com/plantuml/plantuml/issues/501#issuecomment-805783661)
+- [QA-13557](https://forum.plantuml.net/13557/support-for-the-different-%40start-commands)
diff --git a/src/net/sourceforge/plantuml/gitlog/GitDiagram.java b/src/net/sourceforge/plantuml/gitlog/GitDiagram.java
index b355612cf..f1ad5fd1e 100644
--- a/src/net/sourceforge/plantuml/gitlog/GitDiagram.java
+++ b/src/net/sourceforge/plantuml/gitlog/GitDiagram.java
@@ -68,7 +68,7 @@ public class GitDiagram extends UmlDiagram {
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {
- return createImageBuilder(fileFormatOption).drawable(getTextBlock()).write(os);
+ return createImageBuilder(fileFormatOption).drawable(getTextMainBlock(fileFormatOption)).write(os);
}
private void drawInternal(UGraphic ug) {
@@ -84,7 +84,7 @@ public class GitDiagram extends UmlDiagram {
}
@Override
- protected TextBlock getTextBlock() {
+ protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
diff --git a/src/net/sourceforge/plantuml/help/Help.java b/src/net/sourceforge/plantuml/help/Help.java
index 36962e0a5..cc7322dbb 100644
--- a/src/net/sourceforge/plantuml/help/Help.java
+++ b/src/net/sourceforge/plantuml/help/Help.java
@@ -96,7 +96,7 @@ public class Help extends UmlDiagram {
}
@Override
- protected TextBlock getTextBlock() {
+ protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
throw new UnsupportedOperationException();
}
diff --git a/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java b/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java
index 7aabbed27..cdc6eb494 100644
--- a/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java
+++ b/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java
@@ -94,7 +94,7 @@ public class JsonDiagram extends TitledDiagram {
protected ImageData exportDiagramNow(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {
- return createImageBuilder(fileFormatOption).drawable(getTextBlock()).write(os);
+ return createImageBuilder(fileFormatOption).drawable(getTextMainBlock(fileFormatOption)).write(os);
}
private void drawInternal(UGraphic ug) {
@@ -113,7 +113,7 @@ public class JsonDiagram extends TitledDiagram {
}
@Override
- protected TextBlock getTextBlock() {
+ protected TextBlock getTextMainBlock(final FileFormatOption fileFormatOption) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
@@ -121,7 +121,7 @@ public class JsonDiagram extends TitledDiagram {
}
public XDimension2D calculateDimension(StringBounder stringBounder) {
- return TextBlockUtils.getMinMax(getTextBlock(), stringBounder, true).getDimension();
+ return TextBlockUtils.getMinMax(getTextMainBlock(fileFormatOption), stringBounder, true).getDimension();
}
};
}
diff --git a/src/net/sourceforge/plantuml/klimt/color/package-info.java b/src/net/sourceforge/plantuml/klimt/color/package-info.java
new file mode 100644
index 000000000..1568496a9
--- /dev/null
+++ b/src/net/sourceforge/plantuml/klimt/color/package-info.java
@@ -0,0 +1,12 @@
+/**
+ * Provides classes used to manage
+ *
+ * Color.
+ *
+ * @see net.sourceforge.plantuml.help.CommandHelpColor
+ * @see net.sourceforge.plantuml.eggs.PSystemColorsFactory
+ * @see net.sourceforge.plantuml.klimt.creole.command.CommandCreoleColorAndSizeChange
+ * @see net.sourceforge.plantuml.klimt.creole.command.CommandCreoleColorChange
+ *
+ */
+package net.sourceforge.plantuml.klimt.color;
diff --git a/src/net/sourceforge/plantuml/klimt/color/readme.md b/src/net/sourceforge/plantuml/klimt/color/readme.md
new file mode 100644
index 000000000..6d7808afb
--- /dev/null
+++ b/src/net/sourceforge/plantuml/klimt/color/readme.md
@@ -0,0 +1,16 @@
+# Directory Documentation for `color`
+
+## Description
+This package provides classes used to manage [PlantUML Color](https://plantuml.com/color).
+
+## Link
+- [PlantUML Color](https://plantuml.com/color)
+
+## Reference
+
+## Credit or Inspiration
+- [HSLuv, a developer friendly perceptual color space](https://www.kuon.ch/post/2020-03-08-hsluv/) by _Nicolas Goy_.
+- [HSLuv color space](https://www.hsluv.org) by [_Alexei Boronine_](https://www.boronine.com)
+- :octocat: [hsluv/hsluv-java](https://github.com/hsluv/hsluv-java)
+- [Calculating Color Contrast](https://24ways.org/2010/calculating-color-contrast) by _Brian Suda_.
+- [`HSLColor.java` _(on Web Archive)_](https://web.archive.org/web/20220328231936/http://www.camick.com/java/source/HSLColor.java)
diff --git a/src/net/sourceforge/plantuml/klimt/creole/atom/AtomTable.java b/src/net/sourceforge/plantuml/klimt/creole/atom/AtomTable.java
index 9e32d2a7a..d49fe62be 100644
--- a/src/net/sourceforge/plantuml/klimt/creole/atom/AtomTable.java
+++ b/src/net/sourceforge/plantuml/klimt/creole/atom/AtomTable.java
@@ -81,6 +81,7 @@ public class AtomTable extends AbstractAtom implements Atom {
private final List lines = new ArrayList<>();
private final Map positions = new HashMap();
private final HColor lineColor;
+ private Class extends StringBounder> lastCaller;
public AtomTable(HColor lineColor) {
this.lineColor = lineColor;
@@ -110,14 +111,14 @@ public class AtomTable extends AbstractAtom implements Atom {
.draw(URectangle.build(x2 - x1, y2 - y1));
}
for (int j = 0; j < getNbCols(); j++) {
- if (j >= line.cells.size()) {
+ if (j >= line.cells.size())
continue;
- }
+
final Atom cell = line.cells.get(j);
HorizontalAlignment align = HorizontalAlignment.LEFT;
- if (cell instanceof SheetBlock1) {
+ if (cell instanceof SheetBlock1)
align = ((SheetBlock1) cell).getCellAlignment();
- }
+
final HColor cellBackColor = line.cellsBackColor.get(j);
final double x1 = getStartingX(j);
final double x2 = getStartingX(j + 1);
@@ -131,11 +132,11 @@ public class AtomTable extends AbstractAtom implements Atom {
final Position pos = positions.get(cell);
final XDimension2D dimCell = cell.calculateDimension(ug.getStringBounder());
final double dx;
- if (align == HorizontalAlignment.RIGHT) {
+ if (align == HorizontalAlignment.RIGHT)
dx = cellWidth - dimCell.getWidth();
- } else {
+ else
dx = 0;
- }
+
if (cellBackColor == null)
cell.drawU(ug.apply(pos.getTranslate().compose(UTranslate.dx(dx))));
else
@@ -144,20 +145,25 @@ public class AtomTable extends AbstractAtom implements Atom {
}
ug = ug.apply(lineColor);
final ULine hline = ULine.hline(getEndingX(getNbCols() - 1));
- for (int i = 0; i <= getNbLines(); i++) {
+ for (int i = 0; i <= getNbLines(); i++)
ug.apply(UTranslate.dy(getStartingY(i))).draw(hline);
- }
+
final ULine vline = ULine.vline(getEndingY(getNbLines() - 1));
- for (int i = 0; i <= getNbCols(); i++) {
+ for (int i = 0; i <= getNbCols(); i++)
ug.apply(UTranslate.dx(getStartingX(i))).draw(vline);
- }
}
private void initMap(StringBounder stringBounder) {
- if (positions.size() > 0) {
+ final Class extends StringBounder> currentCaller = stringBounder.getClass();
+ if (lastCaller != currentCaller)
+ positions.clear();
+
+ this.lastCaller = currentCaller;
+
+ if (positions.size() > 0)
return;
- }
+
for (Line line : lines) {
for (Atom cell : line.cells) {
final XDimension2D dim = cell.calculateDimension(stringBounder);
@@ -179,33 +185,33 @@ public class AtomTable extends AbstractAtom implements Atom {
private double getStartingX(int col) {
double result = 0;
- for (int i = 0; i < col; i++) {
+ for (int i = 0; i < col; i++)
result += getColWidth(i);
- }
+
return result;
}
private double getEndingX(int col) {
double result = 0;
- for (int i = 0; i <= col; i++) {
+ for (int i = 0; i <= col; i++)
result += getColWidth(i);
- }
+
return result;
}
private double getStartingY(int line) {
double result = 0;
- for (int i = 0; i < line; i++) {
+ for (int i = 0; i < line; i++)
result += getLineHeight(i);
- }
+
return result;
}
private double getEndingY(int line) {
double result = 0;
- for (int i = 0; i <= line; i++) {
+ for (int i = 0; i <= line; i++)
result += getLineHeight(i);
- }
+
return result;
}
@@ -213,9 +219,9 @@ public class AtomTable extends AbstractAtom implements Atom {
double result = 0;
for (int i = 0; i < getNbLines(); i++) {
final Position position = getPosition(i, col);
- if (position == null) {
+ if (position == null)
continue;
- }
+
final double width = position.getWidth();
result = Math.max(result, width);
}
@@ -226,9 +232,9 @@ public class AtomTable extends AbstractAtom implements Atom {
double result = 0;
for (int i = 0; i < getNbCols(); i++) {
final Position position = getPosition(line, i);
- if (position == null) {
+ if (position == null)
continue;
- }
+
final double height = position.getHeight();
result = Math.max(result, height);
}
@@ -236,13 +242,13 @@ public class AtomTable extends AbstractAtom implements Atom {
}
private Position getPosition(int line, int col) {
- if (line >= lines.size()) {
+ if (line >= lines.size())
return null;
- }
+
final Line l = lines.get(line);
- if (col >= l.cells.size()) {
+ if (col >= l.cells.size())
return null;
- }
+
final Atom atom = l.cells.get(col);
return positions.get(atom);
}
diff --git a/src/net/sourceforge/plantuml/klimt/creole/package-info.java b/src/net/sourceforge/plantuml/klimt/creole/package-info.java
new file mode 100644
index 000000000..99f501c28
--- /dev/null
+++ b/src/net/sourceforge/plantuml/klimt/creole/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Provides classes used to manage
+ *
+ * Creole (markup language).
+ *
+ */
+package net.sourceforge.plantuml.klimt.creole;
diff --git a/src/net/sourceforge/plantuml/klimt/creole/readme.md b/src/net/sourceforge/plantuml/klimt/creole/readme.md
new file mode 100644
index 000000000..d1dd36370
--- /dev/null
+++ b/src/net/sourceforge/plantuml/klimt/creole/readme.md
@@ -0,0 +1,10 @@
+# Directory Documentation for `creole`
+
+## Description
+This package provides classes used to manage [PlantUML Creole](https://plantuml.com/creole) markup language.
+
+## Link
+- [PlantUML Creole](https://plantuml.com/creole)
+
+## Reference
+- [Creole (markup) _(on Wikipedia)_](https://en.wikipedia.org/wiki/Creole_(markup))
diff --git a/src/net/sourceforge/plantuml/klimt/drawing/g2d/ExtendedGeneralPath.java b/src/net/sourceforge/plantuml/klimt/drawing/g2d/ExtendedGeneralPath.java
index 37bfe9b7b..1ff88279b 100644
--- a/src/net/sourceforge/plantuml/klimt/drawing/g2d/ExtendedGeneralPath.java
+++ b/src/net/sourceforge/plantuml/klimt/drawing/g2d/ExtendedGeneralPath.java
@@ -35,25 +35,6 @@
*/
package net.sourceforge.plantuml.klimt.drawing.g2d;
-/*
-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
diff --git a/src/net/sourceforge/plantuml/klimt/drawing/svg/SvgGraphics.java b/src/net/sourceforge/plantuml/klimt/drawing/svg/SvgGraphics.java
index c13d9b5a7..be1e8f466 100644
--- a/src/net/sourceforge/plantuml/klimt/drawing/svg/SvgGraphics.java
+++ b/src/net/sourceforge/plantuml/klimt/drawing/svg/SvgGraphics.java
@@ -1024,7 +1024,7 @@ public class SvgGraphics {
public void addCommentMetadata(String metadata) {
// ::comment when __CORE__
- final String signature = getMetadataHex(metadata);
+ final String signature = getMetadataHex(metadata).replace("--", "- -");
final String comment = "SRC=[" + signature + "]";
final Comment commentElement = document.createComment(comment);
getG().appendChild(commentElement);
diff --git a/src/net/sourceforge/plantuml/klimt/shape/UText.java b/src/net/sourceforge/plantuml/klimt/shape/UText.java
index 938007efb..6968ba1ed 100644
--- a/src/net/sourceforge/plantuml/klimt/shape/UText.java
+++ b/src/net/sourceforge/plantuml/klimt/shape/UText.java
@@ -38,6 +38,7 @@ package net.sourceforge.plantuml.klimt.shape;
import net.sourceforge.plantuml.klimt.UShape;
import net.sourceforge.plantuml.klimt.font.FontConfiguration;
import net.sourceforge.plantuml.klimt.font.StringBounder;
+import net.sourceforge.plantuml.klimt.geom.XDimension2D;
public class UText implements UShape {
@@ -83,4 +84,8 @@ public class UText implements UShape {
return orientation;
}
+ public XDimension2D calculateDimension(StringBounder stringBounder) {
+ return stringBounder.calculateDimension(font.getFont(), text);
+ }
+
}
diff --git a/src/net/sourceforge/plantuml/klimt/sprite/ListSpriteDiagram.java b/src/net/sourceforge/plantuml/klimt/sprite/ListSpriteDiagram.java
index b23c5610d..ec49bdf7d 100644
--- a/src/net/sourceforge/plantuml/klimt/sprite/ListSpriteDiagram.java
+++ b/src/net/sourceforge/plantuml/klimt/sprite/ListSpriteDiagram.java
@@ -79,11 +79,11 @@ public class ListSpriteDiagram extends UmlDiagram {
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {
- return createImageBuilder(fileFormatOption).drawable(getTextBlock()).write(os);
+ return createImageBuilder(fileFormatOption).drawable(getTextMainBlock(fileFormatOption)).write(os);
}
@Override
- protected TextBlock getTextBlock() {
+ protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
diff --git a/src/net/sourceforge/plantuml/klimt/sprite/StdlibDiagram.java b/src/net/sourceforge/plantuml/klimt/sprite/StdlibDiagram.java
index f637002ea..74c0f7ec5 100644
--- a/src/net/sourceforge/plantuml/klimt/sprite/StdlibDiagram.java
+++ b/src/net/sourceforge/plantuml/klimt/sprite/StdlibDiagram.java
@@ -91,11 +91,11 @@ public class StdlibDiagram extends UmlDiagram {
protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {
- return createImageBuilder(fileFormatOption).drawable(getTextBlock()).write(os);
+ return createImageBuilder(fileFormatOption).drawable(getTextMainBlock(fileFormatOption)).write(os);
}
@Override
- protected TextBlock getTextBlock() {
+ protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
diff --git a/src/net/sourceforge/plantuml/klimt/sprite/package-info.java b/src/net/sourceforge/plantuml/klimt/sprite/package-info.java
new file mode 100644
index 000000000..53dd54d25
--- /dev/null
+++ b/src/net/sourceforge/plantuml/klimt/sprite/package-info.java
@@ -0,0 +1,10 @@
+/**
+ * Provides classes used to manage
+ *
+ * Sprite.
+ *
+ * @see net.sourceforge.plantuml.klimt.sprite.CommandListSprite
+ * @see net.sourceforge.plantuml.klimt.sprite.CommandStdlib
+ *
+ */
+package net.sourceforge.plantuml.klimt.sprite;
diff --git a/src/net/sourceforge/plantuml/klimt/sprite/readme.md b/src/net/sourceforge/plantuml/klimt/sprite/readme.md
new file mode 100644
index 000000000..314f10af7
--- /dev/null
+++ b/src/net/sourceforge/plantuml/klimt/sprite/readme.md
@@ -0,0 +1,14 @@
+# Directory Documentation for `sprite`
+
+## Description
+This package provides classes used to manage [PlantUML Sprite](https://plantuml.com/sprite).
+
+## Link
+- [PlantUML Sprite](https://plantuml.com/sprite)
+
+## Reference
+
+## See also
+- [PlantUML Standard Library](https://plantuml.com/stdlib)
+- [`stdlib`](../../../../../../stdlib/)
+- :octocat: [plantuml/plantuml-stdlib](https://github.com/plantuml/plantuml-stdlib)
diff --git a/src/net/sourceforge/plantuml/math/ASCIIMathTeXImg.java b/src/net/sourceforge/plantuml/math/ASCIIMathTeXImg.java
index 6aec5694c..d4d32969b 100644
--- a/src/net/sourceforge/plantuml/math/ASCIIMathTeXImg.java
+++ b/src/net/sourceforge/plantuml/math/ASCIIMathTeXImg.java
@@ -602,7 +602,7 @@ public class ASCIIMathTeXImg {
case CONST:
str = AMremoveCharsAndBlanks(str, symbol.input.length());
String texsymbol = AMTgetTeXsymbol(symbol);
- if (texsymbol.charAt(0) == '\\' || symbol.tag.equals("mo"))
+ if (texsymbol.isEmpty() || texsymbol.charAt(0) == '\\' || symbol.tag.equals("mo"))
return new String[] { texsymbol, str };
else {
return new String[] { "{" + texsymbol + "}", str };
@@ -676,7 +676,7 @@ public class ASCIIMathTeXImg {
if (result[0] == null)
return new String[] { "{" + AMTgetTeXsymbol(symbol) + "}", str };
if (symbol.hasFlag("func")) { // functions hack
- st = "" + str.charAt(0);
+ st = "" + (str.isEmpty() ? "" : str.charAt(0));
if (st.equals("^") || st.equals("_") || st.equals("/") || st.equals("|") || st.equals(",")
|| (symbol.input.length() == 1 && symbol.input.matches("\\w") && !st.equals("("))) {
return new String[] { "{" + AMTgetTeXsymbol(symbol) + "}", str };
@@ -905,8 +905,8 @@ public class ASCIIMathTeXImg {
subarr = new ArrayList(Arrays.asList(
newFrag.substring(pos.get(i) + 8, subpos.get(pos.get(i)).get(1))));
for (int j = 2; j < subpos.get(pos.get(i)).size(); j++) {
- subarr.add(newFrag.substring(subpos.get(i).get(j - 1) + 1,
- subpos.get(i).get(j)));
+ subarr.add(newFrag.substring(subpos.get(pos.get(i)).get(j - 1) + 1,
+ subpos.get(pos.get(i)).get(j)));
}
subarr.add(newFrag.substring(
subpos.get(pos.get(i)).get(subpos.get(pos.get(i)).size() - 1) + 1,
diff --git a/src/net/sourceforge/plantuml/mindmap/CommandMindMapDirection.java b/src/net/sourceforge/plantuml/mindmap/CommandMindMapDirection.java
index 27f658495..d23e8f8ea 100644
--- a/src/net/sourceforge/plantuml/mindmap/CommandMindMapDirection.java
+++ b/src/net/sourceforge/plantuml/mindmap/CommandMindMapDirection.java
@@ -53,13 +53,13 @@ public class CommandMindMapDirection extends SingleLineCommand2
static IRegex getRegexConcat() {
return RegexConcat.build(CommandMindMapDirection.class.getName(), RegexLeaf.start(), //
- new RegexLeaf("[^*]*"), //
+ new RegexLeaf("[^*#]*"), //
new RegexLeaf("\\b"), //
new RegexLeaf("DIRECTION", "(left|right|top|bottom)"), //
new RegexLeaf("\\b"), //
- new RegexLeaf("[^*]*"), //
+ new RegexLeaf("[^*#]*"), //
new RegexLeaf("(side|direction)"), //
- new RegexLeaf("[^*]*"), //
+ new RegexLeaf("[^*#]*"), //
RegexLeaf.end());
}
diff --git a/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmode.java b/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmode.java
index 8c53a6853..e46204474 100644
--- a/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmode.java
+++ b/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmode.java
@@ -55,7 +55,7 @@ public class CommandMindMapOrgmode extends SingleLineCommand2 {
static IRegex getRegexConcat() {
return RegexConcat.build(CommandMindMapOrgmode.class.getName(), RegexLeaf.start(), //
- new RegexLeaf("TYPE", "([ \t]*\\*+)"), //
+ new RegexLeaf("TYPE", "([ \t]*[*#]+)"), //
new RegexOptional(new RegexLeaf("BACKCOLOR", "\\[(#\\w+)\\]")), //
new RegexLeaf("SHAPE", "(_)?"), //
RegexLeaf.spaceOneOrMore(), //
diff --git a/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmodeMultiline.java b/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmodeMultiline.java
index 79fd1936a..7d03529bc 100644
--- a/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmodeMultiline.java
+++ b/src/net/sourceforge/plantuml/mindmap/CommandMindMapOrgmodeMultiline.java
@@ -60,7 +60,7 @@ public class CommandMindMapOrgmodeMultiline extends CommandMultilines2\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
UrlBuilder.OPTIONAL, //
RegexLeaf.spaceZeroOrMore(), //
ColorParser.exp1(), RegexLeaf.end());
diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java
index ec7457a56..de7209791 100644
--- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java
+++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java
@@ -55,6 +55,7 @@ import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.skin.VisibilityModifier;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.text.StringLocated;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.utils.BlocLines;
@@ -70,9 +71,7 @@ public class CommandCreateEntityObjectMultilines extends CommandMultilines2\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
UrlBuilder.OPTIONAL, //
RegexLeaf.spaceZeroOrMore(), //
ColorParser.exp1(), //
diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJson.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJson.java
index 94f3c4c13..ad217dd09 100644
--- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJson.java
+++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJson.java
@@ -59,6 +59,7 @@ import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.text.StringLocated;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.utils.BlocLines;
@@ -74,9 +75,7 @@ public class CommandCreateJson extends CommandMultilines2
new RegexLeaf("TYPE", "json"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("NAME", "(?:[%g]([^%g]+)[%g][%s]+as[%s]+)?([%pLN_.]+)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.+\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
UrlBuilder.OPTIONAL, //
RegexLeaf.spaceZeroOrMore(), //
ColorParser.exp1(), //
diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJsonSingleLine.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJsonSingleLine.java
index fbdc4aa76..b185f30aa 100644
--- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJsonSingleLine.java
+++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJsonSingleLine.java
@@ -56,6 +56,7 @@ import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.utils.LineLocation;
@@ -70,9 +71,7 @@ public class CommandCreateJsonSingleLine extends SingleLineCommand2\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
UrlBuilder.OPTIONAL, //
RegexLeaf.spaceZeroOrMore(), //
ColorParser.exp1(), //
diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateMap.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateMap.java
index 8e2cbe564..939c14edf 100644
--- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateMap.java
+++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateMap.java
@@ -62,6 +62,7 @@ import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexOptional;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.stereo.Stereotype;
+import net.sourceforge.plantuml.stereo.StereotypePattern;
import net.sourceforge.plantuml.text.StringLocated;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.utils.BlocLines;
@@ -77,9 +78,7 @@ public class CommandCreateMap extends CommandMultilines2
new RegexLeaf("TYPE", "map"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("NAME", "(?:[%g]([^%g]+)[%g][%s]+as[%s]+)?([%pLN_.]+)"), //
- RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("STEREO", "(\\<\\<.+\\>\\>)?"), //
- RegexLeaf.spaceZeroOrMore(), //
+ StereotypePattern.optional("STEREO"), //
UrlBuilder.OPTIONAL, //
RegexLeaf.spaceZeroOrMore(), //
color().getRegex(), //
diff --git a/src/net/sourceforge/plantuml/png/PngTitler.java b/src/net/sourceforge/plantuml/png/PngTitler.java
index 662710e6f..56a35e0d0 100644
--- a/src/net/sourceforge/plantuml/png/PngTitler.java
+++ b/src/net/sourceforge/plantuml/png/PngTitler.java
@@ -36,6 +36,7 @@
package net.sourceforge.plantuml.png;
import net.sourceforge.plantuml.cucadiagram.DisplaySection;
+import net.sourceforge.plantuml.klimt.LineBreakStrategy;
import net.sourceforge.plantuml.klimt.color.HColorSet;
import net.sourceforge.plantuml.klimt.creole.Display;
import net.sourceforge.plantuml.klimt.font.StringBounder;
@@ -73,6 +74,6 @@ public class PngTitler {
if (display == null)
return null;
- return style.createTextBlockBordered(display, set, spriteContainer, Style.ID_TITLE);
+ return style.createTextBlockBordered(display, set, spriteContainer, Style.ID_TITLE, LineBreakStrategy.NONE);
}
}
diff --git a/src/net/sourceforge/plantuml/preproc/Defines.java b/src/net/sourceforge/plantuml/preproc/Defines.java
index ed1478741..14ec49a0e 100644
--- a/src/net/sourceforge/plantuml/preproc/Defines.java
+++ b/src/net/sourceforge/plantuml/preproc/Defines.java
@@ -55,6 +55,7 @@ import net.sourceforge.plantuml.file.AParentFolder;
import net.sourceforge.plantuml.security.SFile;
import net.sourceforge.plantuml.security.SecurityProfile;
import net.sourceforge.plantuml.security.SecurityUtils;
+import net.sourceforge.plantuml.text.StringLocated;
import net.sourceforge.plantuml.tim.EaterException;
import net.sourceforge.plantuml.tim.TMemory;
import net.sourceforge.plantuml.tim.TVariableScope;
@@ -81,11 +82,11 @@ public class Defines implements Truth {
return new Defines();
}
- public void copyTo(TMemory memory) throws EaterException {
+ public void copyTo(TMemory memory, StringLocated location) throws EaterException {
for (Entry ent : values.entrySet()) {
final String name = ent.getKey();
final Define def = ent.getValue();
- memory.putVariable(name, def.asTVariable(), TVariableScope.GLOBAL);
+ memory.putVariable(name, def.asTVariable(), TVariableScope.GLOBAL, location);
}
}
@@ -114,10 +115,10 @@ public class Defines implements Truth {
final Defines result = createEmpty();
result.overrideFilename(file.getName());
result.environment.put("filedate", new Date(file.lastModified()).toString());
- if (SecurityUtils.getSecurityProfile() == SecurityProfile.UNSECURE) {
+ if (SecurityUtils.getSecurityProfile() == SecurityProfile.UNSECURE)
result.environment.put("dirpath",
file.getAbsoluteFile().getParentFile().getAbsolutePath().replace('\\', '/'));
- }
+
return result;
}
@@ -126,10 +127,10 @@ public class Defines implements Truth {
final Defines result = createEmpty();
result.overrideFilename(file.getName());
result.environment.put("filedate", new Date(file.lastModified()).toString());
- if (SecurityUtils.getSecurityProfile() == SecurityProfile.UNSECURE) {
+ if (SecurityUtils.getSecurityProfile() == SecurityProfile.UNSECURE)
result.environment.put("dirpath",
file.getAbsoluteFile().getParentFile().getAbsolutePath().replace('\\', '/'));
- }
+
return result;
}
@@ -147,9 +148,9 @@ public class Defines implements Truth {
private static String nameNoExtension(String name) {
final int x = name.lastIndexOf('.');
- if (x == -1) {
+ if (x == -1)
return name;
- }
+
return name.substring(0, x);
}
@@ -169,11 +170,10 @@ public class Defines implements Truth {
}
public boolean isTrue(String name) {
- for (String key : values.keySet()) {
- if (key.equals(name) || key.startsWith(name + "(")) {
+ for (String key : values.keySet())
+ if (key.equals(name) || key.startsWith(name + "("))
return true;
- }
- }
+
return false;
}
@@ -192,9 +192,9 @@ public class Defines implements Truth {
}
private String method1(String line) {
- for (Define def : values.values()) {
+ for (Define def : values.values())
line = def.apply(line);
- }
+
return line;
}
@@ -215,18 +215,17 @@ public class Defines implements Truth {
private String method2(String line) {
final Set words = words(line);
- if (magic == null) {
+ if (magic == null)
magic = getAll();
- }
for (String w : words) {
Collection tmp = magic.get(w);
- if (tmp == null) {
+ if (tmp == null)
continue;
- }
- for (Define def : tmp) {
+
+ for (Define def : tmp)
line = def.apply(line);
- }
+
}
return line;
}
@@ -236,9 +235,9 @@ public class Defines implements Truth {
Pattern p = Pattern.compile(ID);
Matcher m = p.matcher(line);
final Set words = new HashSet<>();
- while (m.find()) {
+ while (m.find())
words.add(m.group(0));
- }
+
return words;
}
diff --git a/src/net/sourceforge/plantuml/preproc/Stdlib.java b/src/net/sourceforge/plantuml/preproc/Stdlib.java
index 43b00edea..805b9f1c8 100644
--- a/src/net/sourceforge/plantuml/preproc/Stdlib.java
+++ b/src/net/sourceforge/plantuml/preproc/Stdlib.java
@@ -3,10 +3,13 @@ package net.sourceforge.plantuml.preproc;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.awt.image.BufferedImage;
+import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -317,9 +320,12 @@ public class Stdlib {
return new BrotliInputStream(raw);
}
- private static InputStream getInternalInputStream(String fullname, String extension) {
- final String res = "/stdlib/" + fullname + extension;
- return Stdlib.class.getResourceAsStream(res);
+ private static InputStream getInternalInputStream(String fullname, String extension) throws FileNotFoundException {
+ final String path = "stdlib/" + fullname + extension;
+ InputStream result = Stdlib.class.getResourceAsStream("/" + path);
+ if (result == null)
+ result = new BufferedInputStream(new FileInputStream(path));
+ return result;
}
public static void extractStdLib() throws IOException {
@@ -329,9 +335,12 @@ public class Stdlib {
}
}
- private static Collection getAll() throws IOException {
+ public static Collection getAll() throws IOException {
final Set result = new TreeSet<>();
final InputStream home = getInternalInputStream("home", ".repx");
+ if (home == null)
+ throw new IOException("Cannot access to /stdlib/*.repx files");
+
final BufferedReader br = new BufferedReader(new InputStreamReader(home));
String name;
while ((name = br.readLine()) != null)
@@ -442,11 +451,11 @@ public class Stdlib {
}
}
- private String getVersion() {
+ public String getVersion() {
return info.get("VERSION");
}
- private String getSource() {
+ public String getSource() {
return info.get("SOURCE");
}
diff --git a/src/net/sourceforge/plantuml/preproc/Sub.java b/src/net/sourceforge/plantuml/preproc/Sub.java
index 00b7bddcd..b39e8d4d0 100644
--- a/src/net/sourceforge/plantuml/preproc/Sub.java
+++ b/src/net/sourceforge/plantuml/preproc/Sub.java
@@ -48,7 +48,7 @@ import net.sourceforge.plantuml.tim.TContext;
import net.sourceforge.plantuml.tim.TMemory;
public class Sub {
- // ::remove folder when __HAXE__
+ // ::remove folder when __HAXE__
private final String name;
private final List lines = new ArrayList<>();
diff --git a/src/net/sourceforge/plantuml/preproc/Truth.java b/src/net/sourceforge/plantuml/preproc/Truth.java
index 7a33da793..1ec283d02 100644
--- a/src/net/sourceforge/plantuml/preproc/Truth.java
+++ b/src/net/sourceforge/plantuml/preproc/Truth.java
@@ -36,6 +36,7 @@
package net.sourceforge.plantuml.preproc;
public interface Truth {
+
public boolean isTrue(String name);
}
diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java
index ee238c99c..8132faab8 100644
--- a/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java
+++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java
@@ -54,7 +54,6 @@ import net.sourceforge.plantuml.preproc.Stdlib;
import net.sourceforge.plantuml.security.SURL;
import net.sourceforge.plantuml.text.StringLocated;
import net.sourceforge.plantuml.tim.EaterException;
-import net.sourceforge.plantuml.utils.LineLocation;
import net.sourceforge.plantuml.utils.Log;
public class PreprocessorUtils {
@@ -139,21 +138,21 @@ public class PreprocessorUtils {
if (StartDiagramExtractReader.containsStartDiagram(url, s, charset))
return StartDiagramExtractReader.build(url, s, suf, charset);
- return getReaderInclude(url, s.getLocation(), charset);
+ return getReaderInclude(url, s, charset);
} catch (IOException e) {
Logme.error(e);
- throw EaterException.located("Cannot open URL " + e.getMessage());
+ throw new EaterException("Cannot open URL " + e.getMessage(), s);
}
}
- public static ReadLine getReaderInclude(SURL url, LineLocation lineLocation, Charset charset)
+ public static ReadLine getReaderInclude(SURL url, StringLocated s, Charset charset)
throws EaterException, UnsupportedEncodingException {
final InputStream is = url.openStream();
if (is == null)
- throw EaterException.located("Cannot open URL");
+ throw new EaterException("Cannot open URL", s);
- return ReadLineReader.create(new InputStreamReader(is, charset), url.toString(), lineLocation);
+ return ReadLineReader.create(new InputStreamReader(is, charset), url.toString(), s.getLocation());
}
}
diff --git a/src/net/sourceforge/plantuml/project/ConstantPlan.java b/src/net/sourceforge/plantuml/project/ConstantPlan.java
index 67ebf79eb..0d0b74b3c 100644
--- a/src/net/sourceforge/plantuml/project/ConstantPlan.java
+++ b/src/net/sourceforge/plantuml/project/ConstantPlan.java
@@ -53,8 +53,14 @@ public class ConstantPlan implements LoadPlanable {
return new ConstantPlan(load);
}
+ @Override
public int getLoadAt(Day instant) {
return loadPerInstant;
}
+
+ @Override
+ public Day getLastDayIfAny() {
+ return null;
+ }
}
diff --git a/src/net/sourceforge/plantuml/project/GanttDiagram.java b/src/net/sourceforge/plantuml/project/GanttDiagram.java
index fdc8a18c0..44e2bb2e6 100644
--- a/src/net/sourceforge/plantuml/project/GanttDiagram.java
+++ b/src/net/sourceforge/plantuml/project/GanttDiagram.java
@@ -51,7 +51,6 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.TitledDiagram;
import net.sourceforge.plantuml.WithSprite;
@@ -86,6 +85,7 @@ import net.sourceforge.plantuml.project.core.TaskInstant;
import net.sourceforge.plantuml.project.core.TaskSeparator;
import net.sourceforge.plantuml.project.draw.FingerPrint;
import net.sourceforge.plantuml.project.draw.ResourceDraw;
+import net.sourceforge.plantuml.project.draw.ResourceDrawBasic;
import net.sourceforge.plantuml.project.draw.TaskDraw;
import net.sourceforge.plantuml.project.draw.TaskDrawDiamond;
import net.sourceforge.plantuml.project.draw.TaskDrawGroup;
@@ -99,6 +99,7 @@ import net.sourceforge.plantuml.project.draw.TimeHeaderSimple;
import net.sourceforge.plantuml.project.draw.TimeHeaderWeekly;
import net.sourceforge.plantuml.project.draw.TimeHeaderYearly;
import net.sourceforge.plantuml.project.lang.CenterBorderColor;
+import net.sourceforge.plantuml.project.solver.ImpossibleSolvingException;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.time.WeekNumberStrategy;
@@ -115,7 +116,7 @@ import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.svek.GraphvizCrash;
import net.sourceforge.plantuml.text.BackSlash;
-public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprite {
+public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprite, GanttStyle {
private final Map draws = new LinkedHashMap();
private final Map tasks = new LinkedHashMap();
@@ -149,13 +150,18 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private final RealOrigin origin = RealUtils.createOrigin();
+ private int defaultCompletion = 100;
+
+ private Task it;
+ private Resource they;
+
public CommandExecutionResult changeLanguage(String lang) {
this.locale = new Locale(lang);
return CommandExecutionResult.ok();
}
public DiagramDescription getDescription() {
- return new DiagramDescription("(Project)");
+ return new DiagramDescription("(Gantt)");
}
public void setWeekNumberStrategy(DayOfWeek firstDayOfWeek, int minimalDaysInFirstWeek) {
@@ -173,8 +179,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
@Override
protected ImageData exportDiagramNow(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException {
- final StringBounder stringBounder = fileFormatOption.getDefaultStringBounder(getSkinParam());
- return createImageBuilder(fileFormatOption).drawable(getTextBlock(stringBounder)).write(os);
+ return createImageBuilder(fileFormatOption).drawable(getTextMainBlock(fileFormatOption)).write(os);
}
public void setPrintScale(PrintScale printScale) {
@@ -203,21 +208,27 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
}
@Override
- protected TextBlock getTextBlock() {
- final FileFormatOption fileFormatOption = new FileFormatOption(FileFormat.PNG);
- final StringBounder stringBounder = fileFormatOption.getDefaultStringBounder(getSkinParam());
- return getTextBlock(stringBounder);
+ public String checkFinalError() {
+ try {
+ initMinMax();
+ } catch (ImpossibleSolvingException ex) {
+ return ex.getMessage();
+ }
+ return null;
}
- private TextBlock getTextBlock(StringBounder stringBounder) {
+ @Override
+ protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) {
+ final StringBounder stringBounder = fileFormatOption.getDefaultStringBounder(getSkinParam());
if (printStart == null) {
initMinMax();
} else {
this.min = printStart;
this.max = printEnd;
}
- final TimeHeader timeHeader = getTimeHeader();
- initTaskAndResourceDraws(timeHeader.getTimeScale(), timeHeader.getFullHeaderHeight(), stringBounder);
+ final TimeHeader timeHeader = getTimeHeader(stringBounder);
+ initTaskAndResourceDraws(timeHeader.getTimeScale(), timeHeader.getFullHeaderHeight(stringBounder),
+ stringBounder);
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
@@ -233,12 +244,12 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
final HColor back = timelineStyle.value(PName.BackGroundColor).asColor(getIHtmlColorSet());
if (back.isTransparent() == false) {
final URectangle rect1 = URectangle.build(calculateDimension(ug.getStringBounder()).getWidth(),
- timeHeader.getTimeHeaderHeight());
+ timeHeader.getTimeHeaderHeight(ug.getStringBounder()));
ug.apply(back.bg()).draw(rect1);
if (showFootbox) {
final URectangle rect2 = URectangle.build(
calculateDimension(ug.getStringBounder()).getWidth(),
- timeHeader.getTimeFooterHeight());
+ timeHeader.getTimeFooterHeight(ug.getStringBounder()));
ug.apply(back.bg()).apply(UTranslate.dy(totalHeightWithoutFooter)).draw(rect2);
}
}
@@ -280,7 +291,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
public XDimension2D calculateDimension(StringBounder stringBounder) {
return new XDimension2D(getTitlesColumnWidth(stringBounder) + getBarsColumnWidth(timeHeader),
- getTotalHeight(timeHeader));
+ getTotalHeight(stringBounder, timeHeader));
}
private double getBarsColumnWidth(final TimeHeader timeHeader) {
@@ -292,27 +303,27 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
};
}
- private TimeHeader getTimeHeader() {
+ private TimeHeader getTimeHeader(StringBounder stringBounder) {
if (openClose.getStartingDay() == null)
- return new TimeHeaderSimple(thParam(), printScale);
+ return new TimeHeaderSimple(stringBounder, thParam(), printScale);
else if (printScale == PrintScale.DAILY)
- return new TimeHeaderDaily(thParam(), nameDays, printStart, printEnd);
+ return new TimeHeaderDaily(stringBounder, thParam(), nameDays, printStart);
else if (printScale == PrintScale.WEEKLY)
- return new TimeHeaderWeekly(thParam(), weekNumberStrategy, withCalendarDate);
+ return new TimeHeaderWeekly(stringBounder, thParam(), weekNumberStrategy, withCalendarDate, printStart);
else if (printScale == PrintScale.MONTHLY)
- return new TimeHeaderMonthly(thParam());
+ return new TimeHeaderMonthly(stringBounder, thParam(), printStart);
else if (printScale == PrintScale.QUARTERLY)
- return new TimeHeaderQuarterly(thParam());
+ return new TimeHeaderQuarterly(stringBounder, thParam(), printStart);
else if (printScale == PrintScale.YEARLY)
- return new TimeHeaderYearly(thParam());
+ return new TimeHeaderYearly(stringBounder, thParam(), printStart);
else
throw new IllegalStateException();
}
private TimeHeaderParameters thParam() {
- return new TimeHeaderParameters(colorDays(), getFactorScale(), min, max, getIHtmlColorSet(), getTimelineStyle(),
- getClosedStyle(), locale, openClose, colorDaysOfWeek, verticalSeparatorBefore);
+ return new TimeHeaderParameters(colorDays(), getFactorScale(), min, max, getIHtmlColorSet(), locale, openClose,
+ colorDaysOfWeek, verticalSeparatorBefore, this);
}
private Map colorDays() {
@@ -320,19 +331,21 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
return Collections.unmodifiableMap(colorDaysInternal);
}
- private Style getClosedStyle() {
- return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, SName.closed)
+ @Override
+ public final Style getStyle(SName param) {
+ return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, param)
.getMergedStyle(getCurrentStyleBuilder());
}
- private Style getTimelineStyle() {
- return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, SName.timeline)
+ @Override
+ public final Style getStyle(SName param1, SName param2) {
+ return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, param1, param2)
.getMergedStyle(getCurrentStyleBuilder());
}
- private double getTotalHeight(TimeHeader timeHeader) {
+ private double getTotalHeight(StringBounder stringBounder, TimeHeader timeHeader) {
if (showFootbox)
- return totalHeightWithoutFooter + timeHeader.getTimeFooterHeight();
+ return totalHeightWithoutFooter + timeHeader.getTimeFooterHeight(stringBounder);
return totalHeightWithoutFooter;
}
@@ -430,13 +443,12 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
} else if (task instanceof TaskGroup) {
final TaskGroup taskGroup = (TaskGroup) task;
draw = new TaskDrawGroup(timeScale, y, taskGroup.getCode().getSimpleDisplay(), getStart(taskGroup),
- getEnd(taskGroup), getSkinParam(), task, this, task.getStyleBuilder());
+ getEnd(taskGroup), task, this, task.getStyleBuilder());
} else {
final TaskImpl tmp = (TaskImpl) task;
final String disp = hideResourceName ? tmp.getCode().getSimpleDisplay() : tmp.getPrettyDisplay();
if (tmp.isDiamond()) {
- draw = new TaskDrawDiamond(timeScale, y, disp, getStart(tmp), getSkinParam(), task, this,
- task.getStyleBuilder());
+ draw = new TaskDrawDiamond(timeScale, y, disp, getStart(tmp), task, this, task.getStyleBuilder());
} else {
final boolean oddStart = printStart != null && min.compareTo(getStart(tmp)) == 0;
final boolean oddEnd = printStart != null && max.compareTo(getEnd(tmp)) == 0;
@@ -457,14 +469,20 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
yy = headerHeight;
} else if (this.hideResourceFoobox == false)
for (Resource res : resources.values()) {
- final ResourceDraw draw = new ResourceDraw(this, res, timeScale, yy, min, max);
+ final ResourceDraw draw = buildResourceDraw(this, res, timeScale, yy, min, max);
res.setTaskDraw(draw);
- yy += draw.getHeight();
+ yy += draw.getHeight(stringBounder);
}
this.totalHeightWithoutFooter = yy;
}
+ private ResourceDraw buildResourceDraw(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Day min,
+ Day max) {
+ return new ResourceDrawBasic(gantt, res, timeScale, y, min, max);
+ // return new ResourceDrawVersion2(gantt, res, timeScale, y, min, max);
+ }
+
private Collection getConstraints(Task task) {
final List result = new ArrayList<>();
for (GanttConstraint constraint : constraints) {
@@ -603,7 +621,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
final OpenClose except = this.openCloseForTask.get(codeOrShortName);
result = new TaskImpl(getSkinParam().getCurrentStyleBuilder(), code, openClose.mutateMe(except),
- openClose.getStartingDay());
+ openClose.getStartingDay(), defaultCompletion);
if (currentGroup != null)
currentGroup.addTask(result);
@@ -866,4 +884,35 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
verticalSeparatorBefore.add(day);
}
+ public void setTaskDefaultCompletion(int defaultCompletion) {
+ this.defaultCompletion = defaultCompletion;
+ }
+
+ public List getAllTasksForResource(Resource res) {
+ final List result = new ArrayList();
+ for (Task task : tasks.values())
+ if (task.isAssignedTo(res)) {
+ final TaskDrawRegular draw = (TaskDrawRegular) draws.get(task);
+ result.add(draw);
+ }
+
+ return Collections.unmodifiableList(result);
+ }
+
+ public void setIt(Task result) {
+ this.it = result;
+ }
+
+ public Task getIt() {
+ return it;
+ }
+
+ public final Resource getThey() {
+ return they;
+ }
+
+ public final void setThey(Resource they) {
+ this.they = they;
+ }
+
}
diff --git a/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java b/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java
index 392990439..ceb183bcb 100644
--- a/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java
+++ b/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java
@@ -59,6 +59,7 @@ import net.sourceforge.plantuml.project.command.CommandNoteBottom;
import net.sourceforge.plantuml.project.command.CommandPrintBetween;
import net.sourceforge.plantuml.project.command.CommandPrintScale;
import net.sourceforge.plantuml.project.command.CommandSeparator;
+import net.sourceforge.plantuml.project.command.CommandTaskCompleteDefault;
import net.sourceforge.plantuml.project.command.CommandWeekNumberStrategy;
import net.sourceforge.plantuml.project.command.NaturalCommand;
import net.sourceforge.plantuml.project.lang.SentenceAnd;
@@ -78,8 +79,8 @@ import net.sourceforge.plantuml.style.CommandStyleMultilinesCSS;
public class GanttDiagramFactory extends PSystemCommandFactory {
- static private final List subjects() {
- return Arrays.asList(SubjectTask.ME, SubjectProject.ME, SubjectDayOfWeek.ME, SubjectDayAsDate.ME,
+ static private final List> subjects() {
+ return Arrays.asList(SubjectTask.ME, SubjectProject.ME, SubjectDayOfWeek.ME, SubjectDayAsDate.ME,
SubjectDaysAsDates.ME, SubjectResource.ME, SubjectToday.ME, SubjectSeparator.ME);
}
@@ -115,31 +116,32 @@ public class GanttDiagramFactory extends PSystemCommandFactory {
cmds.add(new CommandLabelOnColumn());
cmds.add(new CommandHideResourceName());
cmds.add(new CommandHideResourceFootbox());
+ cmds.add(new CommandTaskCompleteDefault());
}
private void addLanguageCommands(List cmd) {
- for (Subject subject : subjects())
- for (SentenceSimple sentenceA : subject.getSentences()) {
+ for (Subject subject : subjects())
+ for (SentenceSimple sentenceA : subject.getSentences()) {
cmd.add(NaturalCommand.create(sentenceA));
- for (SentenceSimple sentenceB : subject.getSentences()) {
+ for (SentenceSimple sentenceB : subject.getSentences()) {
final String signatureA = sentenceA.getSignature();
final String signatureB = sentenceB.getSignature();
if (signatureA.equals(signatureB) == false)
- cmd.add(NaturalCommand.create(new SentenceAnd(sentenceA, sentenceB)));
+ cmd.add(NaturalCommand.create(new SentenceAnd(sentenceA, sentenceB)));
}
}
- for (Subject subject : subjects())
- for (SentenceSimple sentenceA : subject.getSentences())
- for (SentenceSimple sentenceB : subject.getSentences())
- for (SentenceSimple sentenceC : subject.getSentences()) {
+ for (Subject subject : subjects())
+ for (SentenceSimple sentenceA : subject.getSentences())
+ for (SentenceSimple sentenceB : subject.getSentences())
+ for (SentenceSimple sentenceC : subject.getSentences()) {
final String signatureA = sentenceA.getSignature();
final String signatureB = sentenceB.getSignature();
final String signatureC = sentenceC.getSignature();
if (signatureA.equals(signatureB) == false && signatureA.equals(signatureC) == false
&& signatureC.equals(signatureB) == false)
- cmd.add(NaturalCommand.create(new SentenceAndAnd(sentenceA, sentenceB, sentenceC)));
+ cmd.add(NaturalCommand.create(new SentenceAndAnd(sentenceA, sentenceB, sentenceC)));
}
}
diff --git a/src/net/sourceforge/plantuml/project/GanttStyle.java b/src/net/sourceforge/plantuml/project/GanttStyle.java
new file mode 100644
index 000000000..44e15537d
--- /dev/null
+++ b/src/net/sourceforge/plantuml/project/GanttStyle.java
@@ -0,0 +1,47 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.project;
+
+import net.sourceforge.plantuml.style.SName;
+import net.sourceforge.plantuml.style.Style;
+
+public interface GanttStyle {
+
+ public Style getStyle(SName param);
+
+ public Style getStyle(SName param1, SName param2);
+
+}
diff --git a/src/net/sourceforge/plantuml/project/LoadPlanable.java b/src/net/sourceforge/plantuml/project/LoadPlanable.java
index d8e71f71d..76ad4c539 100644
--- a/src/net/sourceforge/plantuml/project/LoadPlanable.java
+++ b/src/net/sourceforge/plantuml/project/LoadPlanable.java
@@ -40,4 +40,6 @@ import net.sourceforge.plantuml.project.time.Day;
public interface LoadPlanable {
public int getLoadAt(Day instant);
+
+ public Day getLastDayIfAny();
}
diff --git a/src/net/sourceforge/plantuml/project/OpenClose.java b/src/net/sourceforge/plantuml/project/OpenClose.java
index 1e8afbf65..7d0256c6d 100644
--- a/src/net/sourceforge/plantuml/project/OpenClose.java
+++ b/src/net/sourceforge/plantuml/project/OpenClose.java
@@ -49,6 +49,8 @@ public class OpenClose implements Histogram, LoadPlanable {
private final Map weekdayStatus = new EnumMap<>(DayOfWeek.class);
private final Map dayStatus = new HashMap<>();
private Day startingDay;
+ private Day offBefore;
+ private Day offAfter;
public int daysInWeek() {
int result = 7;
@@ -89,6 +91,11 @@ public class OpenClose implements Histogram, LoadPlanable {
}
private DayStatus getLocalStatus(Day day) {
+ if (offBefore != null && day.compareTo(offBefore) < 0)
+ return DayStatus.CLOSE;
+ if (offAfter != null && day.compareTo(offAfter) > 0)
+ return DayStatus.CLOSE;
+
final DayStatus status1 = dayStatus.get(day);
if (status1 != null)
return status1;
@@ -174,6 +181,14 @@ public class OpenClose implements Histogram, LoadPlanable {
return getLoatAtInternal(day);
}
+ public void setOffBeforeDate(Day day) {
+ this.offBefore = day;
+ }
+
+ public void setOffAfterDate(Day day) {
+ this.offAfter = day;
+ }
+
private int getLoatAtInternal(Day day) {
if (isClosed(day))
return 0;
@@ -193,8 +208,18 @@ public class OpenClose implements Histogram, LoadPlanable {
return 100;
return OpenClose.this.getLoadAt(instant);
}
+
+ @Override
+ public Day getLastDayIfAny() {
+ return offAfter;
+ }
};
return this;
}
+ @Override
+ public Day getLastDayIfAny() {
+ return offAfter;
+ }
+
}
diff --git a/src/net/sourceforge/plantuml/project/PlanUtils.java b/src/net/sourceforge/plantuml/project/PlanUtils.java
index b80f591b8..d75adfd5e 100644
--- a/src/net/sourceforge/plantuml/project/PlanUtils.java
+++ b/src/net/sourceforge/plantuml/project/PlanUtils.java
@@ -48,6 +48,10 @@ public class PlanUtils {
public int getLoadAt(Day instant) {
return Math.min(p1.getLoadAt(instant), p2.getLoadAt(instant));
}
+
+ public Day getLastDayIfAny() {
+ return lastOf(p1.getLastDayIfAny(), p2.getLastDayIfAny());
+ }
};
}
@@ -56,7 +60,21 @@ public class PlanUtils {
public int getLoadAt(Day instant) {
return p1.getLoadAt(instant) * p2.getLoadAt(instant) / 100;
}
+
+ public Day getLastDayIfAny() {
+ return lastOf(p1.getLastDayIfAny(), p2.getLastDayIfAny());
+ }
};
}
+ private static Day lastOf(Day day1, Day day2) {
+ if (day1 == null)
+ return day2;
+ if (day2 == null)
+ return day1;
+ if (day1.compareTo(day2) > 0)
+ return day1;
+ return day2;
+ }
+
}
diff --git a/src/net/sourceforge/plantuml/project/TimeHeaderParameters.java b/src/net/sourceforge/plantuml/project/TimeHeaderParameters.java
index 95bcdd4f4..c140797ac 100644
--- a/src/net/sourceforge/plantuml/project/TimeHeaderParameters.java
+++ b/src/net/sourceforge/plantuml/project/TimeHeaderParameters.java
@@ -37,38 +37,42 @@ package net.sourceforge.plantuml.project;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
+import net.sourceforge.plantuml.klimt.UStroke;
import net.sourceforge.plantuml.klimt.color.HColor;
import net.sourceforge.plantuml.klimt.color.HColorSet;
+import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
+import net.sourceforge.plantuml.style.PName;
+import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
-public class TimeHeaderParameters {
+public class TimeHeaderParameters implements GanttStyle {
private final Map colorDays;
private final double scale;
private final Day min;
private final Day max;
private final HColorSet colorSet;
- private final Style timelineStyle;
- private final Style closedStyle;
+ private final GanttStyle ganttStyle;
private final Locale locale;
private final OpenClose openClose;
private final Map colorDaysOfWeek;
private final Set verticalSeparatorBefore;
public TimeHeaderParameters(Map colorDays, double scale, Day min, Day max, HColorSet colorSet,
- Style timelineStyle, Style closedStyle, Locale locale, OpenClose openClose,
- Map colorDaysOfWeek, Set verticalSeparatorBefore) {
+ Locale locale, OpenClose openClose, Map colorDaysOfWeek,
+ Set verticalSeparatorBefore, GanttStyle ganttStyle) {
this.colorDays = colorDays;
this.scale = scale;
this.min = min;
this.max = max;
- this.colorSet = colorSet;
- this.timelineStyle = timelineStyle;
- this.closedStyle = closedStyle;
+ this.colorSet = Objects.requireNonNull(colorSet);
+ this.ganttStyle = ganttStyle;
this.locale = locale;
this.openClose = openClose;
this.colorDaysOfWeek = colorDaysOfWeek;
@@ -100,11 +104,11 @@ public class TimeHeaderParameters {
}
public final Style getTimelineStyle() {
- return timelineStyle;
+ return getStyle(SName.timeline);
}
public final Style getClosedStyle() {
- return closedStyle;
+ return getStyle(SName.closed);
}
public final Locale getLocale() {
@@ -123,4 +127,26 @@ public class TimeHeaderParameters {
return verticalSeparatorBefore;
}
+ public final UGraphic forVerticalSeparator(UGraphic ug) {
+ final Style style = getStyle(SName.verticalSeparator);
+ final HColor color = style.value(PName.LineColor).asColor(getColorSet());
+ final UStroke stroke = style.getStroke();
+ return ug.apply(color).apply(stroke);
+ }
+
+ @Override
+ public final Style getStyle(SName param1, SName param2) {
+ return ganttStyle.getStyle(param1, param2);
+ }
+
+ @Override
+ public Style getStyle(SName param) {
+ return ganttStyle.getStyle(param);
+ }
+
+ public double getCellWidth(StringBounder stringBounder) {
+ final double w = getStyle(SName.timeline, SName.day).value(PName.FontSize).asDouble();
+ return w * 1.6;
+ }
+
}
diff --git a/src/net/sourceforge/plantuml/project/command/CommandColorTask.java b/src/net/sourceforge/plantuml/project/command/CommandColorTask.java
index 57f5e58c0..6c5583384 100644
--- a/src/net/sourceforge/plantuml/project/command/CommandColorTask.java
+++ b/src/net/sourceforge/plantuml/project/command/CommandColorTask.java
@@ -59,7 +59,8 @@ public class CommandColorTask extends SingleLineCommand2 {
new RegexLeaf("CODE", "\\[([%pLN_.]+)\\]"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("COLORS", "#(\\w+)(?:/(#?\\w+))?"), //
- RegexLeaf.spaceZeroOrMore(), RegexLeaf.end());
+ RegexLeaf.spaceZeroOrMore(), //
+ RegexLeaf.end());
}
@Override
diff --git a/src/net/sourceforge/plantuml/project/command/CommandFootbox.java b/src/net/sourceforge/plantuml/project/command/CommandFootbox.java
index 43697e905..36ce4504c 100644
--- a/src/net/sourceforge/plantuml/project/command/CommandFootbox.java
+++ b/src/net/sourceforge/plantuml/project/command/CommandFootbox.java
@@ -45,7 +45,7 @@ import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.utils.LineLocation;
public class CommandFootbox extends SingleLineCommand2 {
- // ::remove folder when __HAXE__
+ // ::remove folder when __HAXE__
public CommandFootbox() {
super(getRegexConcat());
@@ -55,7 +55,8 @@ public class CommandFootbox extends SingleLineCommand2 {
return RegexConcat.build(CommandFootbox.class.getName(), RegexLeaf.start(), //
new RegexLeaf("TYPE", "(hide|show)?"), //
RegexLeaf.spaceZeroOrMore(), //
- new RegexLeaf("footbox"), RegexLeaf.end()); //
+ new RegexLeaf("footbox"), //
+ RegexLeaf.end());
}
@Override
diff --git a/src/net/sourceforge/plantuml/project/command/CommandGanttArrow.java b/src/net/sourceforge/plantuml/project/command/CommandGanttArrow.java
index 1c1c55a30..0929fd2a8 100644
--- a/src/net/sourceforge/plantuml/project/command/CommandGanttArrow.java
+++ b/src/net/sourceforge/plantuml/project/command/CommandGanttArrow.java
@@ -63,7 +63,8 @@ public class CommandGanttArrow extends SingleLineCommand2 {
new RegexLeaf("\\>"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("CODE2", "([%pLN_.]+)"), //
- RegexLeaf.spaceZeroOrMore(), RegexLeaf.end());
+ RegexLeaf.spaceZeroOrMore(), //
+ RegexLeaf.end());
}
@Override
diff --git a/src/net/sourceforge/plantuml/project/command/CommandHideResourceFootbox.java b/src/net/sourceforge/plantuml/project/command/CommandHideResourceFootbox.java
index acfa84310..08e48fa3c 100644
--- a/src/net/sourceforge/plantuml/project/command/CommandHideResourceFootbox.java
+++ b/src/net/sourceforge/plantuml/project/command/CommandHideResourceFootbox.java
@@ -57,7 +57,7 @@ public class CommandHideResourceFootbox extends SingleLineCommand2
new RegexLeaf("ress?ources?"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("footbox"), //
- RegexLeaf.end()); //
+ RegexLeaf.end());
}
@Override
diff --git a/src/net/sourceforge/plantuml/project/command/CommandHideResourceName.java b/src/net/sourceforge/plantuml/project/command/CommandHideResourceName.java
index e343e3461..e386dee8c 100644
--- a/src/net/sourceforge/plantuml/project/command/CommandHideResourceName.java
+++ b/src/net/sourceforge/plantuml/project/command/CommandHideResourceName.java
@@ -57,7 +57,7 @@ public class CommandHideResourceName extends SingleLineCommand2 {
new RegexLeaf("ress?ources?"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("names?"), //
- RegexLeaf.end()); //
+ RegexLeaf.end());
}
@Override
diff --git a/src/net/sourceforge/plantuml/project/command/CommandLabelOnColumn.java b/src/net/sourceforge/plantuml/project/command/CommandLabelOnColumn.java
index ff2d12789..949f12e64 100644
--- a/src/net/sourceforge/plantuml/project/command/CommandLabelOnColumn.java
+++ b/src/net/sourceforge/plantuml/project/command/CommandLabelOnColumn.java
@@ -70,7 +70,8 @@ public class CommandLabelOnColumn extends SingleLineCommand2 {
new RegexLeaf("ALIGNED", "(left|right)"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("aligned") //
- )), RegexLeaf.end()); //
+ )), //
+ RegexLeaf.end());
}
@Override
diff --git a/src/net/sourceforge/plantuml/project/command/CommandLanguage.java b/src/net/sourceforge/plantuml/project/command/CommandLanguage.java
index cae28078d..a8532b63d 100644
--- a/src/net/sourceforge/plantuml/project/command/CommandLanguage.java
+++ b/src/net/sourceforge/plantuml/project/command/CommandLanguage.java
@@ -55,7 +55,7 @@ public class CommandLanguage extends SingleLineCommand2 {
new RegexLeaf("language"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("LANG", "(\\w+)"), //
- RegexLeaf.end()); //
+ RegexLeaf.end());
}
@Override
diff --git a/src/net/sourceforge/plantuml/project/command/CommandPrintBetween.java b/src/net/sourceforge/plantuml/project/command/CommandPrintBetween.java
index cc0412fb2..5c0d1a8a5 100644
--- a/src/net/sourceforge/plantuml/project/command/CommandPrintBetween.java
+++ b/src/net/sourceforge/plantuml/project/command/CommandPrintBetween.java
@@ -48,7 +48,7 @@ import net.sourceforge.plantuml.utils.LineLocation;
public class CommandPrintBetween extends SingleLineCommand2 {
- private static final ComplementDate pattern = new ComplementDate();
+ private static final ComplementDate pattern = ComplementDate.any();
public CommandPrintBetween() {
super(getRegexConcat());
@@ -66,7 +66,7 @@ public class CommandPrintBetween extends SingleLineCommand2 {
new RegexLeaf("and"), //
RegexLeaf.spaceOneOrMore(), //
pattern.toRegex("END"), //
- RegexLeaf.end()); //
+ RegexLeaf.end());
}
@Override
diff --git a/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java b/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java
index c82a9c027..84b1a6edb 100644
--- a/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java
+++ b/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java
@@ -77,7 +77,7 @@ public class CommandPrintScale extends SingleLineCommand2 {
new RegexLeaf("zoom"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("ZOOM", "([.\\d]+)"))), //
- RegexLeaf.end()); //
+ RegexLeaf.end());
}
@Override
diff --git a/src/net/sourceforge/plantuml/project/command/CommandTaskCompleteDefault.java b/src/net/sourceforge/plantuml/project/command/CommandTaskCompleteDefault.java
new file mode 100644
index 000000000..794c91455
--- /dev/null
+++ b/src/net/sourceforge/plantuml/project/command/CommandTaskCompleteDefault.java
@@ -0,0 +1,83 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.project.command;
+
+import net.sourceforge.plantuml.command.CommandExecutionResult;
+import net.sourceforge.plantuml.command.SingleLineCommand2;
+import net.sourceforge.plantuml.klimt.color.NoSuchColorException;
+import net.sourceforge.plantuml.project.GanttDiagram;
+import net.sourceforge.plantuml.regex.IRegex;
+import net.sourceforge.plantuml.regex.RegexConcat;
+import net.sourceforge.plantuml.regex.RegexLeaf;
+import net.sourceforge.plantuml.regex.RegexOr;
+import net.sourceforge.plantuml.regex.RegexResult;
+import net.sourceforge.plantuml.utils.LineLocation;
+
+public class CommandTaskCompleteDefault extends SingleLineCommand2 {
+
+ public CommandTaskCompleteDefault() {
+ super(getRegexConcat());
+ }
+
+ static IRegex getRegexConcat() {
+ return RegexConcat.build(CommandTaskCompleteDefault.class.getName(), RegexLeaf.start(), //
+ new RegexLeaf("task"), //
+ RegexLeaf.spaceOneOrMore(), //
+ new RegexOr(//
+ new RegexLeaf("default[%s]+completion"), //
+ new RegexLeaf("completion[%s]+default")), //
+ RegexLeaf.spaceOneOrMore(), //
+ new RegexLeaf("to"), //
+ RegexLeaf.spaceOneOrMore(), //
+ new RegexLeaf("VALUE", "(\\d+)"), //
+ new RegexLeaf(".*"), //
+ RegexLeaf.end());
+ }
+
+ @Override
+ protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg)
+ throws NoSuchColorException {
+
+ final int value = Integer.parseInt(arg.get("VALUE", 0));
+ if (value > 100)
+ return CommandExecutionResult.error("Completetion must between 0 and 100");
+
+ diagram.setTaskDefaultCompletion(value);
+
+ return CommandExecutionResult.ok();
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/project/command/NaturalCommand.java b/src/net/sourceforge/plantuml/project/command/NaturalCommand.java
index 2da5d3792..88511e131 100644
--- a/src/net/sourceforge/plantuml/project/command/NaturalCommand.java
+++ b/src/net/sourceforge/plantuml/project/command/NaturalCommand.java
@@ -37,27 +37,27 @@ package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2;
-import net.sourceforge.plantuml.project.GanttDiagram;
+import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.project.lang.Sentence;
import net.sourceforge.plantuml.regex.RegexResult;
import net.sourceforge.plantuml.utils.LineLocation;
-public class NaturalCommand extends SingleLineCommand2 {
+public class NaturalCommand extends SingleLineCommand2 {
- private final Sentence sentence;
+ private final Sentence sentence;
- public NaturalCommand(Sentence sentence) {
+ public NaturalCommand(Sentence sentence) {
super(sentence.toRegex());
this.sentence = sentence;
}
@Override
- final protected CommandExecutionResult executeArg(GanttDiagram system, LineLocation location, RegexResult arg) {
+ final protected CommandExecutionResult executeArg(D system, LineLocation location, RegexResult arg) {
return sentence.execute(system, arg);
}
- public static NaturalCommand create(Sentence sentence) {
- return new NaturalCommand(sentence);
+ public static NaturalCommand create(Sentence sentence) {
+ return new NaturalCommand(sentence);
}
diff --git a/src/net/sourceforge/plantuml/project/core/AbstractTask.java b/src/net/sourceforge/plantuml/project/core/AbstractTask.java
index fe74f41cf..69d385016 100644
--- a/src/net/sourceforge/plantuml/project/core/AbstractTask.java
+++ b/src/net/sourceforge/plantuml/project/core/AbstractTask.java
@@ -35,6 +35,7 @@
*/
package net.sourceforge.plantuml.project.core;
+import net.sourceforge.plantuml.stereo.Stereotype;
import net.sourceforge.plantuml.style.StyleBuilder;
public abstract class AbstractTask implements Task {
@@ -43,27 +44,54 @@ public abstract class AbstractTask implements Task {
private final StyleBuilder styleBuilder;
private Task row;
+ private String displayString;
+ private Stereotype stereotype;
protected AbstractTask(StyleBuilder styleBuilder, TaskCode code) {
this.styleBuilder = styleBuilder;
this.code = code;
}
+ @Override
final public void putInSameRowAs(Task row) {
if (this != row)
this.row = row;
}
+ @Override
public final Task getRow() {
return row;
}
+ @Override
public final TaskCode getCode() {
return code;
}
+ @Override
public final StyleBuilder getStyleBuilder() {
return styleBuilder;
}
+ @Override
+ public void setDisplay(String displayString) {
+ this.displayString = displayString;
+ }
+
+ @Override
+ public String getDisplayString() {
+ return this.displayString;
+ }
+
+ @Override
+ public Stereotype getStereotype() {
+ return stereotype;
+ }
+
+ @Override
+ public final void setStereotype(Stereotype stereotype) {
+ this.stereotype = stereotype;
+ }
+
+
}
diff --git a/src/net/sourceforge/plantuml/project/core/Resource.java b/src/net/sourceforge/plantuml/project/core/Resource.java
index 687b479a2..594209158 100644
--- a/src/net/sourceforge/plantuml/project/core/Resource.java
+++ b/src/net/sourceforge/plantuml/project/core/Resource.java
@@ -94,4 +94,17 @@ public class Resource {
public void addCloseDay(DayOfWeek day) {
openClose.close(day);
}
+
+ public void setOffBeforeDate(Day day) {
+ openClose.setOffBeforeDate(day);
+ }
+
+ public void setOffAfterDate(Day day) {
+ openClose.setOffAfterDate(day);
+ }
+
+ public Day getLastDayIfAny() {
+ return openClose.getLastDayIfAny();
+ }
+
}
diff --git a/src/net/sourceforge/plantuml/project/core/Task.java b/src/net/sourceforge/plantuml/project/core/Task.java
index 653cff0d2..b6b2bc351 100644
--- a/src/net/sourceforge/plantuml/project/core/Task.java
+++ b/src/net/sourceforge/plantuml/project/core/Task.java
@@ -40,6 +40,7 @@ import net.sourceforge.plantuml.project.Load;
import net.sourceforge.plantuml.project.lang.CenterBorderColor;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
+import net.sourceforge.plantuml.stereo.Stereotype;
import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.url.Url;
@@ -79,4 +80,14 @@ public interface Task extends Moment {
public StyleBuilder getStyleBuilder();
+ public boolean isAssignedTo(Resource res);
+
+ public void setDisplay(String displayString);
+
+ public String getDisplayString();
+
+ public Stereotype getStereotype();
+
+ public void setStereotype(Stereotype stereotype);
+
}
diff --git a/src/net/sourceforge/plantuml/project/core/TaskGroup.java b/src/net/sourceforge/plantuml/project/core/TaskGroup.java
index 804e08bf1..b8d1e8c49 100644
--- a/src/net/sourceforge/plantuml/project/core/TaskGroup.java
+++ b/src/net/sourceforge/plantuml/project/core/TaskGroup.java
@@ -56,6 +56,7 @@ public class TaskGroup extends AbstractTask implements Task {
this.parent = parent;
}
+ @Override
public Day getStart() {
Day min = null;
for (Task child : children)
@@ -68,6 +69,7 @@ public class TaskGroup extends AbstractTask implements Task {
throw new UnsupportedOperationException();
}
+ @Override
public Day getEnd() {
Day max = null;
for (Task child : children)
@@ -80,54 +82,67 @@ public class TaskGroup extends AbstractTask implements Task {
throw new UnsupportedOperationException();
}
+ @Override
public void setStart(Day start) {
throw new UnsupportedOperationException();
}
+ @Override
public void setEnd(Day end) {
throw new UnsupportedOperationException();
}
+ @Override
public void setColors(CenterBorderColor... colors) {
throw new UnsupportedOperationException();
}
+ @Override
public void addResource(Resource resource, int percentage) {
throw new UnsupportedOperationException();
}
+ @Override
public Load getLoad() {
throw new UnsupportedOperationException();
}
+ @Override
public void setLoad(Load load) {
throw new UnsupportedOperationException();
}
+ @Override
public void setDiamond(boolean diamond) {
throw new UnsupportedOperationException();
}
+ @Override
public boolean isDiamond() {
throw new UnsupportedOperationException();
}
+ @Override
public void setCompletion(int completion) {
throw new UnsupportedOperationException();
}
+ @Override
public void setUrl(Url url) {
throw new UnsupportedOperationException();
}
+ @Override
public void addPause(Day pause) {
throw new UnsupportedOperationException();
}
+ @Override
public void addPause(DayOfWeek pause) {
throw new UnsupportedOperationException();
}
+ @Override
public void setNote(Display note) {
}
@@ -139,4 +154,9 @@ public class TaskGroup extends AbstractTask implements Task {
return parent;
}
+ @Override
+ public boolean isAssignedTo(Resource res) {
+ return false;
+ }
+
}
diff --git a/src/net/sourceforge/plantuml/project/core/TaskImpl.java b/src/net/sourceforge/plantuml/project/core/TaskImpl.java
index 491a3dbc1..a3db7f866 100644
--- a/src/net/sourceforge/plantuml/project/core/TaskImpl.java
+++ b/src/net/sourceforge/plantuml/project/core/TaskImpl.java
@@ -66,7 +66,7 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
private final LoadPlanable defaultPlan;
private boolean diamond;
- private int completion = 100;
+ private int completion;
private Display note;
private Url url;
@@ -76,8 +76,9 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
this.url = url;
}
- public TaskImpl(StyleBuilder styleBuilder, TaskCode code, LoadPlanable plan, Day startingDay) {
+ public TaskImpl(StyleBuilder styleBuilder, TaskCode code, LoadPlanable plan, Day startingDay, int completion) {
super(styleBuilder, code);
+ this.completion = completion;
this.defaultPlan = plan;
this.solver = new SolverImpl(this);
if (startingDay == null)
@@ -88,6 +89,7 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
setLoad(Load.inWinks(1));
}
+ @Override
public int getLoadAt(Day instant) {
if (isPaused(instant))
return 0;
@@ -131,10 +133,12 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
return 0;
}
+ @Override
public void addPause(Day pause) {
this.pausedDay.add(pause);
}
+ @Override
public void addPause(DayOfWeek pause) {
this.pausedDayOfWeek.add(pause);
}
@@ -156,9 +160,29 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
}
return result;
}
+
+ @Override
+ public Day getLastDayIfAny() {
+ return TaskImpl.this.getLastDayIfAny();
+ }
};
}
+ @Override
+ public Day getLastDayIfAny() {
+ Day result = null;
+
+ for (Resource res : resources.keySet()) {
+ if (res.getLastDayIfAny() == null)
+ return null;
+
+ if (result == null || result.compareTo(res.getLastDayIfAny()) < 0)
+ result = res.getLastDayIfAny();
+ }
+
+ return result;
+ }
+
public String getPrettyDisplay() {
if (resources.size() > 0) {
final StringBuilder result = new StringBuilder(getCode().getSimpleDisplay());
@@ -190,6 +214,7 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
return "" + getStart() + " ---> " + getEnd() + " [" + getLoad() + "]";
}
+ @Override
public Day getStart() {
Day result = (Day) solver.getData(TaskAttribute.START);
if (diamond == false)
@@ -199,42 +224,52 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
return result;
}
+ @Override
public Day getEnd() {
return (Day) solver.getData(TaskAttribute.END);
}
+ @Override
public Load getLoad() {
return (Load) solver.getData(TaskAttribute.LOAD);
}
+ @Override
public void setLoad(Load load) {
solver.setData(TaskAttribute.LOAD, load);
}
+ @Override
public void setStart(Day start) {
solver.setData(TaskAttribute.START, start);
}
+ @Override
public void setEnd(Day end) {
solver.setData(TaskAttribute.END, end);
}
+ @Override
public void setColors(CenterBorderColor... colors) {
this.colors = colors;
}
+ @Override
public void addResource(Resource resource, int percentage) {
this.resources.put(resource, percentage);
}
+ @Override
public void setDiamond(boolean diamond) {
this.diamond = diamond;
}
+ @Override
public boolean isDiamond() {
return this.diamond;
}
+ @Override
public void setCompletion(int completion) {
this.completion = completion;
}
@@ -274,6 +309,7 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
}
+ @Override
public void setNote(Display note) {
this.note = note;
}
@@ -286,4 +322,9 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
return defaultPlan;
}
+ @Override
+ public boolean isAssignedTo(Resource res) {
+ return resources.containsKey(res);
+ }
+
}
diff --git a/src/net/sourceforge/plantuml/project/core/TaskSeparator.java b/src/net/sourceforge/plantuml/project/core/TaskSeparator.java
index fcf21d64a..68b30a326 100644
--- a/src/net/sourceforge/plantuml/project/core/TaskSeparator.java
+++ b/src/net/sourceforge/plantuml/project/core/TaskSeparator.java
@@ -52,22 +52,27 @@ public class TaskSeparator extends AbstractTask implements Task {
this.comment = comment;
}
+ @Override
public Day getStart() {
throw new UnsupportedOperationException();
}
+ @Override
public Day getEnd() {
throw new UnsupportedOperationException();
}
+ @Override
public void setStart(Day start) {
throw new UnsupportedOperationException();
}
+ @Override
public void setEnd(Day end) {
throw new UnsupportedOperationException();
}
+ @Override
public void setColors(CenterBorderColor... colors) {
throw new UnsupportedOperationException();
}
@@ -76,10 +81,12 @@ public class TaskSeparator extends AbstractTask implements Task {
return comment;
}
+ @Override
public void addResource(Resource resource, int percentage) {
throw new UnsupportedOperationException();
}
+ @Override
public Load getLoad() {
throw new UnsupportedOperationException();
}
@@ -88,31 +95,43 @@ public class TaskSeparator extends AbstractTask implements Task {
throw new UnsupportedOperationException();
}
+ @Override
public void setDiamond(boolean diamond) {
throw new UnsupportedOperationException();
}
+ @Override
public boolean isDiamond() {
throw new UnsupportedOperationException();
}
+ @Override
public void setCompletion(int completion) {
throw new UnsupportedOperationException();
}
+ @Override
public void setUrl(Url url) {
throw new UnsupportedOperationException();
}
+ @Override
public void addPause(Day pause) {
throw new UnsupportedOperationException();
}
+ @Override
public void addPause(DayOfWeek pause) {
throw new UnsupportedOperationException();
}
+ @Override
public void setNote(Display note) {
}
+ @Override
+ public boolean isAssignedTo(Resource res) {
+ return false;
+ }
+
}
diff --git a/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java b/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java
index 70c21a718..7d501e98e 100644
--- a/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java
+++ b/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java
@@ -49,11 +49,11 @@ import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.real.Real;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
-import net.sourceforge.plantuml.style.ISkinParam;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
+import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.utils.Direction;
@@ -85,8 +85,8 @@ public abstract class AbstractTaskDraw implements TaskDraw {
this.note = note;
}
- public AbstractTaskDraw(TimeScale timeScale, Real y, String prettyDisplay, Day start, ISkinParam skinParam,
- Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder) {
+ public AbstractTaskDraw(TimeScale timeScale, Real y, String prettyDisplay, Day start, Task task,
+ ToTaskDraw toTaskDraw, StyleBuilder styleBuilder) {
this.y = y;
this.styleBuilder = styleBuilder;
this.toTaskDraw = toTaskDraw;
@@ -96,7 +96,7 @@ public abstract class AbstractTaskDraw implements TaskDraw {
this.task = task;
}
- abstract StyleSignatureBasic getStyleSignature();
+ abstract StyleSignature getStyleSignature();
private StyleSignatureBasic getStyleSignatureUnstarted() {
return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, SName.task, SName.unstarted);
diff --git a/src/net/sourceforge/plantuml/project/draw/ResourceDraw.java b/src/net/sourceforge/plantuml/project/draw/ResourceDraw.java
index fb4f72f99..0215bceae 100644
--- a/src/net/sourceforge/plantuml/project/draw/ResourceDraw.java
+++ b/src/net/sourceforge/plantuml/project/draw/ResourceDraw.java
@@ -35,96 +35,13 @@
*/
package net.sourceforge.plantuml.project.draw;
-import net.sourceforge.plantuml.klimt.UTranslate;
-import net.sourceforge.plantuml.klimt.color.HColor;
-import net.sourceforge.plantuml.klimt.color.HColors;
-import net.sourceforge.plantuml.klimt.creole.Display;
-import net.sourceforge.plantuml.klimt.drawing.UGraphic;
-import net.sourceforge.plantuml.klimt.font.FontConfiguration;
-import net.sourceforge.plantuml.klimt.font.UFont;
-import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
-import net.sourceforge.plantuml.klimt.shape.TextBlock;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
import net.sourceforge.plantuml.klimt.shape.UDrawable;
-import net.sourceforge.plantuml.klimt.shape.ULine;
-import net.sourceforge.plantuml.klimt.sprite.SpriteContainerEmpty;
-import net.sourceforge.plantuml.project.GanttDiagram;
-import net.sourceforge.plantuml.project.core.Resource;
-import net.sourceforge.plantuml.project.time.Day;
-import net.sourceforge.plantuml.project.timescale.TimeScale;
-public class ResourceDraw implements UDrawable {
+public interface ResourceDraw extends UDrawable {
- private final Resource res;
- private final TimeScale timeScale;
- private final double y;
- private final Day min;
- private final Day max;
- private final GanttDiagram gantt;
+ public double getHeight(StringBounder stringBounder);
- public ResourceDraw(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Day min, Day max) {
- this.res = res;
- this.timeScale = timeScale;
- this.y = y;
- this.min = min;
- this.max = max;
- this.gantt = gantt;
- }
-
- public void drawU(UGraphic ug) {
- final TextBlock title = Display.getWithNewlines(res.getName()).create(getFontConfiguration(13),
- HorizontalAlignment.LEFT, new SpriteContainerEmpty());
- title.drawU(ug);
- final ULine line = ULine.hline(timeScale.getEndingPosition(max) - timeScale.getStartingPosition(min));
- ug.apply(HColors.BLACK).apply(UTranslate.dy(title.calculateDimension(ug.getStringBounder()).getHeight()))
- .draw(line);
-
- double startingPosition = -1;
- int totalLoad = 0;
- int totalLimit = 0;
- for (Day i = min; i.compareTo(max) <= 0; i = i.increment()) {
- final boolean isBreaking = timeScale.isBreaking(i);
- totalLoad += gantt.getLoadForResource(res, i);
- totalLimit += 100;
- if (isBreaking) {
- if (totalLoad > 0) {
- final boolean over = totalLoad > totalLimit;
- final FontConfiguration fontConfiguration = getFontConfiguration(9,
- over ? HColors.RED : HColors.BLACK);
- final TextBlock value = Display.getWithNewlines("" + totalLoad).create(fontConfiguration,
- HorizontalAlignment.LEFT, new SpriteContainerEmpty());
- if (startingPosition == -1)
- startingPosition = timeScale.getStartingPosition(i);
- final double endingPosition = timeScale.getEndingPosition(i);
- final double start = (startingPosition + endingPosition) / 2
- - value.calculateDimension(ug.getStringBounder()).getWidth() / 2;
- value.drawU(ug.apply(new UTranslate(start, 16)));
- }
- startingPosition = -1;
- totalLoad = 0;
- totalLimit = 0;
- } else {
- if (startingPosition == -1)
- startingPosition = timeScale.getStartingPosition(i);
- }
- }
-
- }
-
- private FontConfiguration getFontConfiguration(int size) {
- return getFontConfiguration(size, HColors.BLACK);
- }
-
- private FontConfiguration getFontConfiguration(int size, HColor color) {
- final UFont font = UFont.serif(size);
- return FontConfiguration.create(font, color, color, null);
- }
-
- public double getHeight() {
- return 16 * 2;
- }
-
- public final double getY() {
- return y;
- }
+ public double getY();
}
diff --git a/src/net/sourceforge/plantuml/project/draw/ResourceDrawBasic.java b/src/net/sourceforge/plantuml/project/draw/ResourceDrawBasic.java
new file mode 100644
index 000000000..5ba180cda
--- /dev/null
+++ b/src/net/sourceforge/plantuml/project/draw/ResourceDrawBasic.java
@@ -0,0 +1,132 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.project.draw;
+
+import net.sourceforge.plantuml.klimt.UTranslate;
+import net.sourceforge.plantuml.klimt.color.HColor;
+import net.sourceforge.plantuml.klimt.color.HColors;
+import net.sourceforge.plantuml.klimt.creole.Display;
+import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.FontConfiguration;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
+import net.sourceforge.plantuml.klimt.font.UFont;
+import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
+import net.sourceforge.plantuml.klimt.shape.TextBlock;
+import net.sourceforge.plantuml.klimt.shape.ULine;
+import net.sourceforge.plantuml.klimt.sprite.SpriteContainerEmpty;
+import net.sourceforge.plantuml.project.GanttDiagram;
+import net.sourceforge.plantuml.project.core.Resource;
+import net.sourceforge.plantuml.project.time.Day;
+import net.sourceforge.plantuml.project.timescale.TimeScale;
+
+public class ResourceDrawBasic implements ResourceDraw {
+
+ private final Resource res;
+ private final TimeScale timeScale;
+ private final double y;
+ private final Day min;
+ private final Day max;
+ private final GanttDiagram gantt;
+
+ public ResourceDrawBasic(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Day min, Day max) {
+ this.res = res;
+ this.timeScale = timeScale;
+ this.y = y;
+ this.min = min;
+ this.max = max;
+ this.gantt = gantt;
+ }
+
+ public void drawU(UGraphic ug) {
+ final TextBlock title = Display.getWithNewlines(res.getName()).create(getFontConfiguration(13),
+ HorizontalAlignment.LEFT, new SpriteContainerEmpty());
+ title.drawU(ug);
+ final ULine line = ULine.hline(timeScale.getEndingPosition(max) - timeScale.getStartingPosition(min));
+ ug.apply(HColors.BLACK).apply(UTranslate.dy(title.calculateDimension(ug.getStringBounder()).getHeight()))
+ .draw(line);
+
+ double startingPosition = -1;
+ int totalLoad = 0;
+ int totalLimit = 0;
+ for (Day i = min; i.compareTo(max) <= 0; i = i.increment()) {
+ final boolean isBreaking = timeScale.isBreaking(i);
+ totalLoad += gantt.getLoadForResource(res, i);
+ totalLimit += 100;
+ if (isBreaking) {
+ if (totalLoad > 0) {
+ final boolean over = totalLoad > totalLimit;
+ final FontConfiguration fontConfiguration = getFontConfiguration(9,
+ over ? HColors.RED : HColors.BLACK);
+ final TextBlock value = Display.getWithNewlines("" + totalLoad).create(fontConfiguration,
+ HorizontalAlignment.LEFT, new SpriteContainerEmpty());
+ if (startingPosition == -1)
+ startingPosition = timeScale.getStartingPosition(i);
+ final double endingPosition = timeScale.getEndingPosition(i);
+ final double start = (startingPosition + endingPosition) / 2
+ - value.calculateDimension(ug.getStringBounder()).getWidth() / 2;
+ value.drawU(ug.apply(new UTranslate(start, 16)));
+ }
+ startingPosition = -1;
+ totalLoad = 0;
+ totalLimit = 0;
+ } else {
+ if (startingPosition == -1)
+ startingPosition = timeScale.getStartingPosition(i);
+ }
+ }
+
+ }
+
+ private FontConfiguration getFontConfiguration(int size) {
+ return getFontConfiguration(size, HColors.BLACK);
+ }
+
+ private FontConfiguration getFontConfiguration(int size, HColor color) {
+ final UFont font = UFont.serif(size);
+ return FontConfiguration.create(font, color, color, null);
+ }
+
+ @Override
+ public double getHeight(StringBounder stringBounder) {
+ return 16 * 2;
+ }
+
+ @Override
+ public final double getY() {
+ return y;
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/project/draw/ResourceDrawVersion2.java b/src/net/sourceforge/plantuml/project/draw/ResourceDrawVersion2.java
new file mode 100644
index 000000000..522fe9e91
--- /dev/null
+++ b/src/net/sourceforge/plantuml/project/draw/ResourceDrawVersion2.java
@@ -0,0 +1,138 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.project.draw;
+
+import net.sourceforge.plantuml.klimt.UShape;
+import net.sourceforge.plantuml.klimt.UTranslate;
+import net.sourceforge.plantuml.klimt.color.HColor;
+import net.sourceforge.plantuml.klimt.color.HColors;
+import net.sourceforge.plantuml.klimt.creole.Display;
+import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.FontConfiguration;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
+import net.sourceforge.plantuml.klimt.font.UFont;
+import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
+import net.sourceforge.plantuml.klimt.shape.TextBlock;
+import net.sourceforge.plantuml.klimt.shape.ULine;
+import net.sourceforge.plantuml.klimt.shape.URectangle;
+import net.sourceforge.plantuml.klimt.sprite.SpriteContainerEmpty;
+import net.sourceforge.plantuml.project.GanttDiagram;
+import net.sourceforge.plantuml.project.LabelPosition;
+import net.sourceforge.plantuml.project.LabelStrategy;
+import net.sourceforge.plantuml.project.core.Resource;
+import net.sourceforge.plantuml.project.time.Day;
+import net.sourceforge.plantuml.project.timescale.TimeScale;
+
+public class ResourceDrawVersion2 implements ResourceDraw {
+
+ private final Resource res;
+ private final TimeScale timeScale;
+ private final double y;
+ private final Day min;
+ private final Day max;
+ private final GanttDiagram gantt;
+
+ public ResourceDrawVersion2(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Day min, Day max) {
+ this.res = res;
+ this.timeScale = timeScale;
+ this.y = y;
+ this.min = min;
+ this.max = max;
+ this.gantt = gantt;
+ }
+
+ public void drawU(UGraphic ug) {
+ final StringBounder stringBounder = ug.getStringBounder();
+
+ double ypos = 16;
+ final double tmpHeight = getHeight(stringBounder) - ypos;
+ for (Day wink = gantt.getStartingDate(); wink.compareTo(gantt.getEndingDate()) <= 0; wink = wink.increment()) {
+ final double start = timeScale.getStartingPosition(wink);
+ final double end = timeScale.getEndingPosition(wink);
+ final UShape rect = URectangle.build(end - start, tmpHeight);
+ if (res.isClosedAt(wink))
+ ug.apply(HColors.LIGHT_GRAY.bg()).apply(new UTranslate(start, ypos)).draw(rect);
+
+ }
+
+ final TextBlock title = Display.getWithNewlines(res.getName()).create(getFontConfiguration(13),
+ HorizontalAlignment.LEFT, new SpriteContainerEmpty());
+ title.drawU(ug);
+ final ULine line = ULine.hline(timeScale.getEndingPosition(max) - timeScale.getStartingPosition(min));
+ ug.apply(HColors.BLACK).apply(UTranslate.dy(title.calculateDimension(ug.getStringBounder()).getHeight()))
+ .draw(line);
+
+ final LabelStrategy labelStrategy = new LabelStrategy(LabelPosition.LEGACY, HorizontalAlignment.LEFT);
+
+ for (TaskDrawRegular draw : gantt.getAllTasksForResource(res)) {
+ draw.drawShape(ug.apply(UTranslate.dy(ypos + getTopMarginBetweenTask())));
+ draw.drawTitle(ug.apply(UTranslate.dy(ypos + getTopMarginBetweenTask())), labelStrategy, 10, 100);
+ ypos += draw.getShapeHeight(stringBounder) + getMarginBetweenTask();
+ }
+ }
+
+ @Override
+ public double getHeight(StringBounder stringBounder) {
+ double ypos = 16;
+ for (TaskDrawRegular draw : gantt.getAllTasksForResource(res))
+ ypos += draw.getShapeHeight(stringBounder) + getMarginBetweenTask();
+
+ return ypos + 8;
+ }
+
+ private double getTopMarginBetweenTask() {
+ return 2;
+ }
+
+ private double getMarginBetweenTask() {
+ return 4;
+ }
+
+ private FontConfiguration getFontConfiguration(int size) {
+ return getFontConfiguration(size, HColors.BLACK);
+ }
+
+ private FontConfiguration getFontConfiguration(int size, HColor color) {
+ final UFont font = UFont.serif(size);
+ return FontConfiguration.create(font, color, color, null);
+ }
+
+ @Override
+ public final double getY() {
+ return y;
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java
index 30e3d8031..260579d10 100644
--- a/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java
+++ b/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java
@@ -54,21 +54,21 @@ import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.real.Real;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
-import net.sourceforge.plantuml.style.ISkinParam;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
+import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
public class TaskDrawDiamond extends AbstractTaskDraw {
- public TaskDrawDiamond(TimeScale timeScale, Real y, String prettyDisplay, Day start, ISkinParam skinParam,
- Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder) {
- super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder);
+ public TaskDrawDiamond(TimeScale timeScale, Real y, String prettyDisplay, Day start, Task task,
+ ToTaskDraw toTaskDraw, StyleBuilder styleBuilder) {
+ super(timeScale, y, prettyDisplay, start, task, toTaskDraw, styleBuilder);
}
@Override
- StyleSignatureBasic getStyleSignature() {
+ StyleSignature getStyleSignature() {
return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, SName.milestone);
}
@@ -134,29 +134,39 @@ public class TaskDrawDiamond extends AbstractTaskDraw {
@Override
public void drawU(UGraphic ug) {
+ if (url != null)
+ ug.startUrl(url);
+
+ final String displayString = getTask().getDisplayString();
+
final Style style = getStyle();
final ClockwiseTopRightBottomLeft margin = style.getMargin();
ug = ug.apply(UTranslate.dy(margin.getTop()));
final double x1 = timeScale.getStartingPosition(start);
- final double x2 = timeScale.getEndingPosition(start);
- final double width = getDiamondHeight();
- final double delta = x2 - x1 - width;
- if (url != null)
- ug.startUrl(url);
-
- drawShape(applyColors(ug).apply(UTranslate.dx(x1 + delta / 2)));
+ ug = ug.apply(UTranslate.dx(x1));
+ if (displayString == null) {
+ final double x2 = timeScale.getEndingPosition(start);
+ final double width = getDiamondHeight();
+ final double delta = x2 - x1 - width;
+ ug = ug.apply(UTranslate.dx(delta / 2));
+ drawShape(applyColors(ug));
+ } else {
+ final TextBlock draw = Display.getWithNewlines(displayString).create(getFontConfiguration(),
+ HorizontalAlignment.LEFT, new SpriteContainerEmpty());
+ draw.drawU(ug);
+ }
if (url != null)
ug.closeUrl();
}
private UGraphic applyColors(UGraphic ug) {
final CenterBorderColor col = this.getColors();
- if (col != null && col.isOk()) {
+ if (col != null && col.isOk())
return col.apply(ug);
- }
+
return ug.apply(getLineColor()).apply(getBackgroundColor().bg());
}
diff --git a/src/net/sourceforge/plantuml/project/draw/TaskDrawGroup.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawGroup.java
index 88ff50d60..346182887 100644
--- a/src/net/sourceforge/plantuml/project/draw/TaskDrawGroup.java
+++ b/src/net/sourceforge/plantuml/project/draw/TaskDrawGroup.java
@@ -54,22 +54,19 @@ import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.real.Real;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
-import net.sourceforge.plantuml.style.ISkinParam;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
+import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
public class TaskDrawGroup extends AbstractTaskDraw {
private final Day end;
- private final ISkinParam skinParam;
-
- public TaskDrawGroup(TimeScale timeScale, Real y, String prettyDisplay, Day start, Day end, ISkinParam skinParam,
- Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder) {
- super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder);
- this.skinParam = skinParam;
+ public TaskDrawGroup(TimeScale timeScale, Real y, String prettyDisplay, Day start, Day end, Task task,
+ ToTaskDraw toTaskDraw, StyleBuilder styleBuilder) {
+ super(timeScale, y, prettyDisplay, start, task, toTaskDraw, styleBuilder);
this.end = end;
}
@@ -122,7 +119,7 @@ public class TaskDrawGroup extends AbstractTaskDraw {
}
@Override
- StyleSignatureBasic getStyleSignature() {
+ StyleSignature getStyleSignature() {
return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, SName.task);
}
diff --git a/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java
index ebe606c9a..7d8d9a1ae 100644
--- a/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java
+++ b/src/net/sourceforge/plantuml/project/draw/TaskDrawRegular.java
@@ -65,11 +65,12 @@ import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.real.Real;
import net.sourceforge.plantuml.sequencediagram.graphic.Segment;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
-import net.sourceforge.plantuml.style.ISkinParam;
+import net.sourceforge.plantuml.style.ISkinSimple;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
+import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.svek.image.Opale;
@@ -80,13 +81,13 @@ public class TaskDrawRegular extends AbstractTaskDraw {
private final boolean oddEnd;
private final Collection paused;
private final Collection constraints;
- private final ISkinParam skinParam;
+ private final ISkinSimple skinSimple;
public TaskDrawRegular(TimeScale timeScale, Real y, String prettyDisplay, Day start, Day end, boolean oddStart,
- boolean oddEnd, ISkinParam skinParam, Task task, ToTaskDraw toTaskDraw,
+ boolean oddEnd, ISkinSimple skinSimple, Task task, ToTaskDraw toTaskDraw,
Collection constraints, StyleBuilder styleBuilder) {
- super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder);
- this.skinParam = skinParam;
+ super(timeScale, y, prettyDisplay, start, task, toTaskDraw, styleBuilder);
+ this.skinSimple = skinSimple;
this.constraints = constraints;
this.end = end;
this.oddStart = oddStart;
@@ -101,7 +102,7 @@ public class TaskDrawRegular extends AbstractTaskDraw {
}
@Override
- protected double getShapeHeight(StringBounder stringBounder) {
+ public double getShapeHeight(StringBounder stringBounder) {
final Style style = getStyle();
final ClockwiseTopRightBottomLeft padding = style.getPadding();
return padding.getTop() + getTitle().calculateDimension(stringBounder).getHeight() + padding.getBottom();
@@ -162,15 +163,15 @@ public class TaskDrawRegular extends AbstractTaskDraw {
}
@Override
- StyleSignatureBasic getStyleSignature() {
- return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, SName.task);
+ StyleSignature getStyleSignature() {
+ return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, SName.task)
+ .withTOBECHANGED(getTask().getStereotype());
}
public void drawU(UGraphic ug) {
final double startPos = timeScale.getStartingPosition(start);
drawNote(ug.apply((new UTranslate(startPos, getYNotePosition(ug.getStringBounder())))));
- ug = applyColors(ug);
drawShape(ug);
}
@@ -203,7 +204,7 @@ public class TaskDrawRegular extends AbstractTaskDraw {
final FontConfiguration fc = style.getFontConfiguration(getColorSet());
final HorizontalAlignment horizontalAlignment = style.value(PName.HorizontalAlignment).asHorizontalAlignment();
- final Sheet sheet = skinParam.sheet(fc, horizontalAlignment, CreoleMode.FULL).createSheet(note);
+ final Sheet sheet = skinSimple.sheet(fc, horizontalAlignment, CreoleMode.FULL).createSheet(note);
final double padding = style.value(PName.Padding).asDouble();
final SheetBlock1 sheet1 = new SheetBlock1(sheet, LineBreakStrategy.NONE, padding);
@@ -256,7 +257,8 @@ public class TaskDrawRegular extends AbstractTaskDraw {
return endPos;
}
- private void drawShape(UGraphic ug) {
+ public void drawShape(UGraphic ug) {
+ ug = applyColors(ug);
final Style style = getStyleSignature().getMergedStyle(getStyleBuilder());
final ClockwiseTopRightBottomLeft margin = style.getMargin();
diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeader.java b/src/net/sourceforge/plantuml/project/draw/TimeHeader.java
index ab995c7e4..9d171188e 100644
--- a/src/net/sourceforge/plantuml/project/draw/TimeHeader.java
+++ b/src/net/sourceforge/plantuml/project/draw/TimeHeader.java
@@ -35,113 +35,102 @@
*/
package net.sourceforge.plantuml.project.draw;
-import java.util.Objects;
-
-import net.sourceforge.plantuml.klimt.UStroke;
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.color.HColor;
-import net.sourceforge.plantuml.klimt.color.HColorSet;
import net.sourceforge.plantuml.klimt.color.HColors;
import net.sourceforge.plantuml.klimt.creole.Display;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
import net.sourceforge.plantuml.klimt.font.FontConfiguration;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
import net.sourceforge.plantuml.klimt.font.UFont;
import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.klimt.shape.ULine;
import net.sourceforge.plantuml.klimt.shape.URectangle;
import net.sourceforge.plantuml.klimt.sprite.SpriteContainerEmpty;
+import net.sourceforge.plantuml.project.TimeHeaderParameters;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.style.PName;
-import net.sourceforge.plantuml.style.Style;
+import net.sourceforge.plantuml.style.SName;
public abstract class TimeHeader {
- // ::remove folder when __HAXE__
-
- protected final double Y_POS_ROW16() {
- return 16;
- }
-
- protected final double Y_POS_ROW28() {
- return 28;
- }
+ // ::remove folder when __HAXE__
private final TimeScale timeScale;
- private final Style closedStyle;
- private final Style timelineStyle;
- private final HColorSet colorSet;
+ protected final TimeHeaderParameters thParam;
- protected final Day min;
- protected final Day max;
-
- public TimeHeader(Style timelineStyle, Style closedStyle, Day min, Day max, TimeScale timeScale,
- HColorSet colorSet) {
+ public TimeHeader(TimeHeaderParameters thParam, TimeScale timeScale) {
+ this.thParam = thParam;
this.timeScale = timeScale;
- this.min = min;
- this.max = max;
- this.closedStyle = Objects.requireNonNull(closedStyle);
- this.timelineStyle = Objects.requireNonNull(timelineStyle);
- this.colorSet = colorSet;
+ }
+
+ protected final boolean isBold2(Day wink) {
+ return thParam.getVerticalSeparatorBefore().contains(wink);
+ }
+
+ protected final Day getMin() {
+ return thParam.getMin();
+ }
+
+ protected final Day getMax() {
+ return thParam.getMax();
}
protected final HColor closedBackgroundColor() {
- return closedStyle.value(PName.BackGroundColor).asColor(colorSet);
+ return thParam.getClosedStyle().value(PName.BackGroundColor).asColor(thParam.getColorSet());
}
protected final HColor closedFontColor() {
- return closedStyle.value(PName.FontColor).asColor(colorSet);
+ return thParam.getClosedStyle().value(PName.FontColor).asColor(thParam.getColorSet());
}
protected final HColor openFontColor() {
- return timelineStyle.value(PName.FontColor).asColor(colorSet);
+ return thParam.getTimelineStyle().value(PName.FontColor).asColor(thParam.getColorSet());
}
- protected final HColor getBarColor() {
- return timelineStyle.value(PName.LineColor).asColor(colorSet);
+ protected final HColor getLineColor() {
+ return thParam.getTimelineStyle().value(PName.LineColor).asColor(thParam.getColorSet());
}
- public abstract double getTimeHeaderHeight();
+ public abstract double getTimeHeaderHeight(StringBounder stringBounder);
- public abstract double getTimeFooterHeight();
+ public abstract double getTimeFooterHeight(StringBounder stringBounder);
+
+ public abstract double getFullHeaderHeight(StringBounder stringBounder);
public abstract void drawTimeHeader(UGraphic ug, double totalHeightWithoutFooter);
public abstract void drawTimeFooter(UGraphic ug);
- public abstract double getFullHeaderHeight();
-
- protected final void drawHline(UGraphic ug, double y) {
- final double xmin = getTimeScale().getStartingPosition(min);
- final double xmax = getTimeScale().getEndingPosition(max);
- final ULine hline = ULine.hline(xmax - xmin);
- ug.apply(getBarColor()).apply(UTranslate.dy(y)).draw(hline);
+ public final TimeScale getTimeScale() {
+ return timeScale;
}
- protected final void drawVbar(UGraphic ug, double x, double y1, double y2, boolean bold) {
+ protected final void drawHline(UGraphic ug, double y) {
+ final double xmin = getTimeScale().getStartingPosition(thParam.getMin());
+ final double xmax = getTimeScale().getEndingPosition(thParam.getMax());
+ final ULine hline = ULine.hline(xmax - xmin);
+ ug.apply(getLineColor()).apply(UTranslate.dy(y)).draw(hline);
+ }
+
+ protected final void drawVline(UGraphic ug, double x, double y1, double y2) {
final ULine vbar = ULine.vline(y2 - y1);
- if (bold)
- ug = goBold(ug);
- else
- ug = ug.apply(getBarColor());
ug.apply(new UTranslate(x, y1)).draw(vbar);
}
- final protected FontConfiguration getFontConfiguration(int size, boolean bold, HColor color) {
- UFont font = UFont.serif(size);
+ final protected FontConfiguration getFontConfiguration(UFont font, boolean bold, HColor color) {
if (bold)
font = font.bold();
return FontConfiguration.create(font, color, color, null);
}
- public final TimeScale getTimeScale() {
- return timeScale;
- }
-
- protected final TextBlock getTextBlock(String text, int size, boolean bold, HColor color) {
- return Display.getWithNewlines(text).create(getFontConfiguration(size, bold, color), HorizontalAlignment.LEFT,
+ protected final TextBlock getTextBlock(SName param, String text, boolean bold, HColor color) {
+ final UFont font = thParam.getStyle(SName.timeline, param).getUFont();
+ final FontConfiguration fontConfiguration = getFontConfiguration(font, bold, color);
+ return Display.getWithNewlines(text).create(fontConfiguration, HorizontalAlignment.LEFT,
new SpriteContainerEmpty());
}
@@ -171,12 +160,16 @@ public abstract class TimeHeader {
return;
ug = ug.apply(HColors.none());
- ug = ug.apply(new UTranslate(x1, getFullHeaderHeight()));
+ ug = ug.apply(new UTranslate(x1, getFullHeaderHeight(ug.getStringBounder())));
ug.draw(URectangle.build(x2 - x1, height));
}
- protected final UGraphic goBold(UGraphic ug) {
- return ug.apply(HColors.BLACK).apply(UStroke.withThickness(2));
+ protected void printVerticalSeparators(UGraphic ug, double totalHeightWithoutFooter) {
+ ug = thParam.forVerticalSeparator(ug);
+ for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment())
+ if (isBold2(wink))
+ drawVline(ug, getTimeScale().getStartingPosition(wink),
+ getFullHeaderHeight(ug.getStringBounder()), totalHeightWithoutFooter);
}
}
diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderCalendar.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderCalendar.java
index 3d8274958..fb85e6503 100644
--- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderCalendar.java
+++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderCalendar.java
@@ -45,16 +45,8 @@ import net.sourceforge.plantuml.project.timescale.TimeScale;
public abstract class TimeHeaderCalendar extends TimeHeader {
- private final TimeHeaderParameters thParam;
-
public TimeHeaderCalendar(TimeHeaderParameters thParam, TimeScale timeScale) {
- super(thParam.getTimelineStyle(), thParam.getClosedStyle(), thParam.getMin(), thParam.getMax(), timeScale,
- thParam.getColorSet());
- this.thParam = thParam;
- }
-
- protected final boolean isBold(Day wink) {
- return thParam.getVerticalSeparatorBefore().contains(wink);
+ super(thParam, timeScale);
}
protected final Locale locale() {
@@ -64,7 +56,7 @@ public abstract class TimeHeaderCalendar extends TimeHeader {
protected final int getLoadAt(Day instant) {
return thParam.getLoadPlanable().getLoadAt(instant);
}
-
+
// Duplicate in TimeHeaderSimple
class Pending {
final double x1;
@@ -84,10 +76,10 @@ public abstract class TimeHeaderCalendar extends TimeHeader {
protected final void drawTextsBackground(UGraphic ug, double totalHeightWithoutFooter) {
- final double height = totalHeightWithoutFooter - getFullHeaderHeight();
+ final double height = totalHeightWithoutFooter - getFullHeaderHeight(ug.getStringBounder());
Pending pending = null;
- for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink);
final double x2 = getTimeScale().getEndingPosition(wink);
HColor back = thParam.getColor(wink);
diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java
index 8fd5bf794..039180af5 100644
--- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java
+++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java
@@ -40,74 +40,122 @@ import java.util.Map;
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.color.HColor;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.project.TimeHeaderParameters;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleDaily;
+import net.sourceforge.plantuml.style.PName;
+import net.sourceforge.plantuml.style.SName;
public class TimeHeaderDaily extends TimeHeaderCalendar {
- public double getTimeHeaderHeight() {
- return Y_POS_ROW28() + 13;
+ private double getH1(StringBounder stringBounder) {
+ final double h = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble() + 2;
+ return h;
}
- public double getTimeFooterHeight() {
- // return 0;
- return 24 + 14;
+ private double getH2(StringBounder stringBounder) {
+ final double h = thParam.getStyle(SName.timeline, SName.day).value(PName.FontSize).asDouble() + 2;
+ return getH1(stringBounder) + h;
+ }
+
+ private double getH3(StringBounder stringBounder) {
+ final double h = thParam.getStyle(SName.timeline, SName.day).value(PName.FontSize).asDouble() + 3;
+ return getH2(stringBounder) + h;
+ }
+
+ @Override
+ public double getTimeHeaderHeight(StringBounder stringBounder) {
+ return getH3(stringBounder);
+ }
+
+ @Override
+ public double getTimeFooterHeight(StringBounder stringBounder) {
+ final double h1 = thParam.getStyle(SName.timeline, SName.day).value(PName.FontSize).asDouble();
+ final double h2 = thParam.getStyle(SName.timeline, SName.day).value(PName.FontSize).asDouble();
+ final double h3 = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble();
+ return h1 + h2 + h3 + 8;
+ }
+
+ private double getHeaderNameDayHeight() {
+ if (nameDays.size() > 0) {
+ final double h = thParam.getStyle(SName.timeline, SName.day).value(PName.FontSize).asDouble() + 6;
+ return h;
+ }
+
+ return 0;
+ }
+
+ @Override
+ public double getFullHeaderHeight(StringBounder stringBounder) {
+ return getTimeHeaderHeight(stringBounder) + getHeaderNameDayHeight();
}
private final Map nameDays;
- public TimeHeaderDaily(TimeHeaderParameters thParam, Map nameDays, Day printStart, Day printEnd) {
- super(thParam, new TimeScaleDaily(thParam.getStartingDay(), thParam.getScale(), printStart));
+ public TimeHeaderDaily(StringBounder stringBounder, TimeHeaderParameters thParam, Map nameDays,
+ Day printStart) {
+ super(thParam, new TimeScaleDaily(thParam.getCellWidth(stringBounder), thParam.getStartingDay(),
+ thParam.getScale(), printStart));
this.nameDays = nameDays;
}
@Override
public void drawTimeHeader(final UGraphic ug, double totalHeightWithoutFooter) {
drawTextsBackground(ug, totalHeightWithoutFooter);
- drawTextsDayOfWeek(ug.apply(UTranslate.dy(Y_POS_ROW16())));
- drawTextDayOfMonth(ug.apply(UTranslate.dy(Y_POS_ROW28())));
+ drawTextsDayOfWeek(ug.apply(UTranslate.dy(getH1(ug.getStringBounder()))));
+ drawTextDayOfMonth(ug.apply(UTranslate.dy(getH2(ug.getStringBounder()))));
drawMonths(ug);
- printSmallVbars(ug, totalHeightWithoutFooter);
+ printVerticalSeparators(ug, totalHeightWithoutFooter);
printNamedDays(ug);
- drawHline(ug, getFullHeaderHeight());
+ drawHline(ug, getFullHeaderHeight(ug.getStringBounder()));
drawHline(ug, totalHeightWithoutFooter);
}
- private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) {
- for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment())
- drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter,
- isBold(wink));
+ @Override
+ protected void printVerticalSeparators(final UGraphic ug, double totalHeightWithoutFooter) {
+ final UGraphic ugVerticalSeparator = thParam.forVerticalSeparator(ug);
+ final UGraphic ugLineColor = ug.apply(getLineColor());
+ for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment())
+ if (isBold2(wink))
+ drawVline(ugVerticalSeparator, getTimeScale().getStartingPosition(wink),
+ getFullHeaderHeight(ug.getStringBounder()), totalHeightWithoutFooter);
+ else
+ drawVline(ugLineColor, getTimeScale().getStartingPosition(wink),
+ getFullHeaderHeight(ug.getStringBounder()), totalHeightWithoutFooter);
- drawVbar(ug, getTimeScale().getEndingPosition(max), getFullHeaderHeight(), totalHeightWithoutFooter, false);
+ drawVline(ugLineColor, getTimeScale().getEndingPosition(getMax()), getFullHeaderHeight(ug.getStringBounder()),
+ totalHeightWithoutFooter);
}
@Override
public void drawTimeFooter(UGraphic ug) {
- drawTextDayOfMonth(ug.apply(UTranslate.dy(12)));
+ final double h = thParam.getStyle(SName.timeline, SName.day).value(PName.FontSize).asDouble() + 2;
drawTextsDayOfWeek(ug);
- drawMonths(ug.apply(UTranslate.dy(24)));
+ drawTextDayOfMonth(ug.apply(UTranslate.dy(h + 2)));
+ drawMonths(ug.apply(UTranslate.dy(2 * h + 3)));
}
private void drawTextsDayOfWeek(UGraphic ug) {
- for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink);
final double x2 = getTimeScale().getEndingPosition(wink);
final HColor textColor = getTextBackColor(wink);
- printCentered(ug, getTextBlock(wink.getDayOfWeek().shortName(locale()), 10, false, textColor), x1, x2);
+ printCentered(ug, getTextBlock(SName.day, wink.getDayOfWeek().shortName(locale()), false, textColor), x1,
+ x2);
}
}
private void drawTextDayOfMonth(UGraphic ug) {
- for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink);
final double x2 = getTimeScale().getEndingPosition(wink);
final HColor textColor = getTextBackColor(wink);
- printCentered(ug, getTextBlock("" + wink.getDayOfMonth(), 10, false, textColor), x1, x2);
+ printCentered(ug, getTextBlock(SName.day, "" + wink.getDayOfMonth(), false, textColor), x1, x2);
}
}
@@ -121,7 +169,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
private void drawMonths(final UGraphic ug) {
MonthYear last = null;
double lastChangeMonth = -1;
- for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink);
if (wink.monthYear().equals(last) == false) {
if (last != null)
@@ -131,48 +179,38 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
last = wink.monthYear();
}
}
- final double x1 = getTimeScale().getStartingPosition(max.increment());
+ final double x1 = getTimeScale().getStartingPosition(getMax().increment());
if (x1 > lastChangeMonth)
printMonth(ug, last, lastChangeMonth, x1);
}
private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) {
- final TextBlock tiny = getTextBlock(monthYear.shortName(locale()), 12, true, openFontColor());
- final TextBlock small = getTextBlock(monthYear.longName(locale()), 12, true, openFontColor());
- final TextBlock big = getTextBlock(monthYear.longNameYYYY(locale()), 12, true, openFontColor());
+ final TextBlock tiny = getTextBlock(SName.month, monthYear.shortName(locale()), true, openFontColor());
+ final TextBlock small = getTextBlock(SName.month, monthYear.longName(locale()), true, openFontColor());
+ final TextBlock big = getTextBlock(SName.month, monthYear.longNameYYYY(locale()), true, openFontColor());
printCentered(ug, false, start, end, tiny, small, big);
}
private void printNamedDays(final UGraphic ug) {
if (nameDays.size() > 0) {
String last = null;
- for (Day wink = min; wink.compareTo(max.increment()) <= 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax().increment()) <= 0; wink = wink.increment()) {
final String name = nameDays.get(wink);
if (name != null && name.equals(last) == false) {
final double x1 = getTimeScale().getStartingPosition(wink);
final double x2 = getTimeScale().getEndingPosition(wink);
- final TextBlock label = getTextBlock(name, 12, false, openFontColor());
+ final TextBlock label = getTextBlock(SName.month, name, false, openFontColor());
final double h = label.calculateDimension(ug.getStringBounder()).getHeight();
- double y1 = getTimeHeaderHeight();
- double y2 = getFullHeaderHeight();
- label.drawU(ug.apply(new UTranslate(x1, Y_POS_ROW28() + 11)));
+ double y1 = getTimeHeaderHeight(ug.getStringBounder());
+ double y2 = getFullHeaderHeight(ug.getStringBounder());
+
+ final double position = getH3(ug.getStringBounder());
+ label.drawU(ug.apply(new UTranslate(x1, position)));
}
last = name;
}
}
}
- @Override
- public double getFullHeaderHeight() {
- return getTimeHeaderHeight() + getHeaderNameDayHeight();
- }
-
- private double getHeaderNameDayHeight() {
- if (nameDays.size() > 0)
- return 16;
-
- return 0;
- }
-
}
diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java
index d8d6e2d67..f784519cd 100644
--- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java
+++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java
@@ -37,104 +37,120 @@ package net.sourceforge.plantuml.project.draw;
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.project.TimeHeaderParameters;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
+import net.sourceforge.plantuml.style.PName;
+import net.sourceforge.plantuml.style.SName;
public class TimeHeaderMonthly extends TimeHeaderCalendar {
- public double getTimeHeaderHeight() {
- return 16 + 13;
+ @Override
+ public double getTimeHeaderHeight(StringBounder stringBounder) {
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
+ final double h2 = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble();
+ return h1 + h2 + 5;
}
- public double getTimeFooterHeight() {
- return 16 + 13 - 1;
+ @Override
+ public double getTimeFooterHeight(StringBounder stringBounder) {
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
+ final double h2 = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble();
+ return h1 + h2 + 5;
}
- public TimeHeaderMonthly(TimeHeaderParameters thParam) {
- super(thParam, new TimeScaleCompressed(thParam.getStartingDay(), thParam.getScale()));
+ @Override
+ public double getFullHeaderHeight(StringBounder stringBounder) {
+ return getTimeHeaderHeight(stringBounder);
+ }
+
+ public TimeHeaderMonthly(StringBounder stringBounder, TimeHeaderParameters thParam, Day printStart) {
+ super(thParam, new TimeScaleCompressed(thParam.getCellWidth(stringBounder), thParam.getStartingDay(),
+ thParam.getScale(), printStart));
}
@Override
public void drawTimeHeader(final UGraphic ug, double totalHeightWithoutFooter) {
drawTextsBackground(ug, totalHeightWithoutFooter);
drawYears(ug);
- drawMonths(ug.apply(UTranslate.dy(16)));
- printSmallVbars(ug, totalHeightWithoutFooter);
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
+ final double h2 = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble();
+ drawMonths(ug.apply(UTranslate.dy(h1 + 2)));
+ printVerticalSeparators(ug, totalHeightWithoutFooter);
drawHline(ug, 0);
- drawHline(ug, 16);
- drawHline(ug, getFullHeaderHeight());
- }
-
- private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) {
- for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment())
- if (isBold(wink))
- drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter,
- isBold(wink));
+ drawHline(ug, h1 + 2);
+ drawHline(ug, h1 + 2 + h2 + 2);
+// drawHline(ug, getFullHeaderHeight(ug.getStringBounder()));
}
@Override
public void drawTimeFooter(UGraphic ug) {
- ug = ug.apply(UTranslate.dy(3));
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
+ final double h2 = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble();
+ // ug = ug.apply(UTranslate.dy(3));
drawMonths(ug);
- drawYears(ug.apply(UTranslate.dy(13)));
+ drawYears(ug.apply(UTranslate.dy(h2 + 2)));
drawHline(ug, 0);
- drawHline(ug, 13);
- drawHline(ug, getTimeFooterHeight());
+ drawHline(ug, h2 + 2);
+ drawHline(ug, h1 + 2 + h2 + 2);
+// drawHline(ug, getTimeFooterHeight(ug.getStringBounder()));
}
private void drawYears(final UGraphic ug) {
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
MonthYear last = null;
double lastChange = -1;
- for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink);
if (last == null || wink.monthYear().year() != last.year()) {
- drawVbar(ug, x1, 0, 15, false);
- if (last != null) {
+ drawVline(ug.apply(getLineColor()), x1, 0, h1 + 2);
+ if (last != null)
printYear(ug, last, lastChange, x1);
- }
+
lastChange = x1;
last = wink.monthYear();
}
}
- final double x1 = getTimeScale().getStartingPosition(max.increment());
- if (x1 > lastChange) {
+ final double x1 = getTimeScale().getStartingPosition(getMax().increment());
+ if (x1 > lastChange)
printYear(ug, last, lastChange, x1);
- }
- drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 15, false);
+
+ drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), 0, h1 + 2);
}
private void drawMonths(UGraphic ug) {
+ final double h2 = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble();
MonthYear last = null;
double lastChange = -1;
- for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink);
if (wink.monthYear().equals(last) == false) {
- drawVbar(ug, x1, 0, 12, false);
- if (last != null) {
+ drawVline(ug.apply(getLineColor()), x1, 0, h2 + 2);
+ if (last != null)
printMonth(ug, last, lastChange, x1);
- }
+
lastChange = x1;
last = wink.monthYear();
}
}
- final double x1 = getTimeScale().getStartingPosition(max.increment());
- if (x1 > lastChange) {
+ final double x1 = getTimeScale().getStartingPosition(getMax().increment());
+ if (x1 > lastChange)
printMonth(ug, last, lastChange, x1);
- }
- drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12, false);
+
+ drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), 0, h2 + 2);
}
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {
- final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, openFontColor());
+ final TextBlock small = getTextBlock(SName.month, "" + monthYear.year(), true, openFontColor());
printCentered(ug, false, start, end, small);
}
private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) {
- final TextBlock small = getTextBlock(monthYear.shortName(locale()), 10, false, openFontColor());
- final TextBlock big = getTextBlock(monthYear.longName(locale()), 10, false, openFontColor());
+ final TextBlock small = getTextBlock(SName.day, monthYear.shortName(locale()), false, openFontColor());
+ final TextBlock big = getTextBlock(SName.day, monthYear.longName(locale()), false, openFontColor());
printCentered(ug, false, start, end, small, big);
}
@@ -142,9 +158,4 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar {
text.drawU(ug.apply(UTranslate.dx(start)));
}
- @Override
- public double getFullHeaderHeight() {
- return getTimeHeaderHeight();
- }
-
}
diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java
index dcf03c017..daa68bcfe 100644
--- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java
+++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java
@@ -37,94 +37,110 @@ package net.sourceforge.plantuml.project.draw;
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.project.TimeHeaderParameters;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
+import net.sourceforge.plantuml.style.PName;
+import net.sourceforge.plantuml.style.SName;
public class TimeHeaderQuarterly extends TimeHeaderCalendar {
- public double getTimeHeaderHeight() {
- return 16 + 13;
+ @Override
+ public double getTimeHeaderHeight(StringBounder stringBounder) {
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
+ final double h2 = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble();
+ return h1 + h2 + 5;
}
- public double getTimeFooterHeight() {
- return 16 + 13 - 1;
+ @Override
+ public double getTimeFooterHeight(StringBounder stringBounder) {
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
+ final double h2 = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble();
+ return h1 + h2 + 5;
}
- public TimeHeaderQuarterly(TimeHeaderParameters thParam) {
- super(thParam, new TimeScaleCompressed(thParam.getStartingDay(), thParam.getScale()));
+ @Override
+ public double getFullHeaderHeight(StringBounder stringBounder) {
+ return getTimeHeaderHeight(stringBounder);
+ }
+
+ public TimeHeaderQuarterly(StringBounder stringBounder, TimeHeaderParameters thParam, Day printStart) {
+ super(thParam, new TimeScaleCompressed(thParam.getCellWidth(stringBounder), thParam.getStartingDay(),
+ thParam.getScale(), printStart));
}
@Override
public void drawTimeHeader(final UGraphic ug, double totalHeightWithoutFooter) {
drawTextsBackground(ug, totalHeightWithoutFooter);
drawYears(ug);
- drawQuarters(ug.apply(UTranslate.dy(16)));
- printSmallVbars(ug, totalHeightWithoutFooter);
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
+ final double h2 = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble();
+ drawQuarters(ug.apply(UTranslate.dy(h1 + 2)));
+ printVerticalSeparators(ug, totalHeightWithoutFooter);
drawHline(ug, 0);
- drawHline(ug, 16);
- drawHline(ug, getFullHeaderHeight());
- }
-
- private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) {
- for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment())
- if (isBold(wink))
- drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter,
- isBold(wink));
+ drawHline(ug, h1 + 2);
+ drawHline(ug, h1 + 2 + h2 + 2);
+ // drawHline(ug, getFullHeaderHeight(ug.getStringBounder()));
}
@Override
public void drawTimeFooter(UGraphic ug) {
- ug = ug.apply(UTranslate.dy(3));
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
+ final double h2 = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble();
+ // ug = ug.apply(UTranslate.dy(3));
drawQuarters(ug);
- drawYears(ug.apply(UTranslate.dy(13)));
+ drawYears(ug.apply(UTranslate.dy(h2 + 2)));
drawHline(ug, 0);
- drawHline(ug, 13);
- drawHline(ug, getTimeFooterHeight());
+ drawHline(ug, h2 + 2);
+ drawHline(ug, h1 + 2 + h2 + 2);
+// drawHline(ug, getTimeFooterHeight(ug.getStringBounder()));
}
private void drawYears(final UGraphic ug) {
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
MonthYear last = null;
double lastChange = -1;
- for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink);
if (last == null || wink.monthYear().year() != last.year()) {
- drawVbar(ug, x1, 0, 15, false);
- if (last != null) {
+ drawVline(ug.apply(getLineColor()), x1, 0, h1 + 2);
+ if (last != null)
printYear(ug, last, lastChange, x1);
- }
+
lastChange = x1;
last = wink.monthYear();
}
}
- final double x1 = getTimeScale().getStartingPosition(max.increment());
- if (x1 > lastChange) {
+ final double x1 = getTimeScale().getStartingPosition(getMax().increment());
+ if (x1 > lastChange)
printYear(ug, last, lastChange, x1);
- }
- drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 15, false);
+
+ drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), 0, h1 + 2);
}
private void drawQuarters(UGraphic ug) {
+ final double h2 = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble();
String last = null;
double lastChange = -1;
- for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink);
if (quarter(wink).equals(last) == false) {
- drawVbar(ug, x1, 0, 12, false);
- if (last != null) {
+ drawVline(ug.apply(getLineColor()), x1, 0, h2 + 2);
+ if (last != null)
printQuarter(ug, last, lastChange, x1);
- }
+
lastChange = x1;
last = quarter(wink);
}
}
- final double x1 = getTimeScale().getStartingPosition(max.increment());
- if (x1 > lastChange) {
+ final double x1 = getTimeScale().getStartingPosition(getMax().increment());
+ if (x1 > lastChange)
printQuarter(ug, last, lastChange, x1);
- }
- drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12, false);
+
+ drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), 0, h2 + 2);
}
private String quarter(Day day) {
@@ -132,12 +148,12 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar {
}
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {
- final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, openFontColor());
+ final TextBlock small = getTextBlock(SName.month, "" + monthYear.year(), true, openFontColor());
printCentered(ug, false, start, end, small);
}
private void printQuarter(UGraphic ug, String quarter, double start, double end) {
- final TextBlock small = getTextBlock(quarter, 10, false, openFontColor());
+ final TextBlock small = getTextBlock(SName.day, quarter, false, openFontColor());
printCentered(ug, false, start, end, small);
}
@@ -145,9 +161,4 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar {
text.drawU(ug.apply(UTranslate.dx(start)));
}
- @Override
- public double getFullHeaderHeight() {
- return getTimeHeaderHeight();
- }
-
}
diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java
index a4a68f26f..a837c08f1 100644
--- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java
+++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java
@@ -35,12 +35,13 @@
*/
package net.sourceforge.plantuml.project.draw;
-import java.util.Set;
-
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.color.HColor;
import net.sourceforge.plantuml.klimt.creole.Display;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.FontConfiguration;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
+import net.sourceforge.plantuml.klimt.font.UFont;
import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.klimt.shape.ULine;
@@ -50,70 +51,60 @@ import net.sourceforge.plantuml.project.core.PrintScale;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.project.timescale.TimeScaleWink;
+import net.sourceforge.plantuml.style.PName;
+import net.sourceforge.plantuml.style.SName;
public class TimeHeaderSimple extends TimeHeader {
- private final TimeHeaderParameters colorDays;
private final PrintScale printScale;
- private final Set verticalSeparators;
@Override
- public double getFullHeaderHeight() {
- return getTimeHeaderHeight() + getHeaderNameDayHeight();
+ public double getFullHeaderHeight(StringBounder stringBounder) {
+ return getTimeHeaderHeight(stringBounder) + getHeaderNameDayHeight();
}
- public double getTimeHeaderHeight() {
- return 16;
+ @Override
+ public double getTimeHeaderHeight(StringBounder stringBounder) {
+ final double h = thParam.getStyle(SName.timeline, SName.day).value(PName.FontSize).asDouble();
+ return h + 6;
}
- public double getTimeFooterHeight() {
- return 16;
+ @Override
+ public double getTimeFooterHeight(StringBounder stringBounder) {
+ final double h = thParam.getStyle(SName.timeline, SName.day).value(PName.FontSize).asDouble();
+ return h + 6;
}
private double getHeaderNameDayHeight() {
return 0;
}
- public TimeHeaderSimple(TimeHeaderParameters thParam, PrintScale printScale) {
- super(thParam.getTimelineStyle(), thParam.getClosedStyle(), thParam.getMin(), thParam.getMax(),
- new TimeScaleWink(thParam.getScale(), printScale), thParam.getColorSet());
- this.colorDays = thParam;
+ public TimeHeaderSimple(StringBounder stringBounder, TimeHeaderParameters thParam, PrintScale printScale) {
+ super(thParam, new TimeScaleWink(thParam.getCellWidth(stringBounder), thParam.getScale(), printScale));
this.printScale = printScale;
- this.verticalSeparators = thParam.getVerticalSeparatorBefore();
- }
-
- private boolean isBold(Day wink) {
- return verticalSeparators.contains(wink);
- }
-
- private void drawSeparatorsDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) {
- final ULine vbar = ULine.vline(totalHeightWithoutFooter - getFullHeaderHeight() + 2);
- ug = goBold(ug).apply(UTranslate.dy(getFullHeaderHeight() - 1));
- for (Day i = min; i.compareTo(max.increment()) <= 0; i = i.increment(printScale))
- if (isBold(i)) {
- final double x1 = timeScale.getStartingPosition(i);
- ug.apply(UTranslate.dx(x1)).draw(vbar);
- }
}
private void drawSmallVlinesDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) {
- final ULine vbar = ULine.vline(totalHeightWithoutFooter);
- for (Day i = min; i.compareTo(max.increment()) <= 0; i = i.increment(printScale)) {
+ ug = ug.apply(getLineColor());
+ ug = ug.apply(UTranslate.dy(6));
+ final ULine vbar = ULine.vline(totalHeightWithoutFooter + 2);
+ for (Day i = getMin(); i.compareTo(getMax().increment()) <= 0; i = i.increment(printScale)) {
final double x1 = timeScale.getStartingPosition(i);
- ug.apply(getBarColor()).apply(UTranslate.dx(x1)).draw(vbar);
+ ug.apply(UTranslate.dx(x1)).draw(vbar);
}
}
private void drawSimpleDayCounter(UGraphic ug, TimeScale timeScale) {
- for (Day i = min; i.compareTo(max.increment()) <= 0; i = i.increment(printScale)) {
+ for (Day i = getMin(); i.compareTo(getMax().increment()) <= 0; i = i.increment(printScale)) {
final int value;
if (printScale == PrintScale.WEEKLY)
value = i.getAbsoluteDayNum() / 7 + 1;
else
value = i.getAbsoluteDayNum() + 1;
- final TextBlock num = Display.getWithNewlines("" + value).create(
- getFontConfiguration(10, false, openFontColor()), HorizontalAlignment.LEFT,
- new SpriteContainerEmpty());
+ final UFont font = thParam.getStyle(SName.timeline, SName.day).getUFont();
+ final FontConfiguration fontConfiguration = getFontConfiguration(font, false, openFontColor());
+ final TextBlock num = Display.getWithNewlines("" + value).create(fontConfiguration,
+ HorizontalAlignment.LEFT, new SpriteContainerEmpty());
final double x1 = timeScale.getStartingPosition(i);
final double x2;
if (printScale == PrintScale.WEEKLY)
@@ -122,33 +113,37 @@ public class TimeHeaderSimple extends TimeHeader {
x2 = timeScale.getEndingPosition(i);
final double width = num.calculateDimension(ug.getStringBounder()).getWidth();
final double delta = (x2 - x1) - width;
- if (i.compareTo(max.increment()) < 0)
+ if (i.compareTo(getMax().increment()) < 0)
num.drawU(ug.apply(UTranslate.dx(x1 + delta / 2)));
}
}
@Override
- public void drawTimeHeader(final UGraphic ug, double totalHeightWithoutFooter) {
- drawTextsBackground(ug.apply(UTranslate.dy(-3)), totalHeightWithoutFooter + 6);
- final double xmin = getTimeScale().getStartingPosition(min);
- final double xmax = getTimeScale().getEndingPosition(max);
- drawSmallVlinesDay(ug, getTimeScale(), totalHeightWithoutFooter + 2);
- drawSeparatorsDay(ug, getTimeScale(), totalHeightWithoutFooter);
+ public void drawTimeHeader(UGraphic ug, double totalHeightWithoutFooter) {
+ // drawTextsBackground(ug.apply(UTranslate.dy(-3)), totalHeightWithoutFooter +
+ // 6);
+ final double xmin = getTimeScale().getStartingPosition(getMin());
+ final double xmax = getTimeScale().getEndingPosition(getMax());
+ drawSmallVlinesDay(ug, getTimeScale(), totalHeightWithoutFooter);
+ printVerticalSeparators(ug, totalHeightWithoutFooter);
drawSimpleDayCounter(ug, getTimeScale());
- ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin));
- ug.apply(getBarColor()).apply(UTranslate.dy(getFullHeaderHeight() - 3)).draw(ULine.hline(xmax - xmin));
+ // ug = ug.apply(getLineColor());
+ // ug.draw(ULine.hline(xmax - xmin));
+ // ug.apply(UTranslate.dy(getFullHeaderHeight(ug.getStringBounder()) -
+ // 3)).draw(ULine.hline(xmax - xmin));
}
@Override
public void drawTimeFooter(UGraphic ug) {
- final double xmin = getTimeScale().getStartingPosition(min);
- final double xmax = getTimeScale().getEndingPosition(max);
+ final double xmin = getTimeScale().getStartingPosition(getMin());
+ final double xmax = getTimeScale().getEndingPosition(getMax());
ug = ug.apply(UTranslate.dy(3));
- drawSmallVlinesDay(ug, getTimeScale(), getTimeFooterHeight() - 3);
+ // drawSmallVlinesDay(ug, getTimeScale(),
+ // getTimeFooterHeight(ug.getStringBounder()) - 3);
drawSimpleDayCounter(ug, getTimeScale());
- ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin));
+ // ug.apply(getLineColor()).draw(ULine.hline(xmax - xmin));
}
// Duplicate in TimeHeaderDaily
@@ -170,13 +165,13 @@ public class TimeHeaderSimple extends TimeHeader {
protected final void drawTextsBackground(UGraphic ug, double totalHeightWithoutFooter) {
- final double height = totalHeightWithoutFooter - getFullHeaderHeight();
+ final double height = totalHeightWithoutFooter - getFullHeaderHeight(ug.getStringBounder());
Pending pending = null;
- for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink);
final double x2 = getTimeScale().getEndingPosition(wink);
- HColor back = colorDays.getColor(wink);
+ HColor back = thParam.getColor(wink);
// // Day of week should be stronger than period of time (back color).
// final HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek());
// if (backDoW != null) {
diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java
index aa8374632..af6fbaffd 100644
--- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java
+++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java
@@ -37,29 +37,48 @@ package net.sourceforge.plantuml.project.draw;
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.project.TimeHeaderParameters;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.time.WeekNumberStrategy;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
+import net.sourceforge.plantuml.style.PName;
+import net.sourceforge.plantuml.style.SName;
public class TimeHeaderWeekly extends TimeHeaderCalendar {
private final WeekNumberStrategy weekNumberStrategy;
private final boolean withCalendarDate;
- public double getTimeHeaderHeight() {
- return 16 + 13;
+ @Override
+ public double getTimeHeaderHeight(StringBounder stringBounder) {
+ final double h1 = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble();
+ final double h2 = thParam.getStyle(SName.timeline, SName.day).value(PName.FontSize).asDouble();
+ return h1 + h2 + 5;
}
- public double getTimeFooterHeight() {
- return 16;
+ @Override
+ public double getTimeFooterHeight(StringBounder stringBounder) {
+ final double h = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble() + 4;
+ return h;
}
- public TimeHeaderWeekly(TimeHeaderParameters thParam, WeekNumberStrategy weekNumberStrategy,
- boolean withCalendarDate) {
- super(thParam, new TimeScaleCompressed(thParam.getStartingDay(), thParam.getScale()));
+ @Override
+ public double getFullHeaderHeight(StringBounder stringBounder) {
+ return getTimeHeaderHeight(stringBounder);
+ }
+
+ private double getH1(StringBounder stringBounder) {
+ final double h = thParam.getStyle(SName.timeline, SName.month).value(PName.FontSize).asDouble() + 4;
+ return h;
+ }
+
+ public TimeHeaderWeekly(StringBounder stringBounder, TimeHeaderParameters thParam,
+ WeekNumberStrategy weekNumberStrategy, boolean withCalendarDate, Day printStart) {
+ super(thParam, new TimeScaleCompressed(thParam.getCellWidth(stringBounder), thParam.getStartingDay(),
+ thParam.getScale(), printStart));
this.weekNumberStrategy = weekNumberStrategy;
this.withCalendarDate = withCalendarDate;
}
@@ -69,76 +88,75 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
drawTextsBackground(ug, totalHeightWithoutFooter);
drawCalendar(ug, totalHeightWithoutFooter);
drawHline(ug, 0);
- drawHline(ug, Y_POS_ROW16());
- drawHline(ug, getFullHeaderHeight());
+ drawHline(ug, getH1(ug.getStringBounder()));
+ drawHline(ug, getFullHeaderHeight(ug.getStringBounder()));
}
@Override
public void drawTimeFooter(UGraphic ug) {
drawHline(ug, 0);
printMonths(ug);
- drawHline(ug, getTimeFooterHeight());
+ drawHline(ug, getTimeFooterHeight(ug.getStringBounder()));
}
private void drawCalendar(final UGraphic ug, double totalHeightWithoutFooter) {
printDaysOfMonth(ug);
- printSmallVbars(ug, totalHeightWithoutFooter);
+ printVerticalSeparators(ug, totalHeightWithoutFooter);
printMonths(ug);
}
private void printMonths(final UGraphic ug) {
MonthYear last = null;
double lastChangeMonth = -1;
- for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink);
if (wink.monthYear().equals(last) == false) {
- drawVbar(ug, x1, 0, Y_POS_ROW16(), false);
- if (last != null) {
+ drawVline(ug.apply(getLineColor()), x1, 0, getH1(ug.getStringBounder()));
+ if (last != null)
printMonth(ug, last, lastChangeMonth, x1);
- }
+
lastChangeMonth = x1;
last = wink.monthYear();
}
}
- drawVbar(ug, getTimeScale().getEndingPosition(max), 0, Y_POS_ROW16(), false);
- final double x1 = getTimeScale().getStartingPosition(max.increment());
- if (x1 > lastChangeMonth) {
+ drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), (double) 0,
+ getH1(ug.getStringBounder()));
+ final double x1 = getTimeScale().getStartingPosition(getMax().increment());
+ if (last != null && x1 > lastChangeMonth)
printMonth(ug, last, lastChangeMonth, x1);
- }
+
}
- private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) {
- for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment())
+ @Override
+ protected void printVerticalSeparators(final UGraphic ug, double totalHeightWithoutFooter) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment())
if (wink.getDayOfWeek() == weekNumberStrategy.getFirstDayOfWeek())
- drawVbar(ug, getTimeScale().getStartingPosition(wink), Y_POS_ROW16(), totalHeightWithoutFooter, false);
-
- drawVbar(ug, getTimeScale().getEndingPosition(max), Y_POS_ROW16(), totalHeightWithoutFooter, false);
-
- for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment())
- if (isBold(wink))
- drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter,
- isBold(wink));
+ drawVline(ug.apply(getLineColor()), getTimeScale().getStartingPosition(wink),
+ getH1(ug.getStringBounder()), totalHeightWithoutFooter);
+ drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), getH1(ug.getStringBounder()),
+ totalHeightWithoutFooter);
+ super.printVerticalSeparators(ug, totalHeightWithoutFooter);
}
private void printDaysOfMonth(final UGraphic ug) {
- for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
if (wink.getDayOfWeek() == weekNumberStrategy.getFirstDayOfWeek()) {
final String num;
if (withCalendarDate)
num = "" + wink.getDayOfMonth();
else
num = "" + wink.getWeekOfYear(weekNumberStrategy);
- final TextBlock textBlock = getTextBlock(num, 10, false, openFontColor());
- printLeft(ug.apply(UTranslate.dy(Y_POS_ROW16())), textBlock,
+ final TextBlock textBlock = getTextBlock(SName.day, num, false, openFontColor());
+ printLeft(ug.apply(UTranslate.dy(getH1(ug.getStringBounder()))), textBlock,
getTimeScale().getStartingPosition(wink) + 5);
}
}
}
private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) {
- final TextBlock small = getTextBlock(monthYear.shortName(locale()), 12, true, openFontColor());
- final TextBlock big = getTextBlock(monthYear.shortNameYYYY(locale()), 12, true, openFontColor());
+ final TextBlock small = getTextBlock(SName.month, monthYear.shortName(locale()), true, openFontColor());
+ final TextBlock big = getTextBlock(SName.month, monthYear.shortNameYYYY(locale()), true, openFontColor());
printCentered(ug, false, start, end, small, big);
}
@@ -146,9 +164,4 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
text.drawU(ug.apply(UTranslate.dx(start)));
}
- @Override
- public double getFullHeaderHeight() {
- return getTimeHeaderHeight();
- }
-
}
diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java
index 9d537fd41..fddee9e9a 100644
--- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java
+++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java
@@ -35,81 +35,83 @@
*/
package net.sourceforge.plantuml.project.draw;
-import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
+import net.sourceforge.plantuml.klimt.font.StringBounder;
import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.project.TimeHeaderParameters;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
+import net.sourceforge.plantuml.style.PName;
+import net.sourceforge.plantuml.style.SName;
public class TimeHeaderYearly extends TimeHeaderCalendar {
- public double getTimeHeaderHeight() {
- return 20;
+ @Override
+ public double getTimeHeaderHeight(StringBounder stringBounder) {
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
+ return h1 + 3;
}
- public double getTimeFooterHeight() {
- return 20 - 1;
+ @Override
+ public double getTimeFooterHeight(StringBounder stringBounder) {
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
+ return h1 + 3;
}
- public TimeHeaderYearly(TimeHeaderParameters thParam) {
- super(thParam, new TimeScaleCompressed(thParam.getStartingDay(), thParam.getScale()));
+ @Override
+ public double getFullHeaderHeight(StringBounder stringBounder) {
+ return getTimeHeaderHeight(stringBounder);
+ }
+
+ public TimeHeaderYearly(StringBounder stringBounder, TimeHeaderParameters thParam, Day printStart) {
+ super(thParam, new TimeScaleCompressed(thParam.getCellWidth(stringBounder), thParam.getStartingDay(),
+ thParam.getScale(), printStart));
}
@Override
public void drawTimeHeader(final UGraphic ug, double totalHeightWithoutFooter) {
drawTextsBackground(ug, totalHeightWithoutFooter);
drawYears(ug);
- printSmallVbars(ug, totalHeightWithoutFooter);
+ printVerticalSeparators(ug, totalHeightWithoutFooter);
drawHline(ug, 0);
- drawHline(ug, getFullHeaderHeight());
- }
-
- private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) {
- for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment())
- if (isBold(wink))
- drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter,
- isBold(wink));
+ drawHline(ug, getFullHeaderHeight(ug.getStringBounder()));
}
@Override
public void drawTimeFooter(UGraphic ug) {
- ug = ug.apply(UTranslate.dy(3));
+ // ug = ug.apply(UTranslate.dy(3));
drawYears(ug);
drawHline(ug, 0);
- drawHline(ug, getTimeFooterHeight());
+ drawHline(ug, getTimeFooterHeight(ug.getStringBounder()));
}
private void drawYears(final UGraphic ug) {
+ final double h1 = thParam.getStyle(SName.timeline, SName.year).value(PName.FontSize).asDouble();
+
MonthYear last = null;
double lastChange = -1;
- for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
+ for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink);
if (last == null || wink.monthYear().year() != last.year()) {
- drawVbar(ug, x1, 0, 19, false);
- if (last != null) {
+ drawVline(ug.apply(getLineColor()), x1, 0, h1 + 2);
+ if (last != null)
printYear(ug, last, lastChange, x1);
- }
+
lastChange = x1;
last = wink.monthYear();
}
}
- final double x1 = getTimeScale().getStartingPosition(max.increment());
- if (x1 > lastChange) {
+ final double x1 = getTimeScale().getStartingPosition(getMax().increment());
+ if (x1 > lastChange)
printYear(ug, last, lastChange, x1);
- }
- drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 19, false);
+
+ drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), 0, h1 + 2);
}
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {
- final TextBlock small = getTextBlock("" + monthYear.year(), 14, true, openFontColor());
+ final TextBlock small = getTextBlock(SName.year, "" + monthYear.year(), true, openFontColor());
printCentered(ug, true, start, end, small);
}
- @Override
- public double getFullHeaderHeight() {
- return getTimeHeaderHeight();
- }
-
}
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementAnything.java b/src/net/sourceforge/plantuml/project/lang/ComplementAnything.java
new file mode 100644
index 000000000..5a9bc3c45
--- /dev/null
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementAnything.java
@@ -0,0 +1,54 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.project.lang;
+
+import net.sourceforge.plantuml.project.Failable;
+import net.sourceforge.plantuml.project.GanttDiagram;
+import net.sourceforge.plantuml.regex.IRegex;
+import net.sourceforge.plantuml.regex.RegexLeaf;
+import net.sourceforge.plantuml.regex.RegexResult;
+
+public class ComplementAnything implements Something {
+
+ public IRegex toRegex(String suffix) {
+ return new RegexLeaf("ANYTHING" + suffix, "(.*?)");
+ }
+
+ public Failable getMe(GanttDiagram system, RegexResult arg, String suffix) {
+ final String value = arg.get("ANYTHING" + suffix, 0);
+ return Failable.ok(value);
+ }
+}
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java b/src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java
index fc61a7aad..cd8a2b411 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java
@@ -45,7 +45,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementBeforeOrAfterOrAtTaskStartOrEnd implements Something {
+public class ComplementBeforeOrAfterOrAtTaskStartOrEnd implements Something {
private static final int POS_NB1 = 0;
private static final int POS_WORKING1 = 1;
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementClose.java b/src/net/sourceforge/plantuml/project/lang/ComplementClose.java
index a3ef45a6e..c2c2e449d 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementClose.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementClose.java
@@ -41,7 +41,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementClose implements Something {
+public class ComplementClose implements Something {
public IRegex toRegex(String suffix) {
return new RegexLeaf("CLOSED" + suffix, "(closed?(?: for \\[([^\\[\\]]+?)\\])?)");
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementCompleted.java b/src/net/sourceforge/plantuml/project/lang/ComplementCompleted.java
index 5931f8e37..0ffcf0b1e 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementCompleted.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementCompleted.java
@@ -42,7 +42,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementCompleted implements Something {
+public class ComplementCompleted implements Something {
public IRegex toRegex(String suffix) {
return new RegexLeaf("COMPLEMENT" + suffix, "(\\d+).*completed?");
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementDate.java b/src/net/sourceforge/plantuml/project/lang/ComplementDate.java
index ae52dfdb0..2b70fd246 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementDate.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementDate.java
@@ -38,44 +38,45 @@ package net.sourceforge.plantuml.project.lang;
import net.sourceforge.plantuml.project.Failable;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.time.Day;
-import net.sourceforge.plantuml.project.time.Month;
import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexOr;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementDate implements Something {
+public class ComplementDate implements Something {
+
+ private final Type type;
+
+ static enum Type {
+ ANY, ONLY_RELATIVE, ONLY_ABSOLUTE;
+ }
+
+ private ComplementDate(Type type) {
+ this.type = type;
+ }
+
+ public static ComplementDate any() {
+ return new ComplementDate(Type.ANY);
+ }
+
+ public static ComplementDate onlyRelative() {
+ return new ComplementDate(Type.ONLY_RELATIVE);
+ }
+
+ public static ComplementDate onlyAbsolute() {
+ return new ComplementDate(Type.ONLY_ABSOLUTE);
+ }
public IRegex toRegex(String suffix) {
- return new RegexOr(toRegexA(suffix), toRegexB(suffix), toRegexC(suffix), toRegexD(suffix), toRegexE(suffix));
- }
-
- private IRegex toRegexA(String suffix) {
- return new RegexConcat( //
- new RegexLeaf("ADAY" + suffix, "([\\d]+)"), //
- new RegexLeaf("[\\w, ]*?"), //
- new RegexLeaf("AMONTH" + suffix, "(" + Month.getRegexString() + ")"), //
- new RegexLeaf("[\\w, ]*?"), //
- new RegexLeaf("AYEAR" + suffix, "([\\d]{4})"));
- }
-
- private IRegex toRegexB(String suffix) {
- return new RegexConcat( //
- new RegexLeaf("BYEAR" + suffix, "([\\d]{4})"), //
- new RegexLeaf("\\D"), //
- new RegexLeaf("BMONTH" + suffix, "([\\d]{1,2})"), //
- new RegexLeaf("\\D"), //
- new RegexLeaf("BDAY" + suffix, "([\\d]{1,2})"));
- }
-
- private IRegex toRegexC(String suffix) {
- return new RegexConcat( //
- new RegexLeaf("CMONTH" + suffix, "(" + Month.getRegexString() + ")"), //
- new RegexLeaf("[\\w, ]*?"), //
- new RegexLeaf("CDAY" + suffix, "([\\d]+)"), //
- new RegexLeaf("[\\w, ]*?"), //
- new RegexLeaf("CYEAR" + suffix, "([\\d]{4})"));
+ final DayPattern dayPattern = new DayPattern(suffix);
+ switch (type) {
+ case ONLY_ABSOLUTE:
+ return dayPattern.toRegex();
+ case ONLY_RELATIVE:
+ return new RegexOr(toRegexD(suffix), toRegexE(suffix));
+ }
+ return new RegexOr(dayPattern.toRegex(), toRegexD(suffix), toRegexE(suffix));
}
private IRegex toRegexD(String suffix) {
@@ -98,45 +99,21 @@ public class ComplementDate implements Something {
}
public Failable getMe(GanttDiagram system, RegexResult arg, String suffix) {
- if (arg.get("ADAY" + suffix, 0) != null) {
- return Failable.ok(resultA(arg, suffix));
- }
- if (arg.get("BDAY" + suffix, 0) != null) {
- return Failable.ok(resultB(arg, suffix));
- }
- if (arg.get("CDAY" + suffix, 0) != null) {
- return Failable.ok(resultC(arg, suffix));
- }
- if (arg.get("DCOUNT" + suffix, 0) != null) {
+ final DayPattern dayPattern = new DayPattern(suffix);
+ final Day result = dayPattern.getDay(arg);
+
+ if (result != null)
+ return Failable.ok(result);
+
+ if (arg.get("DCOUNT" + suffix, 0) != null)
return Failable.ok(resultD(system, arg, suffix));
- }
- if (arg.get("ECOUNT" + suffix, 0) != null) {
+
+ if (arg.get("ECOUNT" + suffix, 0) != null)
return Failable.ok(resultE(system, arg, suffix));
- }
+
throw new IllegalStateException();
}
- private Day resultA(RegexResult arg, String suffix) {
- final int day = Integer.parseInt(arg.get("ADAY" + suffix, 0));
- final String month = arg.get("AMONTH" + suffix, 0);
- final int year = Integer.parseInt(arg.get("AYEAR" + suffix, 0));
- return Day.create(year, month, day);
- }
-
- private Day resultB(RegexResult arg, String suffix) {
- final int day = Integer.parseInt(arg.get("BDAY" + suffix, 0));
- final int month = Integer.parseInt(arg.get("BMONTH" + suffix, 0));
- final int year = Integer.parseInt(arg.get("BYEAR" + suffix, 0));
- return Day.create(year, month, day);
- }
-
- private Day resultC(RegexResult arg, String suffix) {
- final int day = Integer.parseInt(arg.get("CDAY" + suffix, 0));
- final String month = arg.get("CMONTH" + suffix, 0);
- final int year = Integer.parseInt(arg.get("CYEAR" + suffix, 0));
- return Day.create(year, month, day);
- }
-
private Day resultD(GanttDiagram system, RegexResult arg, String suffix) {
final int day = Integer.parseInt(arg.get("DCOUNT" + suffix, 0));
return system.getStartingDate().addDays(day);
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementDates.java b/src/net/sourceforge/plantuml/project/lang/ComplementDates.java
index 4bcbb31f1..253f3e0cf 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementDates.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementDates.java
@@ -45,27 +45,21 @@ import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexOr;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementDates implements Something {
+public class ComplementDates implements Something {
public IRegex toRegex(String suffix) {
return new RegexOr(toRegexB(suffix), toRegexE(suffix));
}
private IRegex toRegexB(String suffix) {
+ final DayPattern dayPattern1 = new DayPattern("1");
+ final DayPattern dayPattern2 = new DayPattern("2");
return new RegexConcat( //
- new RegexLeaf("BYEAR1" + suffix, "([\\d]{4})"), //
- new RegexLeaf("\\D"), //
- new RegexLeaf("BMONTH1" + suffix, "([\\d]{1,2})"), //
- new RegexLeaf("\\D"), //
- new RegexLeaf("BDAY1" + suffix, "([\\d]{1,2})"), //
+ dayPattern1.toRegex(), //
+ Words.exactly(Words.TO), //
+ Words.zeroOrMore(Words.THE), //
RegexLeaf.spaceOneOrMore(), //
- new RegexLeaf("to"), //
- RegexLeaf.spaceOneOrMore(), //
- new RegexLeaf("BYEAR2" + suffix, "([\\d]{4})"), //
- new RegexLeaf("\\D"), //
- new RegexLeaf("BMONTH2" + suffix, "([\\d]{1,2})"), //
- new RegexLeaf("\\D"), //
- new RegexLeaf("BDAY2" + suffix, "([\\d]{1,2})") //
+ dayPattern2.toRegex() //
);
}
@@ -73,8 +67,8 @@ public class ComplementDates implements Something {
return new RegexConcat( //
new RegexLeaf("[dD]\\+"), //
new RegexLeaf("ECOUNT1" + suffix, "([\\d]+)"), //
- RegexLeaf.spaceOneOrMore(), //
- new RegexLeaf("to"), //
+ Words.exactly(Words.TO), //
+ Words.zeroOrMore(Words.THE), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("[dD]\\+"), //
new RegexLeaf("ECOUNT2" + suffix, "([\\d]+)") //
@@ -82,30 +76,19 @@ public class ComplementDates implements Something {
}
public Failable getMe(GanttDiagram project, RegexResult arg, String suffix) {
- if (arg.get("BDAY1" + suffix, 0) != null) {
- return Failable.ok(resultB(arg, suffix));
+ final Day d1 = new DayPattern("1").getDay(arg);
+ if (d1 != null) {
+ final Day d2 = new DayPattern("2").getDay(arg);
+ return Failable.ok(new DaysAsDates(d1, d2));
}
- if (arg.get("ECOUNT1" + suffix, 0) != null) {
+
+ if (arg.get("ECOUNT1" + suffix, 0) != null)
return Failable.ok(resultE(project, arg, suffix));
- }
+
throw new IllegalStateException();
}
- private DaysAsDates resultB(RegexResult arg, String suffix) {
- final int day1 = Integer.parseInt(arg.get("BDAY1" + suffix, 0));
- final int month1 = Integer.parseInt(arg.get("BMONTH1" + suffix, 0));
- final int year1 = Integer.parseInt(arg.get("BYEAR1" + suffix, 0));
- final Day date1 = Day.create(year1, month1, day1);
-
- final int day2 = Integer.parseInt(arg.get("BDAY2" + suffix, 0));
- final int month2 = Integer.parseInt(arg.get("BMONTH2" + suffix, 0));
- final int year2 = Integer.parseInt(arg.get("BYEAR2" + suffix, 0));
- final Day date2 = Day.create(year2, month2, day2);
-
- return new DaysAsDates(date1, date2);
- }
-
private DaysAsDates resultE(GanttDiagram project, RegexResult arg, String suffix) {
final int day1 = Integer.parseInt(arg.get("ECOUNT1" + suffix, 0));
final Day date1 = project.getStartingDate().addDays(day1);
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementDayOfWeek.java b/src/net/sourceforge/plantuml/project/lang/ComplementDayOfWeek.java
index 0bf87b3fe..e0cb00362 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementDayOfWeek.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementDayOfWeek.java
@@ -43,7 +43,7 @@ import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementDayOfWeek implements Something {
+public class ComplementDayOfWeek implements Something {
public IRegex toRegex(String suffix) {
return new RegexConcat( //
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementEmpty.java b/src/net/sourceforge/plantuml/project/lang/ComplementEmpty.java
index 52b5a3c96..d8ea753fe 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementEmpty.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementEmpty.java
@@ -41,7 +41,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementEmpty implements Something {
+public class ComplementEmpty implements Something {
public IRegex toRegex(String suffix) {
return new RegexLeaf("");
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementFromTo.java b/src/net/sourceforge/plantuml/project/lang/ComplementFromTo.java
index e20149962..ac0eec32b 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementFromTo.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementFromTo.java
@@ -41,7 +41,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementFromTo implements Something {
+public class ComplementFromTo implements Something {
public IRegex toRegex(String suffix) {
return new RegexLeaf("COMPLEMENT" + suffix, "from[%s]+\\[([^\\[\\]]+)\\][%s]+to[%s]+\\[([^\\[\\]]+)\\]");
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementInColors.java b/src/net/sourceforge/plantuml/project/lang/ComplementInColors.java
index 05fa7851e..a5e6cc3aa 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementInColors.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementInColors.java
@@ -42,7 +42,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementInColors implements Something {
+public class ComplementInColors implements Something {
public IRegex toRegex(String suffix) {
return new RegexLeaf("COMPLEMENT" + suffix, "in[%s]+(#?\\w+)(?:/(#?\\w+))?");
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementInColors2.java b/src/net/sourceforge/plantuml/project/lang/ComplementInColors2.java
index 1a31c1c37..d68fefc74 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementInColors2.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementInColors2.java
@@ -42,7 +42,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementInColors2 implements Something {
+public class ComplementInColors2 implements Something {
public IRegex toRegex(String suffix) {
return new RegexLeaf("COMPLEMENT" + suffix, "colou?red[%s]+(?:in[%s]+)?(#?\\w+)(?:/(#?\\w+))?");
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementInColorsFromTo.java b/src/net/sourceforge/plantuml/project/lang/ComplementInColorsFromTo.java
index 05d964cd6..ae9d67cdd 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementInColorsFromTo.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementInColorsFromTo.java
@@ -42,7 +42,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementInColorsFromTo implements Something {
+public class ComplementInColorsFromTo implements Something {
public IRegex toRegex(String suffix) {
return new RegexLeaf("COMPLEMENT" + suffix,
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementNamed.java b/src/net/sourceforge/plantuml/project/lang/ComplementNamed.java
index 901aef1ba..d8f05d7aa 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementNamed.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementNamed.java
@@ -41,7 +41,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementNamed implements Something {
+public class ComplementNamed implements Something {
public IRegex toRegex(String suffix) {
return new RegexLeaf("COMPLEMENT" + suffix, "\\[([^\\[\\]]+)\\]");
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementOpen.java b/src/net/sourceforge/plantuml/project/lang/ComplementOpen.java
index c2090468d..a72a48027 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementOpen.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementOpen.java
@@ -41,7 +41,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementOpen implements Something {
+public class ComplementOpen implements Something {
public IRegex toRegex(String suffix) {
return new RegexLeaf("OPEN" + suffix, "(opene?d?(?: for \\[([^\\[\\]]+?)\\])?)");
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementSeveralDays.java b/src/net/sourceforge/plantuml/project/lang/ComplementSeveralDays.java
index 03f1ebad2..b59548795 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementSeveralDays.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementSeveralDays.java
@@ -43,7 +43,7 @@ import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementSeveralDays implements Something {
+public class ComplementSeveralDays implements Something {
public IRegex toRegex(String suffix) {
return new RegexConcat( //
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementTask.java b/src/net/sourceforge/plantuml/project/lang/ComplementTask.java
new file mode 100644
index 000000000..79759fcb9
--- /dev/null
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementTask.java
@@ -0,0 +1,58 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.project.lang;
+
+import net.sourceforge.plantuml.project.Failable;
+import net.sourceforge.plantuml.project.GanttDiagram;
+import net.sourceforge.plantuml.project.core.Task;
+import net.sourceforge.plantuml.regex.IRegex;
+import net.sourceforge.plantuml.regex.RegexLeaf;
+import net.sourceforge.plantuml.regex.RegexResult;
+
+public class ComplementTask implements Something {
+
+ public IRegex toRegex(String suffix) {
+ return new RegexLeaf("COMPLEMENT" + suffix, "\\[([^\\[\\]]+?)\\]");
+ }
+
+ public Failable getMe(GanttDiagram gantt, RegexResult arg, String suffix) {
+ final String code = arg.get("COMPLEMENT" + suffix, 0);
+ final Task task = gantt.getExistingTask(code);
+ if (task == null)
+ return Failable.error("No such task " + code);
+ return Failable.ok(task);
+ }
+}
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementUrl.java b/src/net/sourceforge/plantuml/project/lang/ComplementUrl.java
index c7499f38a..5d2c44c9d 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementUrl.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementUrl.java
@@ -45,7 +45,7 @@ import net.sourceforge.plantuml.url.Url;
import net.sourceforge.plantuml.url.UrlBuilder;
import net.sourceforge.plantuml.url.UrlMode;
-public class ComplementUrl implements Something {
+public class ComplementUrl implements Something {
public IRegex toRegex(String suffix) {
return new RegexConcat( //
diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementWithColorLink.java b/src/net/sourceforge/plantuml/project/lang/ComplementWithColorLink.java
index 688e44b44..b03645955 100644
--- a/src/net/sourceforge/plantuml/project/lang/ComplementWithColorLink.java
+++ b/src/net/sourceforge/plantuml/project/lang/ComplementWithColorLink.java
@@ -42,7 +42,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class ComplementWithColorLink implements Something {
+public class ComplementWithColorLink implements Something {
public IRegex toRegex(String suffix) {
final String optionalStyle = "(?:(dotted|bold|dashed)[%s]+)?";
diff --git a/src/net/sourceforge/plantuml/project/lang/DayPattern.java b/src/net/sourceforge/plantuml/project/lang/DayPattern.java
new file mode 100644
index 000000000..647d204d4
--- /dev/null
+++ b/src/net/sourceforge/plantuml/project/lang/DayPattern.java
@@ -0,0 +1,136 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2024, Arnaud Roques
+ *
+ * Project Info: https://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * https://plantuml.com/patreon (only 1$ per month!)
+ * https://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.project.lang;
+
+import net.sourceforge.plantuml.project.time.Day;
+import net.sourceforge.plantuml.project.time.Month;
+import net.sourceforge.plantuml.regex.IRegex;
+import net.sourceforge.plantuml.regex.RegexConcat;
+import net.sourceforge.plantuml.regex.RegexLeaf;
+import net.sourceforge.plantuml.regex.RegexOr;
+import net.sourceforge.plantuml.regex.RegexResult;
+
+public class DayPattern {
+
+ private final String id;
+ private final String yearKeyA;
+ private final String yearKeyB;
+ private final String yearKeyC;
+ private final String monthKeyA;
+ private final String monthKeyB;
+ private final String monthKeyC;
+ private final String dayKeyA;
+ private final String dayKeyB;
+ private final String dayKeyC;
+
+ public DayPattern(String id) {
+ this.id = id;
+ this.yearKeyA = "AYEAR" + id;
+ this.yearKeyB = "BYEAR" + id;
+ this.yearKeyC = "CYEAR" + id;
+ this.monthKeyA = "AMONTH" + id;
+ this.monthKeyB = "BMONTH" + id;
+ this.monthKeyC = "CMONTH" + id;
+ this.dayKeyA = "ADAY" + id;
+ this.dayKeyB = "BDAY" + id;
+ this.dayKeyC = "CDAY" + id;
+ }
+
+ public IRegex toRegex() {
+ return new RegexOr(toRegexA_DD_MONTH_YYYY(), toRegexB_YYYY_MM_DD(), toRegexC_MONTH_DD_YYYY());
+ }
+
+ public Day getDay(RegexResult arg) {
+ if (arg.get(dayKeyA, 0) != null)
+ return resultA(arg);
+
+ if (arg.get(dayKeyB, 0) != null)
+ return resultB(arg);
+
+ if (arg.get(dayKeyC, 0) != null)
+ return resultC(arg);
+ return null;
+ }
+
+ private IRegex toRegexA_DD_MONTH_YYYY() {
+ return new RegexConcat( //
+ new RegexLeaf(dayKeyA, "([\\d]{1,2})"), //
+ new RegexLeaf("[\\w, ]*?"), //
+ new RegexLeaf(monthKeyA, "(" + Month.getRegexString() + ")"), //
+ new RegexLeaf("[\\w, ]*?"), //
+ new RegexLeaf(yearKeyA, "([\\d]{1,4})"));
+ }
+
+ private Day resultA(RegexResult arg) {
+ final int day = Integer.parseInt(arg.get(dayKeyA, 0));
+ final String month = arg.get(monthKeyA, 0);
+ final int year = Integer.parseInt(arg.get(yearKeyA, 0));
+ return Day.create(year, month, day);
+ }
+
+ private IRegex toRegexB_YYYY_MM_DD() {
+ return new RegexConcat( //
+ new RegexLeaf(yearKeyB, "([\\d]{1,4})"), //
+ new RegexLeaf("\\D"), //
+ new RegexLeaf(monthKeyB, "([\\d]{1,2})"), //
+ new RegexLeaf("\\D"), //
+ new RegexLeaf(dayKeyB, "([\\d]{1,2})"));
+ }
+
+ private Day resultB(RegexResult arg) {
+ final int day = Integer.parseInt(arg.get(dayKeyB, 0));
+ final int month = Integer.parseInt(arg.get(monthKeyB, 0));
+ final int year = Integer.parseInt(arg.get(yearKeyB, 0));
+ return Day.create(year, month, day);
+ }
+
+ private IRegex toRegexC_MONTH_DD_YYYY() {
+ return new RegexConcat( //
+ new RegexLeaf(monthKeyC, "(" + Month.getRegexString() + ")"), //
+ new RegexLeaf("[\\w, ]*?"), //
+ new RegexLeaf(dayKeyC, "([\\d]{1,2})"), //
+ new RegexLeaf("[\\w, ]*?"), //
+ new RegexLeaf(yearKeyC, "([\\d]{1,4})"));
+ }
+
+ private Day resultC(RegexResult arg) {
+ final int day = Integer.parseInt(arg.get(dayKeyC, 0));
+ final String month = arg.get(monthKeyC, 0);
+ final int year = Integer.parseInt(arg.get(yearKeyC, 0));
+ return Day.create(year, month, day);
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/project/lang/PairOfSomething.java b/src/net/sourceforge/plantuml/project/lang/PairOfSomething.java
index ceb3e679b..9c2a02364 100644
--- a/src/net/sourceforge/plantuml/project/lang/PairOfSomething.java
+++ b/src/net/sourceforge/plantuml/project/lang/PairOfSomething.java
@@ -35,26 +35,26 @@
*/
package net.sourceforge.plantuml.project.lang;
+import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.project.Failable;
-import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class PairOfSomething implements Something {
+public class PairOfSomething implements Something {
- private final Something complement1;
- private final Something complement2;
+ private final Something complement1;
+ private final Something complement2;
- public PairOfSomething(Something complement1, Something complement2) {
+ public PairOfSomething(Something complement1, Something complement2) {
this.complement1 = complement1;
this.complement2 = complement2;
}
- public Failable extends Object> getMe(GanttDiagram system, RegexResult arg, String suffix) {
- final Failable extends Object> r1 = complement1.getMe(system, arg, "A" + suffix);
- final Failable extends Object> r2 = complement2.getMe(system, arg, "B" + suffix);
+ public Failable extends Object> getMe(D diagram, RegexResult arg, String suffix) {
+ final Failable extends Object> r1 = complement1.getMe(diagram, arg, "A" + suffix);
+ final Failable extends Object> r2 = complement2.getMe(diagram, arg, "B" + suffix);
if (r1.isFail()) {
return r1;
}
diff --git a/src/net/sourceforge/plantuml/project/lang/Sentence.java b/src/net/sourceforge/plantuml/project/lang/Sentence.java
index 3110735fd..769157d28 100644
--- a/src/net/sourceforge/plantuml/project/lang/Sentence.java
+++ b/src/net/sourceforge/plantuml/project/lang/Sentence.java
@@ -36,14 +36,19 @@
package net.sourceforge.plantuml.project.lang;
import net.sourceforge.plantuml.command.CommandExecutionResult;
-import net.sourceforge.plantuml.project.GanttDiagram;
+import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.regex.IRegex;
+import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public interface Sentence {
+public interface Sentence {
+
+ public final RegexLeaf OPTIONAL_FINAL_DOT = new RegexLeaf("\\s*[.]?\\s*$");
+
+ public final RegexLeaf SENTENCE_SEPARATOR = new RegexLeaf("\\s*(,|\\sand\\s)\\s*");
public IRegex toRegex();
- public CommandExecutionResult execute(GanttDiagram project, RegexResult arg);
+ public CommandExecutionResult execute(D project, RegexResult arg);
}
diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceAnd.java b/src/net/sourceforge/plantuml/project/lang/SentenceAnd.java
index c2f9bd82b..898a476fc 100644
--- a/src/net/sourceforge/plantuml/project/lang/SentenceAnd.java
+++ b/src/net/sourceforge/plantuml/project/lang/SentenceAnd.java
@@ -36,19 +36,19 @@
package net.sourceforge.plantuml.project.lang;
import net.sourceforge.plantuml.command.CommandExecutionResult;
+import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.project.Failable;
-import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class SentenceAnd implements Sentence {
+public class SentenceAnd implements Sentence {
- private final SentenceSimple sentence1;
- private final SentenceSimple sentence2;
+ private final SentenceSimple sentence1;
+ private final SentenceSimple sentence2;
- public SentenceAnd(SentenceSimple sentence1, SentenceSimple sentence2) {
+ public SentenceAnd(SentenceSimple sentence1, SentenceSimple sentence2) {
this.sentence1 = sentence1;
this.sentence2 = sentence2;
}
@@ -56,37 +56,37 @@ public class SentenceAnd implements Sentence {
public IRegex toRegex() {
return new RegexConcat(//
RegexLeaf.start(), //
- sentence1.subjectii.toRegex(), //
+ sentence1.getSubject().toRegex(), //
RegexLeaf.spaceOneOrMore(), //
sentence1.getVerbRegex(), //
+ sentence1.getAdverbialOrPropositon(), //
RegexLeaf.spaceOneOrMore(), //
- sentence1.complementii.toRegex("1"), //
- RegexLeaf.spaceOneOrMore(), //
- new RegexLeaf("and"), //
- RegexLeaf.spaceOneOrMore(), //
+ sentence1.getComplement().toRegex("1"), //
+ SENTENCE_SEPARATOR, //
sentence2.getVerbRegex(), //
+ sentence2.getAdverbialOrPropositon(), //
RegexLeaf.spaceOneOrMore(), //
- sentence2.complementii.toRegex("2"), //
- RegexLeaf.end());
+ sentence2.getComplement().toRegex("2"), //
+ OPTIONAL_FINAL_DOT);
}
- public final CommandExecutionResult execute(GanttDiagram project, RegexResult arg) {
- final Failable extends Object> subject = sentence1.subjectii.getMe(project, arg);
- if (subject.isFail()) {
+ public final CommandExecutionResult execute(D project, RegexResult arg) {
+ final Failable extends Object> subject = sentence1.getSubject().getMe(project, arg);
+ if (subject.isFail())
return CommandExecutionResult.error(subject.getError());
- }
- final Failable extends Object> complement1 = sentence1.complementii.getMe(project, arg, "1");
- if (complement1.isFail()) {
+
+ final Failable extends Object> complement1 = sentence1.getComplement().getMe(project, arg, "1");
+ if (complement1.isFail())
return CommandExecutionResult.error(complement1.getError());
- }
+
final CommandExecutionResult result1 = sentence1.execute(project, subject.get(), complement1.get());
- if (result1.isOk() == false) {
+ if (result1.isOk() == false)
return result1;
- }
- final Failable extends Object> complement2 = sentence2.complementii.getMe(project, arg, "2");
- if (complement2.isFail()) {
+
+ final Failable extends Object> complement2 = sentence2.getComplement().getMe(project, arg, "2");
+ if (complement2.isFail())
return CommandExecutionResult.error(complement2.getError());
- }
+
return sentence2.execute(project, subject.get(), complement2.get());
}
diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceAndAnd.java b/src/net/sourceforge/plantuml/project/lang/SentenceAndAnd.java
index 3385842fc..5e8ba2406 100644
--- a/src/net/sourceforge/plantuml/project/lang/SentenceAndAnd.java
+++ b/src/net/sourceforge/plantuml/project/lang/SentenceAndAnd.java
@@ -36,20 +36,20 @@
package net.sourceforge.plantuml.project.lang;
import net.sourceforge.plantuml.command.CommandExecutionResult;
+import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.project.Failable;
-import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
-public class SentenceAndAnd implements Sentence {
+public class SentenceAndAnd implements Sentence {
- private final SentenceSimple sentence1;
- private final SentenceSimple sentence2;
- private final SentenceSimple sentence3;
+ private final SentenceSimple sentence1;
+ private final SentenceSimple sentence2;
+ private final SentenceSimple sentence3;
- public SentenceAndAnd(SentenceSimple sentence1, SentenceSimple sentence2, SentenceSimple sentence3) {
+ public SentenceAndAnd(SentenceSimple sentence1, SentenceSimple