diff --git a/.github/labeler.yml b/.github/labeler.yml index 4f260b7ecf7..3924b988d3f 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/ci.yml b/.github/workflows/ci.yml index 1bc3effb2f7..7b685a9f5f6 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/labeler.yml b/.github/workflows/labeler.yml index 07b21837db5..2a340279efb 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 de399092598..7db154b0908 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/BUILDING.md b/BUILDING.md index 3c436bdb5bb..be2856729bd 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 94a914390d9..ed53dcb1e2f 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 72fb2d76097..6b79adc3928 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 00000000000..c1266219c10 --- /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/gradle.properties b/gradle.properties index 2318ed74ada..6f86d3d815a 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.13beta3 +version = 1.2024.4beta1 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 79ebca68683..b4217ad1568 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 f57ec2fe1db..393e7a45c57 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 0c94e1a8586..5bf7756f403 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 740d97e9116..c7df0ca29bd 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 f110030e001..667667df004 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 995be47c3e3..d7e2cf55536 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/src/com/plantuml/api/cheerpj/v1/DirectDraw.java b/src/com/plantuml/api/cheerpj/v1/DirectDraw.java index 295b0cc0be7..88572fcf64c 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.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 static Object draw(String mode, String text) { 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 c8a12200e0f..e1ec34f5c4b 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.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 static Object convertToBlob(String mode, String text, String pathOut) { 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 static Object convert(String mode, String text) { 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/net/atmp/CucaDiagram.java b/src/net/atmp/CucaDiagram.java index d13c5fda384..c91cc88d63a 100644 --- a/src/net/atmp/CucaDiagram.java +++ b/src/net/atmp/CucaDiagram.java @@ -376,13 +376,13 @@ private void createFilesTxt(OutputStream os, int index, FileFormat fileFormat) t // ::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 abebc8b07c9..e45fe9f1623 100644 --- a/src/net/sourceforge/plantuml/AbstractPSystem.java +++ b/src/net/sourceforge/plantuml/AbstractPSystem.java @@ -114,14 +114,14 @@ private String getVersion() { } 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 @@ final public UmlSource getSource() { } final public long seed() { - if (source == null) + if (source == null) return 42; - + return getSource().seed(); } @@ -159,9 +159,9 @@ public void setSplitPagesVertical(int splitPagesVertical) { } 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 Display getTitleDisplay() { } @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/EmbeddedDiagram.java b/src/net/sourceforge/plantuml/EmbeddedDiagram.java index 9543cdd91da..6cdd7abed98 100644 --- a/src/net/sourceforge/plantuml/EmbeddedDiagram.java +++ b/src/net/sourceforge/plantuml/EmbeddedDiagram.java @@ -119,6 +119,9 @@ public static String getEmbeddedType(CharSequence cs) { 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 2f1db45a0f4..cf810f74004 100644 --- a/src/net/sourceforge/plantuml/Option.java +++ b/src/net/sourceforge/plantuml/Option.java @@ -112,6 +112,9 @@ public 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 @@ else if (nb.matches("\\d+")) } 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/PSystemBuilder.java b/src/net/sourceforge/plantuml/PSystemBuilder.java index e1e2a3e7b6f..40bde6ee610 100644 --- a/src/net/sourceforge/plantuml/PSystemBuilder.java +++ b/src/net/sourceforge/plantuml/PSystemBuilder.java @@ -48,6 +48,7 @@ import net.sourceforge.plantuml.api.PSystemFactory; import net.sourceforge.plantuml.board.BoardDiagramFactory; import net.sourceforge.plantuml.bpm.BpmDiagramFactory; +import net.sourceforge.plantuml.chronology.ChronologyDiagramFactory; import net.sourceforge.plantuml.classdiagram.ClassDiagramFactory; import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.core.DiagramType; @@ -252,6 +253,7 @@ final public Diagram createPSystem(List source, List\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREOTYPE"), // ColorParser.exp2(), // RegexLeaf.spaceZeroOrMore(), // UrlBuilder.OPTIONAL, // @@ -105,9 +104,7 @@ private static IRegex getRegexConcat() { 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 4e008bac800..75d2551e1d0 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.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 @@ static IRegex getRegexConcat() { 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 488cff81b19..cef3f075344 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.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 @@ private static IRegex getRegexConcat() { 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 @@ protected CommandExecutionResult executeArg(ActivityDiagram diagram, LineLocatio 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 009bed4dcd1..281e6c6ce5c 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java @@ -40,7 +40,6 @@ 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 @@ private LinkRendering nextLinkRenderer() { 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 @@ protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormat } @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 CommandExecutionResult endSwitch() { 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 CommandExecutionResult backward(Display label, BoxStyle boxStyle, LinkRen 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 CommandExecutionResult backward(Display label, BoxStyle boxStyle, LinkRen 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 0a25a1dc95a..35270db4d6e 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.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 boolean containsBreak() { } 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 23ddbae2377..49e136308c3 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.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.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 boolean containsBreak() { } 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 Ftile createFtile(FtileFactory factory) { 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 boolean swithToElse2(LinkRendering whenElse, LinkRendering nextLinkRender 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 boolean elseIf(LinkRendering inlabel, Display test, LinkRendering whenThe 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 void endif(LinkRendering nextLinkRenderer) { 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 7bec98e0de8..d8362f65617 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/InstructionList.java @@ -129,8 +129,13 @@ public Gtile createGtile(ISkinParam skinParam, StringBounder stringBounder) { @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 287b84a210a..1680f463fbc 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.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 boolean containsBreak() { 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 Ftile createFtile(FtileFactory factory) { 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 901b55ce502..d6886bd0b63 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 boolean containsBreak() { 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 InstructionSimple(Display label, LinkRendering inlinkRendering, Swimlane // ::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 Gtile createGtile(ISkinParam skinParam, StringBounder stringBounder) { @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 9ed4ddb9852..dc9efedc6df 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.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 boolean switchCase(Display labelCase, LinkRendering nextLinkRenderer) { 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 554510da793..721f882d04e 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.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 Gtile createGtile(ISkinParam skinParam, StringBounder stringBounder) { @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 boolean containsBreak() { 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 a78abd2ebfe..4a38e0c61d9 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.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; @@ -104,9 +105,7 @@ static IRegex getRegexConcat() { 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/CommandArrow3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrow3.java index 6f7f93d1842..643717928bd 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrow3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrow3.java @@ -78,9 +78,8 @@ protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocati 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 efd28fb286e..fca210ab9cf 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.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 @@ static IRegex getRegexConcat() { UrlBuilder.OPTIONAL, // ColorParser.exp4(), // new RegexLeaf("if"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREO"), // new RegexLeaf("\\("), // new RegexLeaf("TEST", "(.*?)"), // new RegexLeaf("\\)"), // @@ -85,9 +87,8 @@ protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocati 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 @@ protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocati 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 926746f8e33..331389707a7 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf4.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf4.java @@ -82,10 +82,10 @@ protected CommandExecutionResult executeArg(ActivityDiagram3 diagram, LineLocati 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 7f1b9a30d92..78f120eaafd 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIfLegacy1.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIfLegacy1.java @@ -72,7 +72,7 @@ static IRegex getRegexConcat() { 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 63132a78293..3e7dcc420fc 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.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 @@ static IRegex getRegexConcat() { 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 6289d2b608c..82170a3e869 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.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 CommandRepeat3() { 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 d2e6a70a34e..f803285e76a 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/BoxStyle.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/BoxStyle.java @@ -160,11 +160,12 @@ public static BoxStyle fromString(String style) { 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/FtileFactory.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/FtileFactory.java index 897491f1b02..f7cabc6627d 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.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 Ftile addNote(Ftile ftile, Swimlane swimlane, Collection 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 5969966cedf..b39f1ad2eb5 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.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 Ftile assembly(Ftile tile1, Ftile tile2) { @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 1d5bebdd739..0df019d31c9 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.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 Swimlanes(ISkinParam skinParam, Pragma pragma) { } protected Style getStyle() { - if (style == null) { + if (style == null) this.style = getStyleSignature().getMergedStyle(skinParam.getCurrentStyleBuilder()); - } + return style; } @@ -455,4 +456,8 @@ public MinMax getMinMax(StringBounder stringBounder) { 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 4330e476b72..92eda31feec 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.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 FtileFactoryDelegatorIf(FtileFactory factory, Pragma pragma) { @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 a289a153d26..140845b0a20 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.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 FtileFactoryDelegatorRepeat(FtileFactory factory) { @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 510a8df34ce..09e28adbc64 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.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 FtileFactoryDelegatorWhile(FtileFactory factory) { @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 fd6a1a7cb03..924829dd39a 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 @@ public Set getSwimlanes() { 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 @@ protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) { 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 @@ protected FtileGeometry calculateDimensionFtile(StringBounder stringBounder) { 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 053470efe89..90ce41f4484 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 @@ protected Ftile doStep1(Ftile middle) { 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 267511711c0..74393605709 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 Ftile assembly(Ftile tile1, Ftile tile2) { @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 266c7cb8f3c..f7fc67e1b64 100644 --- a/src/net/sourceforge/plantuml/board/BoardDiagram.java +++ b/src/net/sourceforge/plantuml/board/BoardDiagram.java @@ -73,11 +73,11 @@ public BoardDiagram(UmlSource source) { 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 2cbc3663e0b..c568879e450 100644 --- a/src/net/sourceforge/plantuml/bpm/BpmDiagram.java +++ b/src/net/sourceforge/plantuml/bpm/BpmDiagram.java @@ -194,7 +194,7 @@ public CommandExecutionResult endBranch() { } @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 00000000000..9731c3506ff --- /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 00000000000..063b908f9cb --- /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 00000000000..436232f47af --- /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 00000000000..d45338571f1 --- /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 00000000000..f34c49290f2 --- /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 00000000000..2cfb488db37 --- /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 00000000000..cd5eeb396a7 --- /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> 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 00000000000..20d877c1e42 --- /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 00000000000..fca77fb2765 --- /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 00000000000..b77f714cd48 --- /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 00000000000..297264f3b94 --- /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 00000000000..59ffb89f4d0 --- /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 7f42d13f04d..0b5c8cd7380 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.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 @@ private static IRegex getRegexConcat() { 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 2ddf84b86d1..dc171999047 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.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 @@ private static IRegex getRegexConcat() { 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/CommandCreateElementFull2.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateElementFull2.java index 906f0d877fc..cb1a677e85a 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.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 @@ private static RegexConcat getRegexConcat(Mode mode) { 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 @@ private static RegexConcat getRegexConcat(Mode mode) { 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 d4b8686b5a3..4d762c4f82d 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.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 @@ static IRegex getRegexConcat() { 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 00000000000..0f87d56ef48 --- /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 072bbd27c02..dbf5a2bb291 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 String decode(String code) throws NoPlantumlCompressionException { 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 f0b2dc7cab5..61aefd6df93 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 String decode(String code) throws NoPlantumlCompressionException { 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 67cf02b22f6..9404cd51303 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.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 @@ private static IRegex getRegexConcat() { 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 768b1a18153..f32845c7735 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.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 @@ private static IRegex getRegexConcat() { 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 6e9e9c81bb3..00a0ab64149 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.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 @@ private static IRegex getRegexConcat() { 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 d0d64c47773..934bd402055 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.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 @@ private static IRegex getRegexConcat() { )), // 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 65a763e9b33..bc89bf64a13 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.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 @@ private IRegex getRegexConcatMultiLine() { new RegexLeaf("CODE", "([%pLN_.]+)"), // RegexLeaf.spaceZeroOrMore(), // new RegexLeaf("TAGS", Stereotag.pattern() + "?"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREO"), // ColorParser.exp1(), // RegexLeaf.end() // ); @@ -91,9 +90,7 @@ private IRegex getRegexConcatSingleLine() { new RegexLeaf("CODE", "([%pLN_.]+)"), // RegexLeaf.spaceZeroOrMore(), // new RegexLeaf("TAGS", Stereotag.pattern() + "?"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), // - 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 363f8809ea6..f3d7f37ea88 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.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 @@ private IRegex getRegexConcatSingleLine(IRegex partialPattern) { 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 @@ private IRegex getRegexConcatMultiLine(IRegex partialPattern, final boolean with 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 @@ private IRegex getRegexConcatMultiLine(IRegex partialPattern, final boolean with 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 bdfac65713d..edfb8403459 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.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 @@ private RegexConcat getRegexConcatMultiLine(IRegex partialPattern, final boolean 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 @@ private RegexConcat getRegexConcatMultiLine(IRegex partialPattern, final boolean 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 ccbbfb5adce..a93e0bafe19 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.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 @@ private IRegex getRegexConcatMultiLine() { 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 @@ private IRegex getRegexConcatSingleLine() { 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 fb6a746fb0f..c5a0d4596b7 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.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.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 @@ private IRegex getRegexConcatMultiLine() { 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 @@ private IRegex getRegexConcatSingleLine() { 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 f886d749fe7..556b146da21 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.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 @@ private IRegex getRegexConcatMultiLine() { 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 @@ private IRegex getRegexConcatSingleLine() { 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 52154e96e0e..a2ceee953bb 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.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 @@ private IRegex getRegexConcatMultiLine() { 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 @@ private IRegex getRegexConcatMultiLine() { 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 @@ private IRegex getRegexConcatSingleLine() { 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 @@ private IRegex getRegexConcatSingleLine() { 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 368d0b9268e..18ce748ffdf 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 7a045e58887..1f1e7f9aea8 100644 --- a/src/net/sourceforge/plantuml/core/DiagramType.java +++ b/src/net/sourceforge/plantuml/core/DiagramType.java @@ -38,9 +38,9 @@ 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, 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, UNKNOWN; static public DiagramType getTypeFromArobaseStart(String s) { s = s.toLowerCase(); @@ -59,7 +59,8 @@ static public DiagramType getTypeFromArobaseStart(String s) { 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,6 +127,9 @@ static public DiagramType getTypeFromArobaseStart(String s) { if (StartUtils.startsWithSymbolAnd("startfiles", s)) return FILES; + if (StartUtils.startsWithSymbolAnd("startchronology", s)) + return CHRONOLOGY; + return UNKNOWN; } } diff --git a/src/net/sourceforge/plantuml/core/UmlSource.java b/src/net/sourceforge/plantuml/core/UmlSource.java index 97b5ccc7b7e..0dacdc5ef6d 100755 --- a/src/net/sourceforge/plantuml/core/UmlSource.java +++ b/src/net/sourceforge/plantuml/core/UmlSource.java @@ -158,7 +158,10 @@ public IteratorCounter2 iterator2() { // 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/decoration/symbol/USymbolAction.java b/src/net/sourceforge/plantuml/decoration/symbol/USymbolAction.java new file mode 100644 index 00000000000..7ee042799e2 --- /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 00000000000..e8bcb9315af --- /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 b2f64a4a2cf..98758878fab 100644 --- a/src/net/sourceforge/plantuml/decoration/symbol/USymbols.java +++ b/src/net/sourceforge/plantuml/decoration/symbol/USymbols.java @@ -70,6 +70,8 @@ private static USymbol record(String code, USymbol symbol) { 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 @@ else if (symbol.equalsIgnoreCase("frame")) 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 10e4f354c4d..43864b44da8 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.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 @@ private static IRegex getRegexConcat() { 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 7bc02b008af..cfa09179c01 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.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 @@ private static IRegex getRegexConcat() { 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 @@ protected CommandExecutionResult executeArg(DescriptionDiagram diagram, LineLoca 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 11cccd9bcbb..5aa5f50120a 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.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 @@ private static IRegex getRegexConcat() { color().getRegex(), // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("CODE", "([%pLN_.]+)"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexOptional( // - new RegexConcat( // - RegexLeaf.spaceOneOrMore(), // - new RegexLeaf("STEREOTYPE", "(?:\\<\\<([-\\w]+)\\>\\>)") // - )), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optionalArchimate("STEREOTYPE"), // UrlBuilder.OPTIONAL, // RegexLeaf.spaceZeroOrMore(), // ColorParser.exp1(), // @@ -108,7 +103,7 @@ protected CommandExecutionResult executeNow(AbstractEntityDiagram diagram, BlocL if (quark.getData() != null) return CommandExecutionResult.error("Already exists " + quark.getName()); - final String icon = line0.getLazzy("STEREOTYPE", 0); + final String icon = StereotypePattern.removeChevronBrackets(line0.getLazzy("STEREOTYPE", 0)); final Entity entity = diagram.reallyCreateLeaf(quark, Display.getWithNewlines(quark), LeafType.DESCRIPTION, USymbols.RECTANGLE); diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementFull.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementFull.java index 732434db24d..b4fd353ba60 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementFull.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementFull.java @@ -57,11 +57,11 @@ 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.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; @@ -69,7 +69,7 @@ public class CommandCreateElementFull extends SingleLineCommand2 { - 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 @@ private static IRegex getRegexConcat() { new RegexLeaf("CODE1", CODE_WITH_QUOTE), // new RegexConcat(// new RegexLeaf("DISPLAY2", DISPLAY), // - new RegexOptional( // - new RegexConcat( // - RegexLeaf.spaceOneOrMore(), // - new RegexLeaf("STEREOTYPE2", "(\\<\\<.+\\>\\>)")// - )), // - 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 3dc3a46658b..eeba727d17f 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.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 @@ private static RegexConcat getRegexConcat(int type) { return RegexConcat.build(CommandCreateElementMultilines.class.getName() + type, RegexLeaf.start(), // new RegexLeaf("TYPE", "(" + CommandCreateElementFull.ALL_TYPES + ")[%s]+"), // new RegexLeaf("CODE", "([%pLN_.]+)"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREO", "(\\<\\<.+\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREO"), // UrlBuilder.OPTIONAL, // RegexLeaf.spaceZeroOrMore(), // ColorParser.exp1(), // @@ -110,9 +109,7 @@ private static RegexConcat getRegexConcat(int type) { return RegexConcat.build(CommandCreateElementMultilines.class.getName() + type, RegexLeaf.start(), // new RegexLeaf("TYPE", "(" + CommandCreateElementFull.ALL_TYPES + ")[%s]+"), // new RegexLeaf("CODE", "([%pLN_.]+)"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREO", "(\\<\\<.+\\>\\>)?"), // - 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 b607964ebfe..bbc59b1248e 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.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 @@ static IRegex getRegexConcat() { // 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 92a2e931a91..bbe8fc65c54 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.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 CommandPackageWithUSymbol() { private static IRegex getRegexConcat() { return RegexConcat.build(CommandPackageWithUSymbol.class.getName(), RegexLeaf.start(), // new RegexLeaf("SYMBOL", - "(package|rectangle|hexagon|node|artifact|folder|file|frame|cloud|database|storage|component|card|queue|stack)"), // + "(package|rectangle|hexagon|node|artifact|folder|file|frame|cloud|action|process|database|storage|component|card|queue|stack)"), // RegexLeaf.spaceOneOrMore(), // new RegexOr(// new RegexConcat( // @@ -115,9 +116,7 @@ private static IRegex getRegexConcat() { ), // 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/dot/GraphvizUtils.java b/src/net/sourceforge/plantuml/dot/GraphvizUtils.java index 803023cbc53..23261f328b2 100644 --- a/src/net/sourceforge/plantuml/dot/GraphvizUtils.java +++ b/src/net/sourceforge/plantuml/dot/GraphvizUtils.java @@ -197,7 +197,7 @@ public static int retrieveVersion(String s) { 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 8a58e7b25b7..706bb5f0a36 100644 --- a/src/net/sourceforge/plantuml/dot/GraphvizVersionFinder.java +++ b/src/net/sourceforge/plantuml/dot/GraphvizVersionFinder.java @@ -73,7 +73,7 @@ public GraphvizVersionFinder(File dotExe) { 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 00000000000..23a046faf51 --- /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 00000000000..60927fa4c49 --- /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 9604c7f74a0..ccf0e1649d3 100644 --- a/src/net/sourceforge/plantuml/ebnf/PSystemEbnf.java +++ b/src/net/sourceforge/plantuml/ebnf/PSystemEbnf.java @@ -97,11 +97,11 @@ public TextBlock getUDrawable(ISkinParam skinParam) { @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/filesdiagram/FEntry.java b/src/net/sourceforge/plantuml/filesdiagram/FEntry.java index 8364e560d38..c48785d3946 100644 --- a/src/net/sourceforge/plantuml/filesdiagram/FEntry.java +++ b/src/net/sourceforge/plantuml/filesdiagram/FEntry.java @@ -60,47 +60,48 @@ 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 Iterator iterator() { return Collections.unmodifiableCollection(children).iterator(); } + public FEntry getParent() { + return parent; + } + public String getName() { return name; } @@ -132,14 +137,15 @@ public UGraphic drawAndMove(UGraphic ug, FontConfiguration fontConfiguration, IS 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.create7(fontConfiguration, HorizontalAlignment.LEFT, skinParam, CreoleMode.NO_CREOLE); + 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 b5142b7c046..891ad894054 100644 --- a/src/net/sourceforge/plantuml/filesdiagram/FilesDiagram.java +++ b/src/net/sourceforge/plantuml/filesdiagram/FilesDiagram.java @@ -89,11 +89,11 @@ public DiagramDescription getDescription() { 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 592a779a0d9..a90e78caf49 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 void drawU(UGraphic ug) { } 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/flowdiagram/FlowDiagram.java b/src/net/sourceforge/plantuml/flowdiagram/FlowDiagram.java index 7d4b216381b..5b4b4b125c8 100644 --- a/src/net/sourceforge/plantuml/flowdiagram/FlowDiagram.java +++ b/src/net/sourceforge/plantuml/flowdiagram/FlowDiagram.java @@ -230,7 +230,7 @@ public ClockwiseTopRightBottomLeft getDefaultMargins() { } @Override - protected TextBlock getTextBlock() { + protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) { return this; } diff --git a/src/net/sourceforge/plantuml/gitlog/GitDiagram.java b/src/net/sourceforge/plantuml/gitlog/GitDiagram.java index b355612cfe5..f1ad5fd1ecc 100644 --- a/src/net/sourceforge/plantuml/gitlog/GitDiagram.java +++ b/src/net/sourceforge/plantuml/gitlog/GitDiagram.java @@ -68,7 +68,7 @@ public DiagramDescription getDescription() { 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 @@ private void drawInternal(UGraphic ug) { } @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 36962e0a506..cc7322dbb8d 100644 --- a/src/net/sourceforge/plantuml/help/Help.java +++ b/src/net/sourceforge/plantuml/help/Help.java @@ -96,7 +96,7 @@ public ClockwiseTopRightBottomLeft getDefaultMargins() { } @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 7aabbed272d..cdc6eb4944f 100644 --- a/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java +++ b/src/net/sourceforge/plantuml/jsondiagram/JsonDiagram.java @@ -94,7 +94,7 @@ public DiagramDescription getDescription() { 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 @@ private void drawInternal(UGraphic ug) { } @Override - protected TextBlock getTextBlock() { + protected TextBlock getTextMainBlock(final FileFormatOption fileFormatOption) { return new AbstractTextBlock() { public void drawU(UGraphic ug) { @@ -121,7 +121,7 @@ public void drawU(UGraphic ug) { } 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/creole/atom/AtomTable.java b/src/net/sourceforge/plantuml/klimt/creole/atom/AtomTable.java index 9e32d2a7a2f..d49fe62be63 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 String toString() { private final List lines = new ArrayList<>(); private final Map positions = new HashMap(); private final HColor lineColor; + private Class lastCaller; public AtomTable(HColor lineColor) { this.lineColor = lineColor; @@ -110,14 +111,14 @@ public void drawU(UGraphic ug) { .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 void drawU(UGraphic ug) { 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 void drawU(UGraphic ug) { } 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 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 @@ private void initMap(StringBounder stringBounder) { 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 @@ private double getColWidth(int col) { 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 @@ private double getLineHeight(int line) { 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 @@ private double getLineHeight(int line) { } 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/drawing/g2d/ExtendedGeneralPath.java b/src/net/sourceforge/plantuml/klimt/drawing/g2d/ExtendedGeneralPath.java index 37bfe9b7be5..1ff88279ba6 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 c13d9b5a747..be1e8f4661c 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 static String getMetadataHex(String comment) { 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 938007efbc1..6968ba1ed24 100644 --- a/src/net/sourceforge/plantuml/klimt/shape/UText.java +++ b/src/net/sourceforge/plantuml/klimt/shape/UText.java @@ -38,6 +38,7 @@ 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 final int getOrientation() { 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 b23c5610dd2..ec49bdf7d2d 100644 --- a/src/net/sourceforge/plantuml/klimt/sprite/ListSpriteDiagram.java +++ b/src/net/sourceforge/plantuml/klimt/sprite/ListSpriteDiagram.java @@ -79,11 +79,11 @@ public ImageBuilder createImageBuilder(FileFormatOption fileFormatOption) throws 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 f637002ea99..74c0f7ec5bb 100644 --- a/src/net/sourceforge/plantuml/klimt/sprite/StdlibDiagram.java +++ b/src/net/sourceforge/plantuml/klimt/sprite/StdlibDiagram.java @@ -91,11 +91,11 @@ public ImageBuilder createImageBuilder(FileFormatOption fileFormatOption) throws 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/mindmap/MindMapDiagram.java b/src/net/sourceforge/plantuml/mindmap/MindMapDiagram.java index d1981b8331c..975e3d791c4 100644 --- a/src/net/sourceforge/plantuml/mindmap/MindMapDiagram.java +++ b/src/net/sourceforge/plantuml/mindmap/MindMapDiagram.java @@ -83,11 +83,11 @@ public MindMapDiagram(UmlSource source) { 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/nwdiag/NwDiagram.java b/src/net/sourceforge/plantuml/nwdiag/NwDiagram.java index 6bc30d64ed9..6f90745469e 100644 --- a/src/net/sourceforge/plantuml/nwdiag/NwDiagram.java +++ b/src/net/sourceforge/plantuml/nwdiag/NwDiagram.java @@ -331,11 +331,11 @@ private Map toSet(String definition) { 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) { drawMe(ug); diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java index 403e67b2100..3c5d4ded534 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java @@ -52,6 +52,7 @@ 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 @@ private static IRegex getRegexConcat() { new RegexLeaf("TYPE", "object"), // 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(), RegexLeaf.end()); diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java index ec7457a56fd..de720979104 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.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 @@ private static IRegex getRegexConcat() { new RegexLeaf("TYPE", "object"), // 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/CommandCreateJson.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateJson.java index 94f3c4c1364..ad217dd0921 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.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 @@ private static IRegex getRegexConcat() { 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 fbdc4aa76d2..b185f30aa6e 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.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 @@ private static IRegex getRegexConcat() { 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/CommandCreateMap.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateMap.java index 8e2cbe564fd..939c14edff4 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.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 @@ private static IRegex getRegexConcat() { 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/preproc/Stdlib.java b/src/net/sourceforge/plantuml/preproc/Stdlib.java index 43b00edeacd..2c4863e153b 100644 --- a/src/net/sourceforge/plantuml/preproc/Stdlib.java +++ b/src/net/sourceforge/plantuml/preproc/Stdlib.java @@ -332,6 +332,9 @@ public static void extractStdLib() throws IOException { private 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) diff --git a/src/net/sourceforge/plantuml/project/GanttDiagram.java b/src/net/sourceforge/plantuml/project/GanttDiagram.java index 6314bdc33fd..44e2bb2e6d4 100644 --- a/src/net/sourceforge/plantuml/project/GanttDiagram.java +++ b/src/net/sourceforge/plantuml/project/GanttDiagram.java @@ -51,7 +51,6 @@ 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; @@ -162,7 +161,7 @@ public CommandExecutionResult changeLanguage(String lang) { } public DiagramDescription getDescription() { - return new DiagramDescription("(Project)"); + return new DiagramDescription("(Gantt)"); } public void setWeekNumberStrategy(DayOfWeek firstDayOfWeek, int minimalDaysInFirstWeek) { @@ -180,8 +179,7 @@ public final int getDpi(FileFormatOption fileFormatOption) { @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) { @@ -220,13 +218,8 @@ public String checkFinalError() { } @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); - } - - private TextBlock getTextBlock(StringBounder stringBounder) { if (printStart == null) { initMinMax(); } else { @@ -314,15 +307,15 @@ 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); + return new TimeHeaderDaily(stringBounder, thParam(), nameDays, printStart); else if (printScale == PrintScale.WEEKLY) - return new TimeHeaderWeekly(stringBounder, thParam(), weekNumberStrategy, withCalendarDate); + return new TimeHeaderWeekly(stringBounder, thParam(), weekNumberStrategy, withCalendarDate, printStart); else if (printScale == PrintScale.MONTHLY) - return new TimeHeaderMonthly(stringBounder, thParam()); + return new TimeHeaderMonthly(stringBounder, thParam(), printStart); else if (printScale == PrintScale.QUARTERLY) - return new TimeHeaderQuarterly(stringBounder, thParam()); + return new TimeHeaderQuarterly(stringBounder, thParam(), printStart); else if (printScale == PrintScale.YEARLY) - return new TimeHeaderYearly(stringBounder, thParam()); + return new TimeHeaderYearly(stringBounder, thParam(), printStart); else throw new IllegalStateException(); @@ -450,13 +443,12 @@ private void initTaskAndResourceDraws(TimeScale timeScale, double headerHeight, } 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; diff --git a/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java b/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java index eb7d662d3f9..ceb183bcbce 100644 --- a/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java +++ b/src/net/sourceforge/plantuml/project/GanttDiagramFactory.java @@ -79,8 +79,8 @@ 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); } @@ -120,28 +120,28 @@ protected void initCommandsList(List cmds) { } 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/TimeHeaderParameters.java b/src/net/sourceforge/plantuml/project/TimeHeaderParameters.java index 14cab9795c4..c140797ac65 100644 --- a/src/net/sourceforge/plantuml/project/TimeHeaderParameters.java +++ b/src/net/sourceforge/plantuml/project/TimeHeaderParameters.java @@ -37,6 +37,7 @@ import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Set; import net.sourceforge.plantuml.klimt.UStroke; @@ -70,7 +71,7 @@ public TimeHeaderParameters(Map colorDays, double scale, Day min, D this.scale = scale; this.min = min; this.max = max; - this.colorSet = colorSet; + this.colorSet = Objects.requireNonNull(colorSet); this.ganttStyle = ganttStyle; this.locale = locale; this.openClose = openClose; diff --git a/src/net/sourceforge/plantuml/project/command/CommandColorTask.java b/src/net/sourceforge/plantuml/project/command/CommandColorTask.java index 57f5e58c060..6c55833847c 100644 --- a/src/net/sourceforge/plantuml/project/command/CommandColorTask.java +++ b/src/net/sourceforge/plantuml/project/command/CommandColorTask.java @@ -59,7 +59,8 @@ static IRegex getRegexConcat() { 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 43697e905b6..36ce4504c94 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.utils.LineLocation; public class CommandFootbox extends SingleLineCommand2 { - // ::remove folder when __HAXE__ + // ::remove folder when __HAXE__ public CommandFootbox() { super(getRegexConcat()); @@ -55,7 +55,8 @@ static IRegex getRegexConcat() { 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 1c1c55a30c5..0929fd2a85c 100644 --- a/src/net/sourceforge/plantuml/project/command/CommandGanttArrow.java +++ b/src/net/sourceforge/plantuml/project/command/CommandGanttArrow.java @@ -63,7 +63,8 @@ static IRegex getRegexConcat() { 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 acfa8431012..08e48fa3c05 100644 --- a/src/net/sourceforge/plantuml/project/command/CommandHideResourceFootbox.java +++ b/src/net/sourceforge/plantuml/project/command/CommandHideResourceFootbox.java @@ -57,7 +57,7 @@ static IRegex getRegexConcat() { 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 e343e3461ee..e386dee8caa 100644 --- a/src/net/sourceforge/plantuml/project/command/CommandHideResourceName.java +++ b/src/net/sourceforge/plantuml/project/command/CommandHideResourceName.java @@ -57,7 +57,7 @@ static IRegex getRegexConcat() { 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 ff2d1278933..949f12e6493 100644 --- a/src/net/sourceforge/plantuml/project/command/CommandLabelOnColumn.java +++ b/src/net/sourceforge/plantuml/project/command/CommandLabelOnColumn.java @@ -70,7 +70,8 @@ static IRegex getRegexConcat() { 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 cae28078de1..a8532b63d43 100644 --- a/src/net/sourceforge/plantuml/project/command/CommandLanguage.java +++ b/src/net/sourceforge/plantuml/project/command/CommandLanguage.java @@ -55,7 +55,7 @@ static IRegex getRegexConcat() { 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 f13460e0919..5c0d1a8a51b 100644 --- a/src/net/sourceforge/plantuml/project/command/CommandPrintBetween.java +++ b/src/net/sourceforge/plantuml/project/command/CommandPrintBetween.java @@ -66,7 +66,7 @@ static IRegex getRegexConcat() { 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 c82a9c02701..84b1a6edb0d 100644 --- a/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java +++ b/src/net/sourceforge/plantuml/project/command/CommandPrintScale.java @@ -77,7 +77,7 @@ static IRegex getRegexConcat() { 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 index aeec499cd1f..794c9145599 100644 --- a/src/net/sourceforge/plantuml/project/command/CommandTaskCompleteDefault.java +++ b/src/net/sourceforge/plantuml/project/command/CommandTaskCompleteDefault.java @@ -64,7 +64,6 @@ static IRegex getRegexConcat() { RegexLeaf.spaceOneOrMore(), // new RegexLeaf("VALUE", "(\\d+)"), // new RegexLeaf(".*"), // - RegexLeaf.spaceZeroOrMore(), // RegexLeaf.end()); } diff --git a/src/net/sourceforge/plantuml/project/command/NaturalCommand.java b/src/net/sourceforge/plantuml/project/command/NaturalCommand.java index 2da5d379299..88511e1316d 100644 --- a/src/net/sourceforge/plantuml/project/command/NaturalCommand.java +++ b/src/net/sourceforge/plantuml/project/command/NaturalCommand.java @@ -37,27 +37,27 @@ 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 549e2c11fe9..69d385016f1 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 { @@ -44,6 +45,7 @@ public abstract class AbstractTask implements Task { private Task row; private String displayString; + private Stereotype stereotype; protected AbstractTask(StyleBuilder styleBuilder, TaskCode code) { this.styleBuilder = styleBuilder; @@ -80,5 +82,16 @@ public void setDisplay(String displayString) { 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/Task.java b/src/net/sourceforge/plantuml/project/core/Task.java index 46727487508..b6b2bc351a0 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.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; @@ -85,4 +86,8 @@ public interface Task extends Moment { public String getDisplayString(); + public Stereotype getStereotype(); + + public void setStereotype(Stereotype stereotype); + } diff --git a/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java b/src/net/sourceforge/plantuml/project/draw/AbstractTaskDraw.java index 70c21a71804..7d501e98e6d 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.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 @@ final public void setColorsAndCompletion(CenterBorderColor colors, int completio 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 AbstractTaskDraw(TimeScale timeScale, Real y, String prettyDisplay, Day s 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/TaskDrawDiamond.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawDiamond.java index df3a3854b96..260579d103e 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.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); } diff --git a/src/net/sourceforge/plantuml/project/draw/TaskDrawGroup.java b/src/net/sourceforge/plantuml/project/draw/TaskDrawGroup.java index 88ff50d6022..346182887e7 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.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 @@ protected TextBlock getTitle() { } @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 cf3cb4cab17..7d8d9a1aeec 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.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; @@ -162,8 +163,9 @@ private boolean isThereRightArrow() { } @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) { @@ -202,7 +204,7 @@ private Opale getOpaleNote() { 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); diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java index 6d5a550bb18..039180af5bd 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderDaily.java @@ -96,7 +96,7 @@ public double getFullHeaderHeight(StringBounder stringBounder) { private final Map nameDays; public TimeHeaderDaily(StringBounder stringBounder, TimeHeaderParameters thParam, Map nameDays, - Day printStart, Day printEnd) { + Day printStart) { super(thParam, new TimeScaleDaily(thParam.getCellWidth(stringBounder), thParam.getStartingDay(), thParam.getScale(), printStart)); this.nameDays = nameDays; diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java index 81e619c869c..f784519cd4f 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderMonthly.java @@ -67,9 +67,9 @@ public double getFullHeaderHeight(StringBounder stringBounder) { return getTimeHeaderHeight(stringBounder); } - public TimeHeaderMonthly(StringBounder stringBounder, TimeHeaderParameters thParam) { + public TimeHeaderMonthly(StringBounder stringBounder, TimeHeaderParameters thParam, Day printStart) { super(thParam, new TimeScaleCompressed(thParam.getCellWidth(stringBounder), thParam.getStartingDay(), - thParam.getScale())); + thParam.getScale(), printStart)); } @Override diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java index 87e202be02f..daa68bcfe2e 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderQuarterly.java @@ -67,9 +67,9 @@ public double getFullHeaderHeight(StringBounder stringBounder) { return getTimeHeaderHeight(stringBounder); } - public TimeHeaderQuarterly(StringBounder stringBounder, TimeHeaderParameters thParam) { + public TimeHeaderQuarterly(StringBounder stringBounder, TimeHeaderParameters thParam, Day printStart) { super(thParam, new TimeScaleCompressed(thParam.getCellWidth(stringBounder), thParam.getStartingDay(), - thParam.getScale())); + thParam.getScale(), printStart)); } @Override diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java index 65685fe3698..a837c08f113 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderSimple.java @@ -86,7 +86,8 @@ public TimeHeaderSimple(StringBounder stringBounder, TimeHeaderParameters thPara private void drawSmallVlinesDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) { ug = ug.apply(getLineColor()); - final ULine vbar = ULine.vline(totalHeightWithoutFooter); + 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); @@ -120,15 +121,17 @@ private void drawSimpleDayCounter(UGraphic ug, TimeScale timeScale) { @Override public void drawTimeHeader(UGraphic ug, double totalHeightWithoutFooter) { - // drawTextsBackground(ug.apply(UTranslate.dy(-3)), totalHeightWithoutFooter + 6); + // drawTextsBackground(ug.apply(UTranslate.dy(-3)), totalHeightWithoutFooter + + // 6); final double xmin = getTimeScale().getStartingPosition(getMin()); final double xmax = getTimeScale().getEndingPosition(getMax()); - drawSmallVlinesDay(ug, getTimeScale(), totalHeightWithoutFooter + 2); + 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)); + // ug.apply(UTranslate.dy(getFullHeaderHeight(ug.getStringBounder()) - + // 3)).draw(ULine.hline(xmax - xmin)); } @@ -137,7 +140,8 @@ 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); + // drawSmallVlinesDay(ug, getTimeScale(), + // getTimeFooterHeight(ug.getStringBounder()) - 3); drawSimpleDayCounter(ug, getTimeScale()); // ug.apply(getLineColor()).draw(ULine.hline(xmax - xmin)); } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java index c2cbc0d9612..af6fbaffd5e 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderWeekly.java @@ -76,9 +76,9 @@ private double getH1(StringBounder stringBounder) { } public TimeHeaderWeekly(StringBounder stringBounder, TimeHeaderParameters thParam, - WeekNumberStrategy weekNumberStrategy, boolean withCalendarDate) { + WeekNumberStrategy weekNumberStrategy, boolean withCalendarDate, Day printStart) { super(thParam, new TimeScaleCompressed(thParam.getCellWidth(stringBounder), thParam.getStartingDay(), - thParam.getScale())); + thParam.getScale(), printStart)); this.weekNumberStrategy = weekNumberStrategy; this.withCalendarDate = withCalendarDate; } diff --git a/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java b/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java index 47893ed51b4..fddee9e9aad 100644 --- a/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java +++ b/src/net/sourceforge/plantuml/project/draw/TimeHeaderYearly.java @@ -35,7 +35,6 @@ */ 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; @@ -65,9 +64,9 @@ public double getFullHeaderHeight(StringBounder stringBounder) { return getTimeHeaderHeight(stringBounder); } - public TimeHeaderYearly(StringBounder stringBounder, TimeHeaderParameters thParam) { + public TimeHeaderYearly(StringBounder stringBounder, TimeHeaderParameters thParam, Day printStart) { super(thParam, new TimeScaleCompressed(thParam.getCellWidth(stringBounder), thParam.getStartingDay(), - thParam.getScale())); + thParam.getScale(), printStart)); } @Override diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementAnything.java b/src/net/sourceforge/plantuml/project/lang/ComplementAnything.java index 787e7e55a8f..5a9bc3c4534 100644 --- a/src/net/sourceforge/plantuml/project/lang/ComplementAnything.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementAnything.java @@ -41,7 +41,7 @@ import net.sourceforge.plantuml.regex.RegexLeaf; import net.sourceforge.plantuml.regex.RegexResult; -public class ComplementAnything implements Something { +public class ComplementAnything implements Something { public IRegex toRegex(String suffix) { return new RegexLeaf("ANYTHING" + suffix, "(.*?)"); diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java b/src/net/sourceforge/plantuml/project/lang/ComplementBeforeOrAfterOrAtTaskStartOrEnd.java index fc61a7aad96..cd8a2b41123 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.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 a3ef45a6e21..c2c2e449d80 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.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 5931f8e3754..0ffcf0b1ea3 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.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 032af9d04fe..2b70fd2462e 100644 --- a/src/net/sourceforge/plantuml/project/lang/ComplementDate.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementDate.java @@ -44,7 +44,7 @@ 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; diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementDates.java b/src/net/sourceforge/plantuml/project/lang/ComplementDates.java index a48a91aed9e..253f3e0cf3f 100644 --- a/src/net/sourceforge/plantuml/project/lang/ComplementDates.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementDates.java @@ -45,7 +45,7 @@ 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)); diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementDayOfWeek.java b/src/net/sourceforge/plantuml/project/lang/ComplementDayOfWeek.java index 0bf87b3fed6..e0cb00362ed 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.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 52b5a3c96b4..d8ea753feee 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.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 e20149962ff..ac0eec32b7a 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.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 05fa7851e2f..a5e6cc3aa02 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.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 1a31c1c37cb..d68fefc74e3 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.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 05d964cd630..ae9d67cdd52 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.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 901aef1bae3..d8f05d7aa84 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.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 c2090468d03..a72a4802770 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.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 03f1ebad2de..b5954879537 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.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 index aae8a1e631d..79759fcb9c2 100644 --- a/src/net/sourceforge/plantuml/project/lang/ComplementTask.java +++ b/src/net/sourceforge/plantuml/project/lang/ComplementTask.java @@ -42,7 +42,7 @@ import net.sourceforge.plantuml.regex.RegexLeaf; import net.sourceforge.plantuml.regex.RegexResult; -public class ComplementTask implements Something { +public class ComplementTask implements Something { public IRegex toRegex(String suffix) { return new RegexLeaf("COMPLEMENT" + suffix, "\\[([^\\[\\]]+?)\\]"); diff --git a/src/net/sourceforge/plantuml/project/lang/ComplementUrl.java b/src/net/sourceforge/plantuml/project/lang/ComplementUrl.java index c7499f38a35..5d2c44c9d5d 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.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 688e44b4498..b0364595582 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.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/PairOfSomething.java b/src/net/sourceforge/plantuml/project/lang/PairOfSomething.java index ceb3e679b24..9c2a023647a 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 getMe(GanttDiagram system, RegexResult arg, String suffix) { - final Failable r1 = complement1.getMe(system, arg, "A" + suffix); - final Failable r2 = complement2.getMe(system, arg, "B" + suffix); + public Failable getMe(D diagram, RegexResult arg, String suffix) { + final Failable r1 = complement1.getMe(diagram, arg, "A" + suffix); + final Failable 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 eaed4f5a54d..769157d28c7 100644 --- a/src/net/sourceforge/plantuml/project/lang/Sentence.java +++ b/src/net/sourceforge/plantuml/project/lang/Sentence.java @@ -36,19 +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 3929c6a7ae8..898a476fce9 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; } @@ -70,7 +70,7 @@ public IRegex toRegex() { OPTIONAL_FINAL_DOT); } - public final CommandExecutionResult execute(GanttDiagram project, RegexResult arg) { + public final CommandExecutionResult execute(D project, RegexResult arg) { final Failable subject = sentence1.getSubject().getMe(project, arg); if (subject.isFail()) return CommandExecutionResult.error(subject.getError()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceAndAnd.java b/src/net/sourceforge/plantuml/project/lang/SentenceAndAnd.java index 27a9d4ca7a3..5e8ba2406e9 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 sentence2, SentenceSimple sentence3) { this.sentence1 = sentence1; this.sentence2 = sentence2; this.sentence3 = sentence3; @@ -77,7 +77,7 @@ public IRegex toRegex() { OPTIONAL_FINAL_DOT); } - public final CommandExecutionResult execute(GanttDiagram project, RegexResult arg) { + public final CommandExecutionResult execute(D project, RegexResult arg) { final Failable subject = sentence1.getSubject().getMe(project, arg); if (subject.isFail()) return CommandExecutionResult.error(subject.getError()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceDisplayOnSameRowAs.java b/src/net/sourceforge/plantuml/project/lang/SentenceDisplayOnSameRowAs.java index 4e4c955cb84..9881a9a6b08 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceDisplayOnSameRowAs.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceDisplayOnSameRowAs.java @@ -39,7 +39,7 @@ import net.sourceforge.plantuml.project.GanttDiagram; import net.sourceforge.plantuml.project.core.Task; -public class SentenceDisplayOnSameRowAs extends SentenceSimple { +public class SentenceDisplayOnSameRowAs extends SentenceSimple { public SentenceDisplayOnSameRowAs() { super(SubjectTask.ME, Verbs.displayOnSameRowAs, new ComplementNamed()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceEnds.java b/src/net/sourceforge/plantuml/project/lang/SentenceEnds.java index 1fad6f20e25..8cccba70f5e 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceEnds.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceEnds.java @@ -42,7 +42,7 @@ import net.sourceforge.plantuml.project.core.TaskAttribute; import net.sourceforge.plantuml.project.core.TaskInstant; -public class SentenceEnds extends SentenceSimple { +public class SentenceEnds extends SentenceSimple { public SentenceEnds() { super(SubjectTask.ME, Verbs.ends, new ComplementBeforeOrAfterOrAtTaskStartOrEnd()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceHappens.java b/src/net/sourceforge/plantuml/project/lang/SentenceHappens.java index f046ef8e22c..7d408b59c61 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceHappens.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceHappens.java @@ -41,7 +41,7 @@ import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.core.TaskInstant; -public class SentenceHappens extends SentenceSimple { +public class SentenceHappens extends SentenceSimple { public SentenceHappens() { super(SubjectTask.ME, Verbs.happens, Words.zeroOrMore(Words.THE, Words.ON, Words.AT), diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceHappensDate.java b/src/net/sourceforge/plantuml/project/lang/SentenceHappensDate.java index afb8d886fc9..8dd8ceac8f4 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceHappensDate.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceHappensDate.java @@ -41,7 +41,7 @@ import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.time.Day; -public class SentenceHappensDate extends SentenceSimple { +public class SentenceHappensDate extends SentenceSimple { public SentenceHappensDate() { super(SubjectTask.ME, Verbs.happens, Words.zeroOrMore(Words.THE, Words.ON, Words.AT), ComplementDate.any()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceIsColored.java b/src/net/sourceforge/plantuml/project/lang/SentenceIsColored.java index 67b576d845c..8787d747283 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceIsColored.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceIsColored.java @@ -39,7 +39,7 @@ import net.sourceforge.plantuml.project.GanttDiagram; import net.sourceforge.plantuml.project.core.Task; -public class SentenceIsColored extends SentenceSimple { +public class SentenceIsColored extends SentenceSimple { public SentenceIsColored() { super(SubjectTask.ME, Verbs.isColored, new ComplementInColors()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceIsColoredForCompletion.java b/src/net/sourceforge/plantuml/project/lang/SentenceIsColoredForCompletion.java index c07c2bd8a84..502b2e370c8 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceIsColoredForCompletion.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceIsColoredForCompletion.java @@ -39,7 +39,7 @@ import net.sourceforge.plantuml.project.GanttDiagram; import net.sourceforge.plantuml.project.core.Task; -public class SentenceIsColoredForCompletion extends SentenceSimple { +public class SentenceIsColoredForCompletion extends SentenceSimple { public SentenceIsColoredForCompletion() { super(SubjectTask.ME, Verbs.isColored, Words.exactly(Words.FOR, Words.COMPLETION), diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceIsDeleted.java b/src/net/sourceforge/plantuml/project/lang/SentenceIsDeleted.java index 47079388200..6e9840f497c 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceIsDeleted.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceIsDeleted.java @@ -39,7 +39,7 @@ import net.sourceforge.plantuml.project.GanttDiagram; import net.sourceforge.plantuml.project.core.Task; -public class SentenceIsDeleted extends SentenceSimple { +public class SentenceIsDeleted extends SentenceSimple { public SentenceIsDeleted() { super(SubjectTask.ME, Verbs.isDeleted, new ComplementEmpty()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceIsDisplayedAs.java b/src/net/sourceforge/plantuml/project/lang/SentenceIsDisplayedAs.java index 78de0f2b3ec..9cd47e52cc0 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceIsDisplayedAs.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceIsDisplayedAs.java @@ -39,7 +39,7 @@ import net.sourceforge.plantuml.project.GanttDiagram; import net.sourceforge.plantuml.project.core.Task; -public class SentenceIsDisplayedAs extends SentenceSimple { +public class SentenceIsDisplayedAs extends SentenceSimple { public SentenceIsDisplayedAs() { super(SubjectTask.ME, Verbs.isDisplayedAs, new ComplementAnything()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceIsForTask.java b/src/net/sourceforge/plantuml/project/lang/SentenceIsForTask.java index f69a156e7f3..2744814c7e0 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceIsForTask.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceIsForTask.java @@ -40,7 +40,7 @@ import net.sourceforge.plantuml.project.GanttDiagram; import net.sourceforge.plantuml.project.core.Task; -public class SentenceIsForTask extends SentenceSimple { +public class SentenceIsForTask extends SentenceSimple { public SentenceIsForTask() { super(SubjectTask.ME, Verbs.is, new ComplementCompleted()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceLinksTo.java b/src/net/sourceforge/plantuml/project/lang/SentenceLinksTo.java index 68aca0d685d..0901fd42722 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceLinksTo.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceLinksTo.java @@ -40,7 +40,7 @@ import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.url.Url; -public class SentenceLinksTo extends SentenceSimple { +public class SentenceLinksTo extends SentenceSimple { public SentenceLinksTo() { super(SubjectTask.ME, Verbs.linksTo, new ComplementUrl()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceOccurs.java b/src/net/sourceforge/plantuml/project/lang/SentenceOccurs.java index b307a2dc1a0..04fe2c3e3a3 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceOccurs.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceOccurs.java @@ -42,7 +42,7 @@ import net.sourceforge.plantuml.project.core.TaskAttribute; import net.sourceforge.plantuml.project.core.TaskInstant; -public class SentenceOccurs extends SentenceSimple { +public class SentenceOccurs extends SentenceSimple { public SentenceOccurs() { super(SubjectTask.ME, Verbs.occurs, new ComplementFromTo()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentencePausesDate.java b/src/net/sourceforge/plantuml/project/lang/SentencePausesDate.java index 8cf020b38e3..893a20967b1 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentencePausesDate.java +++ b/src/net/sourceforge/plantuml/project/lang/SentencePausesDate.java @@ -40,7 +40,7 @@ import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.time.Day; -public class SentencePausesDate extends SentenceSimple { +public class SentencePausesDate extends SentenceSimple { public SentencePausesDate() { super(SubjectTask.ME, Verbs.pauses, Words.zeroOrMore(Words.THE, Words.ON, Words.AT, Words.FROM), diff --git a/src/net/sourceforge/plantuml/project/lang/SentencePausesDates.java b/src/net/sourceforge/plantuml/project/lang/SentencePausesDates.java index 46d074559c9..36ac07c9a0f 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentencePausesDates.java +++ b/src/net/sourceforge/plantuml/project/lang/SentencePausesDates.java @@ -41,7 +41,7 @@ import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.time.Day; -public class SentencePausesDates extends SentenceSimple { +public class SentencePausesDates extends SentenceSimple { public SentencePausesDates() { super(SubjectTask.ME, Verbs.pauses, Words.zeroOrMore(Words.THE, Words.ON, Words.AT, Words.FROM), diff --git a/src/net/sourceforge/plantuml/project/lang/SentencePausesDayOfWeek.java b/src/net/sourceforge/plantuml/project/lang/SentencePausesDayOfWeek.java index 8edc3d2b5ee..da52bf85977 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentencePausesDayOfWeek.java +++ b/src/net/sourceforge/plantuml/project/lang/SentencePausesDayOfWeek.java @@ -40,7 +40,7 @@ import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.time.DayOfWeek; -public class SentencePausesDayOfWeek extends SentenceSimple { +public class SentencePausesDayOfWeek extends SentenceSimple { public SentencePausesDayOfWeek() { super(SubjectTask.ME, Verbs.pauses, Words.zeroOrMore(Words.THE, Words.ON, Words.AT, Words.FROM), diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceRequire.java b/src/net/sourceforge/plantuml/project/lang/SentenceRequire.java index d22d11f1bd0..d866359c98c 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceRequire.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceRequire.java @@ -40,7 +40,7 @@ import net.sourceforge.plantuml.project.Load; import net.sourceforge.plantuml.project.core.Task; -public class SentenceRequire extends SentenceSimple { +public class SentenceRequire extends SentenceSimple { public SentenceRequire() { super(SubjectTask.ME, Verbs.requires, new ComplementSeveralDays()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceSimple.java b/src/net/sourceforge/plantuml/project/lang/SentenceSimple.java index d3676929687..a82b8121efe 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceSimple.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceSimple.java @@ -36,25 +36,25 @@ 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 abstract class SentenceSimple implements Sentence { +public abstract class SentenceSimple implements Sentence { - private final Subject subject; + private final Subject subject; private final IRegex verb; private final IRegex adverbialOrPropositon; - private final Something complement; + private final Something complement; - public SentenceSimple(Subject subject, IRegex verb, Something complement) { + public SentenceSimple(Subject subject, IRegex verb, Something complement) { this(subject, verb, new RegexLeaf(""), complement); } - public SentenceSimple(Subject subject, IRegex verb, IRegex adverbialOrPropositon, Something complement) { + public SentenceSimple(Subject subject, IRegex verb, IRegex adverbialOrPropositon, Something complement) { this.subject = subject; this.verb = verb; this.adverbialOrPropositon = adverbialOrPropositon; @@ -86,7 +86,7 @@ public final IRegex toRegex() { OPTIONAL_FINAL_DOT); } - public final CommandExecutionResult execute(GanttDiagram project, RegexResult arg) { + public final CommandExecutionResult execute(D project, RegexResult arg) { final Failable currentSubject = subject.getMe(project, arg); if (currentSubject.isFail()) return CommandExecutionResult.error(currentSubject.getError()); @@ -99,7 +99,7 @@ public final CommandExecutionResult execute(GanttDiagram project, RegexResult ar } - public abstract CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement); + public abstract CommandExecutionResult execute(D project, Object subject, Object complement); public IRegex getVerbRegex() { return verb; @@ -108,15 +108,13 @@ public IRegex getVerbRegex() { protected final IRegex getAdverbialOrPropositon() { return adverbialOrPropositon; } - - protected final Subject getSubject() { + + protected final Subject getSubject() { return subject; } - protected final Something getComplement() { + protected final Something getComplement() { return complement; } - - } diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceTaskEndsAbsolute.java b/src/net/sourceforge/plantuml/project/lang/SentenceTaskEndsAbsolute.java index ea10010e9f8..57d26e3986b 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceTaskEndsAbsolute.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceTaskEndsAbsolute.java @@ -40,7 +40,7 @@ import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.time.Day; -public class SentenceTaskEndsAbsolute extends SentenceSimple { +public class SentenceTaskEndsAbsolute extends SentenceSimple { public SentenceTaskEndsAbsolute() { super(SubjectTask.ME, Verbs.ends, Words.zeroOrMore(Words.THE, Words.ON, Words.AT), ComplementDate.any()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceTaskEndsOnlyRelative.java b/src/net/sourceforge/plantuml/project/lang/SentenceTaskEndsOnlyRelative.java index 25524553f6c..0fbbd5676f5 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceTaskEndsOnlyRelative.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceTaskEndsOnlyRelative.java @@ -40,7 +40,7 @@ import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.time.Day; -public class SentenceTaskEndsOnlyRelative extends SentenceSimple { +public class SentenceTaskEndsOnlyRelative extends SentenceSimple { public SentenceTaskEndsOnlyRelative() { super(SubjectTask.ME, Verbs.ends, Words.zeroOrMore(Words.THE, Words.ON, Words.AT), diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceTaskStarts.java b/src/net/sourceforge/plantuml/project/lang/SentenceTaskStarts.java index 6ce0543d3bd..95aeb442b3d 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceTaskStarts.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceTaskStarts.java @@ -43,7 +43,7 @@ import net.sourceforge.plantuml.project.core.TaskAttribute; import net.sourceforge.plantuml.project.core.TaskInstant; -public class SentenceTaskStarts extends SentenceSimple { +public class SentenceTaskStarts extends SentenceSimple { public SentenceTaskStarts() { super(SubjectTask.ME, Verbs.starts, new ComplementBeforeOrAfterOrAtTaskStartOrEnd()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceTaskStartsAbsolute.java b/src/net/sourceforge/plantuml/project/lang/SentenceTaskStartsAbsolute.java index 3eb5b6616d1..a37db325da6 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceTaskStartsAbsolute.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceTaskStartsAbsolute.java @@ -40,7 +40,7 @@ import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.time.Day; -public class SentenceTaskStartsAbsolute extends SentenceSimple { +public class SentenceTaskStartsAbsolute extends SentenceSimple { public SentenceTaskStartsAbsolute() { super(SubjectTask.ME, Verbs.starts, Words.zeroOrMore(Words.THE, Words.ON, Words.AT), ComplementDate.any()); diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceTaskStartsOnlyRelative.java b/src/net/sourceforge/plantuml/project/lang/SentenceTaskStartsOnlyRelative.java index 80b4ded719c..223a321d4d6 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceTaskStartsOnlyRelative.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceTaskStartsOnlyRelative.java @@ -40,7 +40,7 @@ import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.time.Day; -public class SentenceTaskStartsOnlyRelative extends SentenceSimple { +public class SentenceTaskStartsOnlyRelative extends SentenceSimple { public SentenceTaskStartsOnlyRelative() { super(SubjectTask.ME, Verbs.starts, Words.zeroOrMore(Words.THE, Words.ON, Words.AT), diff --git a/src/net/sourceforge/plantuml/project/lang/SentenceTaskStartsWithColor.java b/src/net/sourceforge/plantuml/project/lang/SentenceTaskStartsWithColor.java index 2e3acc15905..a02ff614a5c 100644 --- a/src/net/sourceforge/plantuml/project/lang/SentenceTaskStartsWithColor.java +++ b/src/net/sourceforge/plantuml/project/lang/SentenceTaskStartsWithColor.java @@ -43,11 +43,11 @@ import net.sourceforge.plantuml.project.core.TaskAttribute; import net.sourceforge.plantuml.project.core.TaskInstant; -public class SentenceTaskStartsWithColor extends SentenceSimple { +public class SentenceTaskStartsWithColor extends SentenceSimple { public SentenceTaskStartsWithColor() { super(SubjectTask.ME, Verbs.starts, - new PairOfSomething(new ComplementBeforeOrAfterOrAtTaskStartOrEnd(), new ComplementWithColorLink())); + new PairOfSomething<>(new ComplementBeforeOrAfterOrAtTaskStartOrEnd(), new ComplementWithColorLink())); } @Override diff --git a/src/net/sourceforge/plantuml/project/lang/Something.java b/src/net/sourceforge/plantuml/project/lang/Something.java index 17451818801..ac005a9911b 100644 --- a/src/net/sourceforge/plantuml/project/lang/Something.java +++ b/src/net/sourceforge/plantuml/project/lang/Something.java @@ -35,15 +35,15 @@ */ 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.RegexResult; -public interface Something { +public interface Something { public IRegex toRegex(String suffix); - public Failable getMe(GanttDiagram project, RegexResult arg, String suffix); + public Failable getMe(D diagram, RegexResult arg, String suffix); } diff --git a/src/net/sourceforge/plantuml/project/lang/Subject.java b/src/net/sourceforge/plantuml/project/lang/Subject.java index 92c80670c81..f53c0f90602 100644 --- a/src/net/sourceforge/plantuml/project/lang/Subject.java +++ b/src/net/sourceforge/plantuml/project/lang/Subject.java @@ -37,17 +37,17 @@ import java.util.Collection; +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.RegexResult; -public interface Subject { +public interface Subject { - public Collection getSentences(); + public Collection> getSentences(); public IRegex toRegex(); - public Failable getMe(GanttDiagram project, RegexResult arg); + public Failable getMe(D project, RegexResult arg); } diff --git a/src/net/sourceforge/plantuml/project/lang/SubjectDayAsDate.java b/src/net/sourceforge/plantuml/project/lang/SubjectDayAsDate.java index 473218921c3..ddc48e6e10f 100644 --- a/src/net/sourceforge/plantuml/project/lang/SubjectDayAsDate.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectDayAsDate.java @@ -49,9 +49,9 @@ import net.sourceforge.plantuml.regex.RegexOr; import net.sourceforge.plantuml.regex.RegexResult; -public class SubjectDayAsDate implements Subject { +public class SubjectDayAsDate implements Subject { - public static final Subject ME = new SubjectDayAsDate(); + public static final Subject ME = new SubjectDayAsDate(); private SubjectDayAsDate() { } @@ -89,11 +89,11 @@ private Day resultE(GanttDiagram system, RegexResult arg) { throw new IllegalStateException(); } - public Collection getSentences() { + public Collection> getSentences() { return Arrays.asList(new Close(), new Open(), new InColor()); } - class Close extends SentenceSimple { + class Close extends SentenceSimple { public Close() { super(SubjectDayAsDate.this, Verbs.isOrAre, new ComplementClose()); @@ -106,7 +106,7 @@ public CommandExecutionResult execute(GanttDiagram project, Object subject, Obje } } - class Open extends SentenceSimple { + class Open extends SentenceSimple { public Open() { super(SubjectDayAsDate.this, Verbs.isOrAre, new ComplementOpen()); } @@ -118,7 +118,7 @@ public CommandExecutionResult execute(GanttDiagram project, Object subject, Obje } } - class InColor extends SentenceSimple { + class InColor extends SentenceSimple { public InColor() { super(SubjectDayAsDate.this, Verbs.isOrAre, new ComplementInColors2()); diff --git a/src/net/sourceforge/plantuml/project/lang/SubjectDayOfWeek.java b/src/net/sourceforge/plantuml/project/lang/SubjectDayOfWeek.java index a1c64377420..9b4fffd057e 100644 --- a/src/net/sourceforge/plantuml/project/lang/SubjectDayOfWeek.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectDayOfWeek.java @@ -47,9 +47,9 @@ import net.sourceforge.plantuml.regex.RegexLeaf; import net.sourceforge.plantuml.regex.RegexResult; -public class SubjectDayOfWeek implements Subject { +public class SubjectDayOfWeek implements Subject { - public static final Subject ME = new SubjectDayOfWeek(); + public static final Subject ME = new SubjectDayOfWeek(); private SubjectDayOfWeek() { } @@ -63,11 +63,11 @@ public Failable getMe(GanttDiagram project, RegexResult arg) { return Failable.ok(DayOfWeek.fromString(s)); } - public Collection getSentences() { + public Collection> getSentences() { return Arrays.asList(new AreClose(), new AreOpen(), new InColor()); } - class AreOpen extends SentenceSimple { + class AreOpen extends SentenceSimple { public AreOpen() { super(SubjectDayOfWeek.this, Verbs.are, new ComplementOpen()); } @@ -80,7 +80,7 @@ public CommandExecutionResult execute(GanttDiagram project, Object subject, Obje } } - class AreClose extends SentenceSimple { + class AreClose extends SentenceSimple { public AreClose() { super(SubjectDayOfWeek.this, Verbs.are, new ComplementClose()); @@ -95,7 +95,7 @@ public CommandExecutionResult execute(GanttDiagram project, Object subject, Obje } - class InColor extends SentenceSimple { + class InColor extends SentenceSimple { public InColor() { super(SubjectDayOfWeek.this, Verbs.isOrAre, new ComplementInColors2()); diff --git a/src/net/sourceforge/plantuml/project/lang/SubjectDaysAsDates.java b/src/net/sourceforge/plantuml/project/lang/SubjectDaysAsDates.java index 99680e27bbf..6f8955fa799 100644 --- a/src/net/sourceforge/plantuml/project/lang/SubjectDaysAsDates.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectDaysAsDates.java @@ -50,9 +50,9 @@ import net.sourceforge.plantuml.regex.RegexOr; import net.sourceforge.plantuml.regex.RegexResult; -public class SubjectDaysAsDates implements Subject { +public class SubjectDaysAsDates implements Subject { - public static final Subject ME = new SubjectDaysAsDates(); + public static final Subject ME = new SubjectDaysAsDates(); private SubjectDaysAsDates() { } @@ -136,11 +136,11 @@ private Day getDate(GanttDiagram project, RegexResult arg, String suffix) { throw new IllegalStateException(); } - public Collection getSentences() { + public Collection> getSentences() { return Arrays.asList(new Close(), new Open(), new InColor(), new Named()); } - class Close extends SentenceSimple { + class Close extends SentenceSimple { public Close() { super(SubjectDaysAsDates.this, Verbs.isOrAre, new ComplementClose()); @@ -156,7 +156,7 @@ public CommandExecutionResult execute(GanttDiagram project, Object subject, Obje } } - class Open extends SentenceSimple { + class Open extends SentenceSimple { public Open() { super(SubjectDaysAsDates.this, Verbs.isOrAre, new ComplementOpen()); @@ -173,7 +173,7 @@ public CommandExecutionResult execute(GanttDiagram project, Object subject, Obje } - class InColor extends SentenceSimple { + class InColor extends SentenceSimple { public InColor() { super(SubjectDaysAsDates.this, Verbs.isOrAre, new ComplementInColors2()); @@ -191,7 +191,7 @@ public CommandExecutionResult execute(GanttDiagram project, Object subject, Obje } - class Named extends SentenceSimple { + class Named extends SentenceSimple { public Named() { super(SubjectDaysAsDates.this, Verbs.isOrAreNamed, new ComplementNamed()); diff --git a/src/net/sourceforge/plantuml/project/lang/SubjectLinks.java b/src/net/sourceforge/plantuml/project/lang/SubjectLinks.java index c76eaec2876..164726cb6e0 100644 --- a/src/net/sourceforge/plantuml/project/lang/SubjectLinks.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectLinks.java @@ -46,7 +46,7 @@ import net.sourceforge.plantuml.regex.RegexResult; // Removed -public class SubjectLinks implements Subject { +public class SubjectLinks implements Subject { private SubjectLinks() { } @@ -59,11 +59,11 @@ public Failable getMe(GanttDiagram project, RegexResult arg) { return Failable.ok(project); } - public Collection getSentences() { + public Collection> getSentences() { return Arrays.asList(new InColor()); } - public class InColor extends SentenceSimple { + public class InColor extends SentenceSimple { public InColor() { super(SubjectLinks.this, Verbs.areColored, new ComplementInColors()); diff --git a/src/net/sourceforge/plantuml/project/lang/SubjectProject.java b/src/net/sourceforge/plantuml/project/lang/SubjectProject.java index 4f72a27484e..6bafeb2f2fd 100644 --- a/src/net/sourceforge/plantuml/project/lang/SubjectProject.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectProject.java @@ -46,9 +46,9 @@ import net.sourceforge.plantuml.regex.RegexLeaf; import net.sourceforge.plantuml.regex.RegexResult; -public class SubjectProject implements Subject { +public class SubjectProject implements Subject { - public static final Subject ME = new SubjectProject(); + public static final Subject ME = new SubjectProject(); private SubjectProject() { } @@ -61,11 +61,11 @@ public Failable getMe(GanttDiagram project, RegexResult arg) { return Failable.ok(project); } - public Collection getSentences() { + public Collection> getSentences() { return Arrays.asList(new Starts()); } - class Starts extends SentenceSimple { + class Starts extends SentenceSimple { public Starts() { super(SubjectProject.this, Verbs.starts, Words.zeroOrMore(Words.ON, Words.FOR, Words.THE, Words.AT), diff --git a/src/net/sourceforge/plantuml/project/lang/SubjectResource.java b/src/net/sourceforge/plantuml/project/lang/SubjectResource.java index d9d311e2d21..ab9ab182af6 100644 --- a/src/net/sourceforge/plantuml/project/lang/SubjectResource.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectResource.java @@ -51,9 +51,9 @@ import net.sourceforge.plantuml.regex.RegexOr; import net.sourceforge.plantuml.regex.RegexResult; -public class SubjectResource implements Subject { +public class SubjectResource implements Subject { - public static final Subject ME = new SubjectResource(); + public static final Subject ME = new SubjectResource(); private SubjectResource() { } @@ -71,7 +71,7 @@ public Failable getMe(GanttDiagram gantt, RegexResult arg) { return Failable.ok(result); } - public Collection getSentences() { + public Collection> getSentences() { return Arrays.asList(new IsOffDate(), new IsOffDates(), new IsOffDayOfWeek(), new IsOnDate(), new IsOnDates(), new IsOffBeforeDate(), new IsOffAfterDate(), new WorksOn()); } @@ -83,7 +83,7 @@ public IRegex toRegex() { ); } - public class WorksOn extends SentenceSimple { + public class WorksOn extends SentenceSimple { public WorksOn() { super(SubjectResource.this, Verbs.worksOn, new ComplementTask()); @@ -99,7 +99,7 @@ public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object } - public class IsOffBeforeDate extends SentenceSimple { + public class IsOffBeforeDate extends SentenceSimple { public IsOffBeforeDate() { super(SubjectResource.this, Verbs.isOff, @@ -116,7 +116,7 @@ public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object } - public class IsOffAfterDate extends SentenceSimple { + public class IsOffAfterDate extends SentenceSimple { public IsOffAfterDate() { super(SubjectResource.this, Verbs.isOff, @@ -133,7 +133,7 @@ public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object } - public class IsOffDate extends SentenceSimple { + public class IsOffDate extends SentenceSimple { public IsOffDate() { super(SubjectResource.this, Verbs.isOff, @@ -150,7 +150,7 @@ public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object } - public class IsOffDates extends SentenceSimple { + public class IsOffDates extends SentenceSimple { public IsOffDates() { super(SubjectResource.this, Verbs.isOff, @@ -168,7 +168,7 @@ public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object } - public class IsOffDayOfWeek extends SentenceSimple { + public class IsOffDayOfWeek extends SentenceSimple { public IsOffDayOfWeek() { super(SubjectResource.this, Verbs.isOff, @@ -184,7 +184,7 @@ public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object } - public class IsOnDate extends SentenceSimple { + public class IsOnDate extends SentenceSimple { public IsOnDate() { super(SubjectResource.this, Verbs.isOn, @@ -201,7 +201,7 @@ public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object } - public class IsOnDates extends SentenceSimple { + public class IsOnDates extends SentenceSimple { public IsOnDates() { super(SubjectResource.this, Verbs.isOn, diff --git a/src/net/sourceforge/plantuml/project/lang/SubjectSeparator.java b/src/net/sourceforge/plantuml/project/lang/SubjectSeparator.java index 4ed3a05e8d1..47369616376 100644 --- a/src/net/sourceforge/plantuml/project/lang/SubjectSeparator.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectSeparator.java @@ -47,9 +47,9 @@ import net.sourceforge.plantuml.regex.RegexLeaf; import net.sourceforge.plantuml.regex.RegexResult; -public class SubjectSeparator implements Subject { +public class SubjectSeparator implements Subject { - public static final Subject ME = new SubjectSeparator(); + public static final Subject ME = new SubjectSeparator(); private SubjectSeparator() { } @@ -62,11 +62,11 @@ public Failable getMe(GanttDiagram project, RegexResult arg) { return Failable.ok(project); } - public Collection getSentences() { + public Collection> getSentences() { return Arrays.asList(new JustBefore(), new JustAfter(), new Just()); } - class JustBefore extends SentenceSimple { + class JustBefore extends SentenceSimple { public JustBefore() { super(SubjectSeparator.this, Verbs.just, Words.exactly(Words.BEFORE), ComplementDate.any()); @@ -82,7 +82,7 @@ public CommandExecutionResult execute(GanttDiagram project, Object subject, Obje } - class JustAfter extends SentenceSimple { + class JustAfter extends SentenceSimple { public JustAfter() { super(SubjectSeparator.this, Verbs.just, Words.exactly(Words.AFTER), ComplementDate.any()); @@ -98,7 +98,7 @@ public CommandExecutionResult execute(GanttDiagram project, Object subject, Obje } - class Just extends SentenceSimple { + class Just extends SentenceSimple { public Just() { super(SubjectSeparator.this, Verbs.just, new ComplementBeforeOrAfterOrAtTaskStartOrEnd()); diff --git a/src/net/sourceforge/plantuml/project/lang/SubjectTask.java b/src/net/sourceforge/plantuml/project/lang/SubjectTask.java index da31a4542ec..0a0ef31dd98 100644 --- a/src/net/sourceforge/plantuml/project/lang/SubjectTask.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectTask.java @@ -48,10 +48,12 @@ 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 class SubjectTask implements Subject { - public static final Subject ME = new SubjectTask(); + public static final Subject ME = new SubjectTask(); private SubjectTask() { } @@ -64,9 +66,16 @@ public Failable getMe(GanttDiagram gantt, RegexResult arg) { return Failable.error("Not sure what are you refering to?"); } else { final String subject = arg.get("SUBJECT", 0); - final String shortName = arg.get("SUBJECT", 1); + final String shortName = arg.get("SHORTNAME", 0); final String then = arg.get("THEN", 0); + final String stereotype = arg.get("STEREOTYPE", 0); + result = gantt.getOrCreateTask(subject, shortName, then != null); + + if (stereotype != null) + result.setStereotype(Stereotype.build(arg.get("STEREOTYPE", 0))); + + gantt.setIt(result); } @@ -89,7 +98,7 @@ public Failable getMe(GanttDiagram gantt, RegexResult arg) { return Failable.ok(result); } - public Collection getSentences() { + public Collection> getSentences() { return Arrays.asList(new SentenceRequire(), new SentenceTaskStarts(), new SentenceTaskStartsWithColor(), new SentenceTaskStartsOnlyRelative(), new SentenceTaskStartsAbsolute(), new SentenceHappens(), new SentenceHappensDate(), new SentenceEnds(), new SentenceTaskEndsOnlyRelative(), @@ -103,13 +112,17 @@ public IRegex toRegex() { return new RegexOr( // new RegexLeaf("IT", "(it)"), // new RegexConcat(new RegexLeaf("THEN", "(then[%s]+)?"), // - new RegexLeaf("SUBJECT", "\\[([^\\[\\]]+?)\\](?:[%s]+as[%s]+\\[([^\\[\\]]+?)\\])?"), // - new RegexOptional( // - new RegexConcat( // - Words.exactly(Words.ON), // - RegexLeaf.spaceOneOrMore(), // - new RegexLeaf("RESOURCE", "((?:\\{[^{}]+\\}[%s]*)+)") // - )))); + new RegexLeaf("SUBJECT", "\\[([^\\[\\]]+?)\\]"), // + StereotypePattern.optional("STEREOTYPE"), // + new RegexOptional(new RegexConcat(// + Words.exactly(Words.AS), // + RegexLeaf.spaceOneOrMore(), // + new RegexLeaf("SHORTNAME", "\\[([^\\[\\]]+?)\\]"))), // + new RegexOptional(new RegexConcat( // + Words.exactly(Words.ON), // + RegexLeaf.spaceOneOrMore(), // + new RegexLeaf("RESOURCE", "((?:\\{[^{}]+\\}[%s]*)+)") // + )))); } } diff --git a/src/net/sourceforge/plantuml/project/lang/SubjectToday.java b/src/net/sourceforge/plantuml/project/lang/SubjectToday.java index 3ee19a018ef..0f4854f16c1 100644 --- a/src/net/sourceforge/plantuml/project/lang/SubjectToday.java +++ b/src/net/sourceforge/plantuml/project/lang/SubjectToday.java @@ -48,10 +48,10 @@ import net.sourceforge.plantuml.regex.RegexLeaf; import net.sourceforge.plantuml.regex.RegexResult; -public class SubjectToday implements Subject { - // ::remove folder when __HAXE__ +public class SubjectToday implements Subject { + // ::remove folder when __HAXE__ - public static final Subject ME = new SubjectToday(); + public static final Subject ME = new SubjectToday(); private SubjectToday() { } @@ -66,11 +66,11 @@ public Failable getMe(GanttDiagram project, RegexResult arg) { return Failable.ok(new Today()); } - public Collection getSentences() { + public Collection> getSentences() { return Arrays.asList(new InColor(), new IsDate()); } - class InColor extends SentenceSimple { + class InColor extends SentenceSimple { public InColor() { super(SubjectToday.this, Verbs.isColored, new ComplementInColors()); @@ -87,7 +87,7 @@ public CommandExecutionResult execute(GanttDiagram project, Object subject, Obje } - class IsDate extends SentenceSimple { + class IsDate extends SentenceSimple { public IsDate() { super(SubjectToday.this, Verbs.is, ComplementDate.any()); diff --git a/src/net/sourceforge/plantuml/project/lang/Words.java b/src/net/sourceforge/plantuml/project/lang/Words.java index e3239c218ca..41bb3178252 100644 --- a/src/net/sourceforge/plantuml/project/lang/Words.java +++ b/src/net/sourceforge/plantuml/project/lang/Words.java @@ -45,6 +45,7 @@ public class Words { public final static String AFTER = "after"; public final static String AND = "and"; + public final static String AS = "as"; public final static String AT = "at"; public final static String BEFORE = "before"; public final static String COMPLETION = "completion"; diff --git a/src/net/sourceforge/plantuml/project/time/Day.java b/src/net/sourceforge/plantuml/project/time/Day.java index b6eb3df98b9..f8d27cae68a 100644 --- a/src/net/sourceforge/plantuml/project/time/Day.java +++ b/src/net/sourceforge/plantuml/project/time/Day.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.project.time; import java.util.Calendar; +import java.util.Locale; import java.util.TimeZone; import net.sourceforge.plantuml.project.Value; @@ -48,7 +49,7 @@ public class Day implements Comparable, Value { private final int dayOfMonth; private final MonthYear monthYear; - private final long ms1; + private final long milliseconds; public static Day create(int year, String month, int dayOfMonth) { return new Day(year, Month.fromString(month), dayOfMonth); @@ -66,10 +67,14 @@ public static Day today() { return create(System.currentTimeMillis()); } + public String toStringShort(Locale locale) { + return monthYear.shortName(locale) + " " + dayOfMonth; + } + public int getWeekOfYear(WeekNumberStrategy strategy) { synchronized (gmt) { gmt.clear(); - gmt.setTimeInMillis(ms1); + gmt.setTimeInMillis(milliseconds); gmt.setFirstDayOfWeek(strategy.getFirstDayOfWeekAsLegacyInt()); gmt.setMinimalDaysInFirstWeek(strategy.getMinimalDaysInFirstWeek()); return gmt.get(Calendar.WEEK_OF_YEAR); @@ -82,12 +87,12 @@ private Day(int year, Month month, int dayOfMonth) { synchronized (gmt) { gmt.clear(); gmt.set(year, month.ordinal(), dayOfMonth); - this.ms1 = gmt.getTimeInMillis(); + this.milliseconds = gmt.getTimeInMillis(); } } private Day(long ms) { - this.ms1 = ms; + this.milliseconds = ms; synchronized (gmt) { gmt.clear(); gmt.setTimeInMillis(ms); @@ -113,11 +118,11 @@ public Day addDays(int nday) { } public final int getAbsoluteDayNum() { - return (int) (ms1 / MILLISECONDS_PER_DAY); + return (int) (milliseconds / MILLISECONDS_PER_DAY); } public final long getMillis() { - return ms1; + return milliseconds; } public int year() { @@ -195,4 +200,12 @@ public Day increment(PrintScale printScale) { return increment(); } + public Day roundDayDown() { + return new Day((milliseconds / MILLISECONDS_PER_DAY) * MILLISECONDS_PER_DAY); + } + + public Day roundDayUp() { + return new Day(((milliseconds + MILLISECONDS_PER_DAY - 1) / MILLISECONDS_PER_DAY) * MILLISECONDS_PER_DAY); + } + } diff --git a/src/net/sourceforge/plantuml/project/timescale/TimeScaleCompressed.java b/src/net/sourceforge/plantuml/project/timescale/TimeScaleCompressed.java index 31cc3283a8c..3e8155866fd 100644 --- a/src/net/sourceforge/plantuml/project/timescale/TimeScaleCompressed.java +++ b/src/net/sourceforge/plantuml/project/timescale/TimeScaleCompressed.java @@ -42,8 +42,8 @@ public class TimeScaleCompressed implements TimeScale { private final TimeScale daily; - public TimeScaleCompressed(double size, Day calendar, double scale) { - this.daily = new TimeScaleDaily(size, calendar, scale, null); + public TimeScaleCompressed(double size, Day calendar, double scale, Day zeroDay) { + this.daily = new TimeScaleDaily(size, calendar, scale, zeroDay); } public double getStartingPosition(Day instant) { diff --git a/src/net/sourceforge/plantuml/regexdiagram/PSystemRegex.java b/src/net/sourceforge/plantuml/regexdiagram/PSystemRegex.java index af874516ce4..4a1e610f0c4 100644 --- a/src/net/sourceforge/plantuml/regexdiagram/PSystemRegex.java +++ b/src/net/sourceforge/plantuml/regexdiagram/PSystemRegex.java @@ -52,11 +52,12 @@ import net.sourceforge.plantuml.ebnf.ETileAlternation; import net.sourceforge.plantuml.ebnf.ETileBox; import net.sourceforge.plantuml.ebnf.ETileConcatenation; +import net.sourceforge.plantuml.ebnf.ETileLookAheadOrBehind; +import net.sourceforge.plantuml.ebnf.ETileNamedGroup; import net.sourceforge.plantuml.ebnf.ETileOneOrMore; import net.sourceforge.plantuml.ebnf.ETileOptional; import net.sourceforge.plantuml.ebnf.ETileZeroOrMore; import net.sourceforge.plantuml.ebnf.Symbol; -import net.sourceforge.plantuml.ebnf.TextBlockable; import net.sourceforge.plantuml.klimt.color.HColor; import net.sourceforge.plantuml.klimt.color.HColorSet; import net.sourceforge.plantuml.klimt.color.HColors; @@ -76,8 +77,6 @@ public class PSystemRegex extends TitledDiagram { - private final List expressions = new ArrayList<>(); - public PSystemRegex(UmlSource source) { super(source, UmlDiagramType.REGEX, null); final ISkinParam skinParam = getSkinParam(); @@ -122,11 +121,11 @@ public DiagramDescription getDescription() { @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) { // while (stack.size() > 1) // concatenation(); final ETile peekFirst = stack.peekFirst(); @@ -164,6 +163,12 @@ else if (token.getType() == ReTokenType.ESCAPED_CHAR) push(token, Symbol.TERMINAL_STRING1); else if (token.getType() == ReTokenType.GROUP) push(token, Symbol.SPECIAL_SEQUENCE); + else if (token.getType() == ReTokenType.LOOK_AHEAD) + lookAheadOrBehind(token.getData()); + else if (token.getType() == ReTokenType.LOOK_BEHIND) + lookAheadOrBehind(token.getData()); + else if (token.getType() == ReTokenType.NAMED_GROUP) + namedGroup(token.getData()); else if (token.getType() == ReTokenType.CLASS) push(token, Symbol.LITTERAL); else if (token.getType() == ReTokenType.ANCHOR) @@ -205,6 +210,16 @@ private void push(ReToken element, Symbol type) { stack.addFirst(new ETileBox(element.getData(), type, fontConfiguration, style, colorSet, getSkinParam())); } + private void lookAheadOrBehind(String name) { + final ETile arg1 = stack.removeFirst(); + stack.addFirst(new ETileLookAheadOrBehind(arg1, fontConfiguration, style, colorSet, name)); + } + + private void namedGroup(String name) { + final ETile arg1 = stack.removeFirst(); + stack.addFirst(new ETileNamedGroup(arg1, fontConfiguration, colorSet, getSkinParam(), name)); + } + private void repetitionZeroOrMore(boolean isCompact) { final ETile arg1 = stack.removeFirst(); if (isCompact) @@ -266,9 +281,10 @@ private void concatenation() { if (arg1 instanceof ETileConcatenation) { arg1.push(arg2); stack.addFirst(arg1); - } else if (arg2 instanceof ETileConcatenation) { - arg2.push(arg1); - stack.addFirst(arg2); + // This does not work for (A[B])(C) +// } else if (arg2 instanceof ETileConcatenation) { +// arg2.push(arg1); +// stack.addFirst(arg2); } else { final ETile concat = new ETileConcatenation(); concat.push(arg1); diff --git a/src/net/sourceforge/plantuml/regexdiagram/ReTokenType.java b/src/net/sourceforge/plantuml/regexdiagram/ReTokenType.java index d723fcfed0b..5941488ea35 100644 --- a/src/net/sourceforge/plantuml/regexdiagram/ReTokenType.java +++ b/src/net/sourceforge/plantuml/regexdiagram/ReTokenType.java @@ -43,12 +43,21 @@ public enum ReTokenType { QUANTIFIER, // ANCHOR, // GROUP, // + NAMED_GROUP, // + LOOK_AHEAD, // + LOOK_BEHIND, // ALTERNATIVE, // PARENTHESIS_OPEN, // PARENTHESIS_CLOSE, // CONCATENATION_IMPLICIT; + public boolean isNamedGroupOrLookAheadOrLookBehind() { + return this == NAMED_GROUP || this == LOOK_AHEAD || this == LOOK_BEHIND; + } + static public boolean needImplicitConcatenation(ReTokenType token1, ReTokenType token2) { + if (token1.isNamedGroupOrLookAheadOrLookBehind()) + return false; if (token1 == ALTERNATIVE) return false; if (token2 == ALTERNATIVE) diff --git a/src/net/sourceforge/plantuml/regexdiagram/RegexExpression.java b/src/net/sourceforge/plantuml/regexdiagram/RegexExpression.java index 77ab743345c..50a3003e39f 100644 --- a/src/net/sourceforge/plantuml/regexdiagram/RegexExpression.java +++ b/src/net/sourceforge/plantuml/regexdiagram/RegexExpression.java @@ -60,12 +60,29 @@ public static List parse(CharInspector it) throws RegexParsingException } else if (current == '|') { result.add(new ReToken(ReTokenType.ALTERNATIVE, "|")); it.jump(); + } else if (isStartPosixGroup(it)) { + final String s = readGroupPosix(it); + result.add(new ReToken(ReTokenType.CLASS, s)); } else if (current == '[') { final String s = readGroup(it); result.add(new ReToken(ReTokenType.GROUP, s)); + } else if (isStartComment(it)) { + skipComment(it); + } else if (isStartLookAhead(it)) { + final ReToken token = readLookAhead(it); + result.add(token); + result.add(new ReToken(ReTokenType.PARENTHESIS_OPEN, "(")); + } else if (isStartLookBehind(it)) { + final ReToken token = readLookBehind(it); + result.add(token); + result.add(new ReToken(ReTokenType.PARENTHESIS_OPEN, "(")); + } else if (isStartNamedCapturingGroup(it)) { + final ReToken token = readNamedGroup(it); + result.add(token); + result.add(new ReToken(ReTokenType.PARENTHESIS_OPEN, "(")); } else if (isStartOpenParenthesis(it)) { - final String s = readOpenParenthesis(it); - result.add(new ReToken(ReTokenType.PARENTHESIS_OPEN, s)); + final ReToken token = readOpenParenthesis(it); + result.add(token); } else if (current == ')') { result.add(new ReToken(ReTokenType.PARENTHESIS_CLOSE, ")")); it.jump(); @@ -96,6 +113,20 @@ public static List parse(CharInspector it) throws RegexParsingException } + private static boolean isStartLookAhead(CharInspector it) { + final char current0 = it.peek(0); + if (current0 == '(' && it.peek(1) == '?' && (it.peek(2) == '=' || it.peek(2) == '!')) + return true; + return false; + } + + private static boolean isStartLookBehind(CharInspector it) { + final char current0 = it.peek(0); + if (current0 == '(' && it.peek(1) == '?' && it.peek(2) == '<' && (it.peek(3) == '=' || it.peek(3) == '!')) + return true; + return false; + } + private static boolean isStartOpenParenthesis(CharInspector it) { final char current0 = it.peek(0); if (current0 == '(') @@ -103,7 +134,90 @@ private static boolean isStartOpenParenthesis(CharInspector it) { return false; } - private static String readOpenParenthesis(CharInspector it) { + private static boolean isStartPosixGroup(CharInspector it) { + final char current0 = it.peek(0); + if (current0 == '[' && it.peek(1) == '[' && it.peek(2) == ':') + return true; + return false; + } + + private static boolean isStartNamedCapturingGroup(CharInspector it) { + final char current0 = it.peek(0); + if (current0 == '(' && it.peek(1) == '?' && it.peek(2) == '<') { + int i = 3; + while (it.peek(i) != 0) { + if (it.peek(i) == '>' && i == 3) + return false; + if (it.peek(i) == '>') + return true; + if (Character.isLetter(it.peek(i)) == false) + return false; + i++; + } + + } + return false; + } + + private static boolean isStartComment(CharInspector it) { + final char current0 = it.peek(0); + if (current0 == '(' && it.peek(1) == '?' && it.peek(2) == '#') + return true; + return false; + } + + private static void skipComment(CharInspector it) throws RegexParsingException { + it.jump(); + it.jump(); + it.jump(); + final StringBuilder comment = new StringBuilder(); + while (true) { + if (it.peek(0) == 0) + throw new RegexParsingException("Unclosed comment"); + if (it.peek(0) == ')') { + it.jump(); + return; + } + comment.append(it.peek(0)); + it.jump(); + } + } + + private static ReToken readLookAhead(CharInspector it) throws RegexParsingException { + it.jump(); + it.jump(); + final char ch = it.peek(0); + it.jump(); + return new ReToken(ReTokenType.LOOK_AHEAD, "?" + ch); + } + + private static ReToken readLookBehind(CharInspector it) throws RegexParsingException { + it.jump(); + it.jump(); + it.jump(); + final char ch = it.peek(0); + it.jump(); + return new ReToken(ReTokenType.LOOK_BEHIND, "?<" + ch); + } + + private static ReToken readNamedGroup(CharInspector it) throws RegexParsingException { + it.jump(); + it.jump(); + it.jump(); + final StringBuilder namedGroup = new StringBuilder(); + while (true) { + if (it.peek(0) == 0) + throw new RegexParsingException("Unclosed named capturing group"); + if (it.peek(0) == '>') { + it.jump(); + return new ReToken(ReTokenType.NAMED_GROUP, namedGroup.toString()); + } + namedGroup.append(it.peek(0)); + it.jump(); + } + } + + private static ReToken readOpenParenthesis(CharInspector it) { final char current0 = it.peek(0); it.jump(); final StringBuilder result = new StringBuilder(); @@ -118,7 +232,7 @@ private static String readOpenParenthesis(CharInspector it) { it.jump(); result.append("?!"); } - return result.toString(); + return new ReToken(ReTokenType.PARENTHESIS_OPEN, result.toString()); } private static boolean isStartQuantifier(CharInspector it) { @@ -164,6 +278,23 @@ private static boolean isEscapedChar(CharInspector it) { return false; } + private static String readGroupPosix(CharInspector it) { + it.jump(); + it.jump(); + it.jump(); + final StringBuilder result = new StringBuilder(":"); + while (it.peek(0) != 0) { + char ch = it.peek(0); + it.jump(); + result.append(ch); + if (ch == ':') + break; + } + it.jump(); + it.jump(); + return result.toString(); + } + private static String readGroup(CharInspector it) { final char current0 = it.peek(0); if (current0 != '[') diff --git a/src/net/sourceforge/plantuml/regexdiagram/ShuntingYard.java b/src/net/sourceforge/plantuml/regexdiagram/ShuntingYard.java index c29e837028e..3749d771ed3 100644 --- a/src/net/sourceforge/plantuml/regexdiagram/ShuntingYard.java +++ b/src/net/sourceforge/plantuml/regexdiagram/ShuntingYard.java @@ -59,6 +59,8 @@ public ShuntingYard(Iterator it) { ouputQueue.add(token); } else if (token.getType() == ReTokenType.GROUP) { ouputQueue.add(token); + } else if (token.getType().isNamedGroupOrLookAheadOrLookBehind()) { + operatorStack.addFirst(token); } else if (token.getType() == ReTokenType.CLASS) { ouputQueue.add(token); } else if (token.getType() == ReTokenType.ANCHOR) { @@ -80,7 +82,8 @@ public ShuntingYard(Iterator it) { && operatorStack.peekFirst().getType() != ReTokenType.PARENTHESIS_OPEN) ouputQueue.add(operatorStack.removeFirst()); final ReToken first = operatorStack.removeFirst(); -// ouputQueue.add(first); + if (operatorStack.peekFirst() != null && operatorStack.peekFirst().getType().isNamedGroupOrLookAheadOrLookBehind()) + ouputQueue.add(operatorStack.removeFirst()); } else { throw new UnsupportedOperationException(token.toString()); diff --git a/src/net/sourceforge/plantuml/salt/PSystemSalt.java b/src/net/sourceforge/plantuml/salt/PSystemSalt.java index be3c0922a11..303aa32bf40 100644 --- a/src/net/sourceforge/plantuml/salt/PSystemSalt.java +++ b/src/net/sourceforge/plantuml/salt/PSystemSalt.java @@ -126,8 +126,7 @@ final protected ImageData exportDiagramNow(OutputStream os, int index, FileForma } @Override - protected TextBlock getTextBlock() { - final FileFormatOption fileFormatOption = new FileFormatOption(FileFormat.PNG); + protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) { final Element salt = createElement(manageSprite()); final StringBounder stringBounder = fileFormatOption.getDefaultStringBounder(getSkinParam()); final XDimension2D size = salt.getPreferredDimension(stringBounder, 0, 0); diff --git a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java index d70277fb4a5..21bd66775a7 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java +++ b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java @@ -296,13 +296,13 @@ protected ImageData exportDiagramInternal(OutputStream os, int index, FileFormat } @Override - final public void exportDiagramGraphic(UGraphic ug) { - final FileMaker sequenceDiagramPngMaker = getSequenceDiagramPngMaker(0, new FileFormatOption(FileFormat.PNG)); + final public void exportDiagramGraphic(UGraphic ug, FileFormatOption fileFormatOption) { + final FileMaker sequenceDiagramPngMaker = getSequenceDiagramPngMaker(0, fileFormatOption); sequenceDiagramPngMaker.createOneGraphic(ug); } @Override - final protected TextBlock getTextBlock() { + final protected TextBlock getTextMainBlock(FileFormatOption fileFormatOption) { throw new UnsupportedOperationException(); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java index c41b98fbd5f..5b4aa1ebea6 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java @@ -65,6 +65,7 @@ import net.sourceforge.plantuml.skin.ArrowHead; import net.sourceforge.plantuml.skin.ArrowPart; 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; @@ -123,9 +124,7 @@ static IRegex getRegexConcat() { new RegexLeaf("ACTIVATION", "(?:(\\+\\+|\\*\\*|!!|--|--\\+\\+|\\+\\+--)?)"), // RegexLeaf.spaceZeroOrMore(), // new RegexLeaf("LIFECOLOR", "(?:(#\\w+)?)"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREOTYPE"), // UrlBuilder.OPTIONAL, // RegexLeaf.spaceZeroOrMore(), // new RegexLeaf("MESSAGE", "(?::[%s]*(.*))?"), // diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxStart.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxStart.java index 9dc4752c69f..10bd93bddcf 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxStart.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxStart.java @@ -50,6 +50,7 @@ import net.sourceforge.plantuml.regex.RegexResult; import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; import net.sourceforge.plantuml.stereo.Stereotype; +import net.sourceforge.plantuml.stereo.StereotypePattern; import net.sourceforge.plantuml.style.ISkinParam; import net.sourceforge.plantuml.utils.LineLocation; @@ -69,8 +70,7 @@ static IRegex getRegexConcat() { new RegexConcat( // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("NAME2", "([^#]+)")))), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), // + StereotypePattern.optional("STEREO"), // color().getRegex(), // RegexLeaf.end()); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA.java index 03c0cd3dfce..04236f68c0f 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA.java @@ -40,6 +40,7 @@ import net.sourceforge.plantuml.regex.RegexConcat; import net.sourceforge.plantuml.regex.RegexLeaf; import net.sourceforge.plantuml.regex.RegexOptional; +import net.sourceforge.plantuml.stereo.StereotypePattern; import net.sourceforge.plantuml.url.UrlBuilder; public class CommandParticipantA extends CommandParticipant { @@ -60,13 +61,12 @@ static IRegex getRegexConcat() { RegexLeaf.spaceOneOrMore() // )), // new RegexLeaf("CODE", "([%pLN_.@]+)"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREO"), // getOrderRegex(), // RegexLeaf.spaceZeroOrMore(), // UrlBuilder.OPTIONAL, // RegexLeaf.spaceZeroOrMore(), // ColorParser.exp1(), RegexLeaf.end()); } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA2.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA2.java index 954bf7ac291..7014b00732f 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA2.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA2.java @@ -39,6 +39,7 @@ import net.sourceforge.plantuml.regex.IRegex; import net.sourceforge.plantuml.regex.RegexConcat; import net.sourceforge.plantuml.regex.RegexLeaf; +import net.sourceforge.plantuml.stereo.StereotypePattern; import net.sourceforge.plantuml.url.UrlBuilder; public class CommandParticipantA2 extends CommandParticipant { @@ -56,9 +57,7 @@ static IRegex getRegexConcat() { new RegexLeaf("as"), // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("FULL", "[%g]([^%g]+)[%g]"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREO"), // getOrderRegex(), // RegexLeaf.spaceZeroOrMore(), // UrlBuilder.OPTIONAL, // diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA3.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA3.java index dcb2b2f0c4e..fe05fbc496a 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA3.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA3.java @@ -39,6 +39,7 @@ import net.sourceforge.plantuml.regex.IRegex; import net.sourceforge.plantuml.regex.RegexConcat; import net.sourceforge.plantuml.regex.RegexLeaf; +import net.sourceforge.plantuml.stereo.StereotypePattern; import net.sourceforge.plantuml.url.UrlBuilder; public class CommandParticipantA3 extends CommandParticipant { @@ -56,9 +57,7 @@ static IRegex getRegexConcat() { new RegexLeaf("as"), // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("CODE", "([%pLN_.@]+)"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREO"), // getOrderRegex(), // RegexLeaf.spaceZeroOrMore(), // UrlBuilder.OPTIONAL, // diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA4.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA4.java index 6197f0265e7..c2ec8e1d0f8 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA4.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantA4.java @@ -39,6 +39,7 @@ import net.sourceforge.plantuml.regex.IRegex; import net.sourceforge.plantuml.regex.RegexConcat; import net.sourceforge.plantuml.regex.RegexLeaf; +import net.sourceforge.plantuml.stereo.StereotypePattern; import net.sourceforge.plantuml.url.UrlBuilder; public class CommandParticipantA4 extends CommandParticipant { @@ -52,9 +53,7 @@ static IRegex getRegexConcat() { getRegexType(), // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("CODE", "[%g]([^%g]+)[%g]"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREO", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREO"), // getOrderRegex(), // RegexLeaf.spaceZeroOrMore(), // UrlBuilder.OPTIONAL, // diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantMultilines.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantMultilines.java index b9d3a554ed1..6404fb34783 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantMultilines.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipantMultilines.java @@ -52,6 +52,7 @@ import net.sourceforge.plantuml.sequencediagram.ParticipantType; import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; import net.sourceforge.plantuml.stereo.Stereotype; +import net.sourceforge.plantuml.stereo.StereotypePattern; import net.sourceforge.plantuml.style.ISkinParam; import net.sourceforge.plantuml.url.Url; import net.sourceforge.plantuml.url.UrlBuilder; @@ -74,9 +75,7 @@ private static RegexConcat getRegexConcat() { new RegexLeaf("TYPE", "(participant)"), // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("CODE", "([%pLN_.@]+)"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREO", "(\\<\\<.+\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREO"), // CommandParticipant.getOrderRegex(), // RegexLeaf.spaceZeroOrMore(), // UrlBuilder.OPTIONAL, // diff --git a/src/net/sourceforge/plantuml/skin/UmlDiagramType.java b/src/net/sourceforge/plantuml/skin/UmlDiagramType.java index 3beaf06915a..00bdbd29fb1 100644 --- a/src/net/sourceforge/plantuml/skin/UmlDiagramType.java +++ b/src/net/sourceforge/plantuml/skin/UmlDiagramType.java @@ -39,7 +39,7 @@ public enum UmlDiagramType { SEQUENCE, STATE, CLASS, OBJECT, ACTIVITY, DESCRIPTION, COMPOSITE, FLOW, TIMING, BPM, NWDIAG, MINDMAP, WBS, WIRE, - HELP, GANTT, SALT, JSON, GIT, BOARD, YAML, HCL, EBNF, REGEX, FILES; + HELP, GANTT, SALT, JSON, GIT, BOARD, YAML, HCL, EBNF, REGEX, FILES, CHRONOLOGY; public SName getStyleName() { if (this == SEQUENCE) @@ -96,6 +96,9 @@ public SName getStyleName() { if (this == REGEX) return SName.regex; + if (this == CHRONOLOGY) + return SName.ganttDiagram; + return SName.activityDiagram; } } diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackage2.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackage2.java index a683fe5b732..b2d94a443de 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackage2.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackage2.java @@ -55,6 +55,7 @@ import net.sourceforge.plantuml.regex.RegexResult; import net.sourceforge.plantuml.statediagram.StateDiagram; 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; @@ -83,9 +84,7 @@ private static IRegex getRegexConcat() { new RegexLeaf("as"), RegexLeaf.spaceOneOrMore() // )), // new RegexLeaf("CODE2", "([%pLN_.]+)"))), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREOTYPE"), // UrlBuilder.OPTIONAL, // RegexLeaf.spaceZeroOrMore(), // color().getRegex(), // diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java index 6a8e408aa88..b8a502ab96f 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java @@ -56,6 +56,7 @@ import net.sourceforge.plantuml.statediagram.StateDiagram; 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; @@ -86,9 +87,7 @@ private static IRegex getRegexConcat() { new RegexLeaf("CODE2", "([%pLN_.]+)"))), // 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/statediagram/command/CommandCreateState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java index 1de76f5f1b3..abb56174744 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java @@ -56,6 +56,7 @@ import net.sourceforge.plantuml.statediagram.StateDiagram; 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; @@ -85,9 +86,7 @@ private static IRegex getRegexConcat() { new RegexLeaf("CODE4", "[%g]([^%g]+)[%g]")), // 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/stereo/Stereotype.java b/src/net/sourceforge/plantuml/stereo/Stereotype.java index 0268b9ae671..7cc43cd38d2 100644 --- a/src/net/sourceforge/plantuml/stereo/Stereotype.java +++ b/src/net/sourceforge/plantuml/stereo/Stereotype.java @@ -78,6 +78,8 @@ private static void checkLabel(String label) { } public static Stereotype build(String label) { + if (label == null) + return null; return build(label, true); } diff --git a/src/net/sourceforge/plantuml/stereo/StereotypePattern.java b/src/net/sourceforge/plantuml/stereo/StereotypePattern.java new file mode 100644 index 00000000000..c86520408cb --- /dev/null +++ b/src/net/sourceforge/plantuml/stereo/StereotypePattern.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.stereo; + +import net.sourceforge.plantuml.regex.IRegex; +import net.sourceforge.plantuml.regex.RegexConcat; +import net.sourceforge.plantuml.regex.RegexLeaf; +import net.sourceforge.plantuml.regex.RegexOptional; + +public class StereotypePattern { + + public static IRegex optional(String param) { + return new RegexConcat( // + RegexLeaf.spaceZeroOrMore(), // + new RegexOptional(mandatory(param)), // + RegexLeaf.spaceZeroOrMore() // + ); + } + + public static IRegex mandatory(String param) { + return new RegexLeaf(param, "(\\<\\<.+\\>\\>)"); + } + + public static IRegex optionalArchimate(String param) { + return new RegexConcat( // + RegexLeaf.spaceZeroOrMore(), // + new RegexOptional(new RegexLeaf(param, "(\\<\\<[-\\w]+\\>\\>)")), // + RegexLeaf.spaceZeroOrMore() // + ); + } + + public static String removeChevronBrackets(String stereo) { + if (stereo != null && stereo.startsWith("<<") && stereo.endsWith(">>")) + return stereo.substring(2, stereo.length() - 2); + return stereo; + } + +} diff --git a/src/net/sourceforge/plantuml/style/SName.java b/src/net/sourceforge/plantuml/style/SName.java index 111c7863aeb..7f1f9689ff1 100644 --- a/src/net/sourceforge/plantuml/style/SName.java +++ b/src/net/sourceforge/plantuml/style/SName.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.style; public enum SName { + action, // activity, // activityBar, // activityDiagram, // @@ -113,6 +114,7 @@ public enum SName { partition, // person, // port, // + process, // queue, // rectangle, // reference, // diff --git a/src/net/sourceforge/plantuml/sudoku/PSystemSudoku.java b/src/net/sourceforge/plantuml/sudoku/PSystemSudoku.java index 90ce3c59690..11c34203174 100644 --- a/src/net/sourceforge/plantuml/sudoku/PSystemSudoku.java +++ b/src/net/sourceforge/plantuml/sudoku/PSystemSudoku.java @@ -70,7 +70,7 @@ final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatO } @Override - public void exportDiagramGraphic(UGraphic ug) { + public void exportDiagramGraphic(UGraphic ug, FileFormatOption fileFormatOption) { final GraphicsSudoku sud = new GraphicsSudoku(sudoku); sud.drawInternal(ug); } diff --git a/src/net/sourceforge/plantuml/syntax/LanguageDescriptor.java b/src/net/sourceforge/plantuml/syntax/LanguageDescriptor.java index 31bd7245a4a..597b5b2e71d 100644 --- a/src/net/sourceforge/plantuml/syntax/LanguageDescriptor.java +++ b/src/net/sourceforge/plantuml/syntax/LanguageDescriptor.java @@ -93,6 +93,8 @@ public LanguageDescriptor() { type.add("metaclass"); type.add("map"); type.add("json"); + type.add("action"); + type.add("process"); keyword.add("@startwire"); keyword.add("@startbpm"); @@ -121,6 +123,7 @@ public LanguageDescriptor() { keyword.add("@startebnf"); keyword.add("@startregex"); keyword.add("@startfiles"); + keyword.add("@startchronology"); keyword.add("@endwire"); keyword.add("@endbpm"); keyword.add("@enduml"); @@ -148,6 +151,7 @@ public LanguageDescriptor() { keyword.add("@endebnf"); keyword.add("@endregex"); keyword.add("@endfiles"); + keyword.add("@endchronology"); keyword.add("as"); keyword.add("also"); keyword.add("autonumber"); diff --git a/src/net/sourceforge/plantuml/text/TLineType.java b/src/net/sourceforge/plantuml/text/TLineType.java index 869f3d8106e..315c58b88f2 100644 --- a/src/net/sourceforge/plantuml/text/TLineType.java +++ b/src/net/sourceforge/plantuml/text/TLineType.java @@ -34,6 +34,8 @@ */ package net.sourceforge.plantuml.text; +import java.util.regex.Pattern; + public enum TLineType { PLAIN, AFFECTATION_DEFINE, AFFECTATION, ASSERT, IF, IFDEF, UNDEF, IFNDEF, ELSE, ELSEIF, ENDIF, WHILE, ENDWHILE, @@ -41,115 +43,174 @@ public enum TLineType { LEGACY_DEFINELONG, THEME, INCLUDE, INCLUDE_DEF, IMPORT, STARTSUB, ENDSUB, INCLUDESUB, LOG, DUMP_MEMORY, COMMENT_SIMPLE, COMMENT_LONG_START; -// private boolean elseLike() { -// return this == ELSE || this == ELSEIF; -// } -// -// public boolean incIndentAfter() { -// return this == IF || this == IFDEF || this == IFNDEF || elseLike(); -// } -// -// public boolean decIndentBefore() { -// return this == ENDIF || elseLike(); -// } + private static final Pattern PATTERN_LEGACY_DEFINE = Pattern.compile("^\\s*!define\\s+[\\p{L}_][\\p{L}_0-9]*\\(.*"); + + private static final Pattern PATTERN_LEGACY_DEFINELONG = Pattern + .compile("^\\s*!definelong\\s+[\\p{L}_][\\p{L}_0-9]*\\b.*"); + + private static final Pattern PATTERN_AFFECTATION_DEFINE = Pattern + .compile("^\\s*!define\\s+[\\p{L}_][\\p{L}_0-9]*\\b.*"); + + private static final Pattern PATTERN_AFFECTATION = Pattern + .compile("^\\s*!\\s*(local|global)?\\s*\\$?[\\p{L}_][\\p{L}_0-9]*\\s*\\??=.*"); + + private static final Pattern PATTERN_COMMENT_SIMPLE1 = Pattern.compile("^\\s*'.*"); + + private static final Pattern PATTERN_COMMENT_SIMPLE2 = Pattern.compile("^\\s*/'.*'/\\s*$"); + + private static final Pattern PATTERN_COMMENT_LONG_START = Pattern.compile("^\\s*/'.*"); + + private static final Pattern PATTERN_IFDEF = Pattern.compile("^\\s*!ifdef\\s+.*"); + + private static final Pattern PATTERN_UNDEF = Pattern.compile("^\\s*!undef\\s+.*"); + + private static final Pattern PATTERN_IFNDEF = Pattern.compile("^\\s*!ifndef\\s+.*"); + + private static final Pattern PATTERN_ASSERT = Pattern.compile("^\\s*!assert\\s+.*"); + + private static final Pattern PATTERN_IF = Pattern.compile("^\\s*!if\\s+.*"); + + private static final Pattern PATTERN_DECLARE_RETURN_FUNCTION = Pattern + .compile("^\\s*!(unquoted\\s|final\\s)*(function)\\s+\\$?[\\p{L}_][\\p{L}_0-9]*.*"); + + private static final Pattern PATTERN_DECLARE_PROCEDURE = Pattern + .compile("^\\s*!(unquoted\\s|final\\s)*(procedure)\\s+\\$?[\\p{L}_][\\p{L}_0-9]*.*"); + + private static final Pattern PATTERN_ELSE = Pattern.compile("^\\s*!else\\b.*"); + + private static final Pattern PATTERN_ELSEIF = Pattern.compile("^\\s*!elseif\\b.*"); + + private static final Pattern PATTERN_ENDIF = Pattern.compile("^\\s*!endif\\b.*"); + + private static final Pattern PATTERN_WHILE = Pattern.compile("^\\s*!while\\s+.*"); + + private static final Pattern PATTERN_ENDWHILE = Pattern.compile("^\\s*!endwhile\\b.*"); + + private static final Pattern PATTERN_FOREACH = Pattern.compile("^\\s*!foreach\\s+.*"); + + private static final Pattern PATTERN_ENDFOREACH = Pattern.compile("^\\s*!endfor\\b.*"); + + private static final Pattern PATTERN_END_FUNCTION = Pattern + .compile("^\\s*!(end\\s*function|end\\s*definelong|end\\s*procedure)\\b.*"); + + private static final Pattern PATTERN_RETURN = Pattern.compile("^\\s*!return\\b.*"); + + private static final Pattern PATTERN_THEME = Pattern.compile("^\\s*!theme\\b.*"); + + private static final Pattern PATTERN_INCLUDE = Pattern + .compile("^\\s*!(include|includeurl|include_many|include_once)\\b.*"); + + private static final Pattern PATTERN_INCLUDE_DEF = Pattern.compile("^\\s*!(includedef)\\b.*"); + + private static final Pattern PATTERN_IMPORT = Pattern.compile("^\\s*!(import)\\b.*"); + + private static final Pattern PATTERN_STARTSUB = Pattern.compile("^\\s*!startsub\\s+.*"); + + private static final Pattern PATTERN_ENDSUB = Pattern.compile("^\\s*!endsub\\b.*"); + + private static final Pattern PATTERN_INCLUDESUB = Pattern.compile("^\\s*!includesub\\b.*"); + + private static final Pattern PATTERN_LOG = Pattern.compile("^\\s*!(log)\\b.*"); + + private static final Pattern PATTERN_DUMP_MEMORY = Pattern.compile("^\\s*!(dump_memory)\\b.*"); public static TLineType getFromLineInternal(String s) { - if (s.matches("^\\s*!define\\s+[\\p{L}_][\\p{L}_0-9]*\\(.*")) { + if (PATTERN_LEGACY_DEFINE.matcher(s).matches()) return LEGACY_DEFINE; - } - if (s.matches("^\\s*!definelong\\s+[\\p{L}_][\\p{L}_0-9]*\\b.*")) { + + if (PATTERN_LEGACY_DEFINELONG.matcher(s).matches()) return LEGACY_DEFINELONG; - } - if (s.matches("^\\s*!define\\s+[\\p{L}_][\\p{L}_0-9]*\\b.*")) { + + if (PATTERN_AFFECTATION_DEFINE.matcher(s).matches()) return AFFECTATION_DEFINE; - } - if (s.matches("^\\s*!\\s*(local|global)?\\s*\\$?[\\p{L}_][\\p{L}_0-9]*\\s*\\??=.*")) { + + if (PATTERN_AFFECTATION.matcher(s).matches()) return AFFECTATION; - } - if (s.matches("^\\s*'.*")) { + + if (PATTERN_COMMENT_SIMPLE1.matcher(s).matches()) return COMMENT_SIMPLE; - } - if (s.matches("^\\s*/'.*'/\\s*$")) { + + if (PATTERN_COMMENT_SIMPLE2.matcher(s).matches()) return COMMENT_SIMPLE; - } - if (s.matches("^\\s*/'.*") && s.contains("'/") == false) { + + if (PATTERN_COMMENT_LONG_START.matcher(s).matches() && s.contains("'/") == false) return COMMENT_LONG_START; - } - if (s.matches("^\\s*!ifdef\\s+.*")) { + + if (PATTERN_IFDEF.matcher(s).matches()) return IFDEF; - } - if (s.matches("^\\s*!undef\\s+.*")) { + + if (PATTERN_UNDEF.matcher(s).matches()) return UNDEF; - } - if (s.matches("^\\s*!ifndef\\s+.*")) { + + if (PATTERN_IFNDEF.matcher(s).matches()) return IFNDEF; - } - if (s.matches("^\\s*!assert\\s+.*")) { + + if (PATTERN_ASSERT.matcher(s).matches()) return ASSERT; - } - if (s.matches("^\\s*!if\\s+.*")) { + + if (PATTERN_IF.matcher(s).matches()) return IF; - } - if (s.matches("^\\s*!(unquoted\\s|final\\s)*(function)\\s+\\$?[\\p{L}_][\\p{L}_0-9]*.*")) { + + if (PATTERN_DECLARE_RETURN_FUNCTION.matcher(s).matches()) return DECLARE_RETURN_FUNCTION; - } - if (s.matches("^\\s*!(unquoted\\s|final\\s)*(procedure)\\s+\\$?[\\p{L}_][\\p{L}_0-9]*.*")) { + + if (PATTERN_DECLARE_PROCEDURE.matcher(s).matches()) return DECLARE_PROCEDURE; - } - if (s.matches("^\\s*!else\\b.*")) { + + if (PATTERN_ELSE.matcher(s).matches()) return ELSE; - } - if (s.matches("^\\s*!elseif\\b.*")) { + + if (PATTERN_ELSEIF.matcher(s).matches()) return ELSEIF; - } - if (s.matches("^\\s*!endif\\b.*")) { + + if (PATTERN_ENDIF.matcher(s).matches()) return ENDIF; - } - if (s.matches("^\\s*!while\\s+.*")) { + + if (PATTERN_WHILE.matcher(s).matches()) return WHILE; - } - if (s.matches("^\\s*!endwhile\\b.*")) { + + if (PATTERN_ENDWHILE.matcher(s).matches()) return ENDWHILE; - } - if (s.matches("^\\s*!foreach\\s+.*")) { + + if (PATTERN_FOREACH.matcher(s).matches()) return FOREACH; - } - if (s.matches("^\\s*!endfor\\b.*")) { + + if (PATTERN_ENDFOREACH.matcher(s).matches()) return ENDFOREACH; - } - if (s.matches("^\\s*!(end\\s*function|end\\s*definelong|end\\s*procedure)\\b.*")) { + + if (PATTERN_END_FUNCTION.matcher(s).matches()) return END_FUNCTION; - } - if (s.matches("^\\s*!return\\b.*")) { + + if (PATTERN_RETURN.matcher(s).matches()) return RETURN; - } - if (s.matches("^\\s*!theme\\b.*")) { + + if (PATTERN_THEME.matcher(s).matches()) return THEME; - } - if (s.matches("^\\s*!(include|includeurl|include_many|include_once)\\b.*")) { + + if (PATTERN_INCLUDE.matcher(s).matches()) return INCLUDE; - } - if (s.matches("^\\s*!(includedef)\\b.*")) { + + if (PATTERN_INCLUDE_DEF.matcher(s).matches()) return INCLUDE_DEF; - } - if (s.matches("^\\s*!(import)\\b.*")) { + + if (PATTERN_IMPORT.matcher(s).matches()) return IMPORT; - } - if (s.matches("^\\s*!startsub\\s+.*")) { + + if (PATTERN_STARTSUB.matcher(s).matches()) return STARTSUB; - } - if (s.matches("^\\s*!endsub\\b.*")) { + + if (PATTERN_ENDSUB.matcher(s).matches()) return ENDSUB; - } - if (s.matches("^\\s*!includesub\\b.*")) { + + if (PATTERN_INCLUDESUB.matcher(s).matches()) return INCLUDESUB; - } - if (s.matches("^\\s*!(log)\\b.*")) { + + if (PATTERN_LOG.matcher(s).matches()) return LOG; - } - if (s.matches("^\\s*!(dump_memory)\\b.*")) { + + if (PATTERN_DUMP_MEMORY.matcher(s).matches()) return DUMP_MEMORY; - } + return PLAIN; } diff --git a/src/net/sourceforge/plantuml/tim/TContext.java b/src/net/sourceforge/plantuml/tim/TContext.java index 23c43aa075d..30f2f0b9ff6 100644 --- a/src/net/sourceforge/plantuml/tim/TContext.java +++ b/src/net/sourceforge/plantuml/tim/TContext.java @@ -97,6 +97,7 @@ import net.sourceforge.plantuml.tim.stdlib.FileExists; import net.sourceforge.plantuml.tim.stdlib.Filename; import net.sourceforge.plantuml.tim.stdlib.FunctionExists; +import net.sourceforge.plantuml.tim.stdlib.GetAllTheme; import net.sourceforge.plantuml.tim.stdlib.GetJsonKey; import net.sourceforge.plantuml.tim.stdlib.GetJsonType; import net.sourceforge.plantuml.tim.stdlib.GetVariableValue; @@ -122,6 +123,7 @@ import net.sourceforge.plantuml.tim.stdlib.Newline; import net.sourceforge.plantuml.tim.stdlib.Now; import net.sourceforge.plantuml.tim.stdlib.Ord; +import net.sourceforge.plantuml.tim.stdlib.RandomFunction; import net.sourceforge.plantuml.tim.stdlib.RetrieveProcedure; import net.sourceforge.plantuml.tim.stdlib.ReverseColor; import net.sourceforge.plantuml.tim.stdlib.ReverseHsluvColor; @@ -208,6 +210,8 @@ private void addStandardFunctions(Defines defines) { functionsSet.addFunction(new LogicalNor()); functionsSet.addFunction(new LogicalNxor()); functionsSet.addFunction(new Ord()); + functionsSet.addFunction(new RandomFunction()); + functionsSet.addFunction(new GetAllTheme()); // %standard_exists_function // %str_replace // !exit diff --git a/src/net/sourceforge/plantuml/tim/TFunction.java b/src/net/sourceforge/plantuml/tim/TFunction.java index 02899691326..b608b400697 100644 --- a/src/net/sourceforge/plantuml/tim/TFunction.java +++ b/src/net/sourceforge/plantuml/tim/TFunction.java @@ -49,9 +49,6 @@ public interface TFunction { public TFunctionType getFunctionType(); - public void executeProcedure(TContext context, TMemory memory, LineLocation location, String s) - throws EaterException, EaterExceptionLocated; - public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List args, Map named) throws EaterException, EaterExceptionLocated; diff --git a/src/net/sourceforge/plantuml/tim/TFunctionImpl.java b/src/net/sourceforge/plantuml/tim/TFunctionImpl.java index dbdf7eb1aa7..54183810b74 100644 --- a/src/net/sourceforge/plantuml/tim/TFunctionImpl.java +++ b/src/net/sourceforge/plantuml/tim/TFunctionImpl.java @@ -69,6 +69,7 @@ public TFunctionImpl(String functionName, List args, boolean this.functionType = functionType; } + @Override public boolean canCover(int nbArg, Set namedArguments) { for (String n : namedArguments) if (signature.getNamedArguments().contains(n) == false) @@ -130,18 +131,7 @@ public void addBody(StringLocated s) throws EaterExceptionLocated { } } - public void executeProcedure(TContext context, TMemory memory, LineLocation location, String s) - throws EaterException, EaterExceptionLocated { - final EaterFunctionCall call = new EaterFunctionCall(new StringLocated(s, location), - context.isLegacyDefine(signature.getFunctionName()), unquoted); - call.analyze(context, memory); - final String endOfLine = call.getEndOfLine(); - final List args = call.getValues(); - final Map named = call.getNamedArguments(); - executeProcedureInternal(context, memory, args, named); - context.appendEndOfLine(endOfLine); - } - + @Override public void executeProcedureInternal(TContext context, TMemory memory, List args, Map named) throws EaterException, EaterExceptionLocated { if (functionType != TFunctionType.PROCEDURE && functionType != TFunctionType.LEGACY_DEFINELONG) @@ -151,8 +141,9 @@ public void executeProcedureInternal(TContext context, TMemory memory, List args, - Map named) throws EaterException, EaterExceptionLocated { + @Override + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, + List args, Map named) throws EaterException, EaterExceptionLocated { if (functionType == TFunctionType.LEGACY_DEFINE) return executeReturnLegacyDefine(location, context, memory, args); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/AlwaysFalse.java b/src/net/sourceforge/plantuml/tim/stdlib/AlwaysFalse.java index c06523e0098..0c73b754a6c 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/AlwaysFalse.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/AlwaysFalse.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%false", 0); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0; } - + + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { return TValue.fromBoolean(false); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/AlwaysTrue.java b/src/net/sourceforge/plantuml/tim/stdlib/AlwaysTrue.java index 90ed2c7c19f..66ec893af2c 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/AlwaysTrue.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/AlwaysTrue.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%true", 0); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { return TValue.fromBoolean(true); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java index 3282983caff..5d9107a92c8 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/CallUserFunction.java @@ -53,10 +53,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%call_user_func", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg > 0; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String fname = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Chr.java b/src/net/sourceforge/plantuml/tim/stdlib/Chr.java index 622230500e4..cdd7e139add 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Chr.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Chr.java @@ -52,15 +52,17 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%chr", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { try { - final char value = (char) values.get(0).toInt(); - return TValue.fromString("" + value); + final String value = String.valueOf(Character.toChars(values.get(0).toInt())); + return TValue.fromString(value); } catch (Throwable t) { return TValue.fromString("\0"); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Darken.java b/src/net/sourceforge/plantuml/tim/stdlib/Darken.java index bb5d05a7b6d..e053ac6c75c 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Darken.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Darken.java @@ -56,10 +56,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%darken", 2); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String colorString = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java index 0140a6385be..1c18155d9b3 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/DateFunction.java @@ -54,10 +54,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%date", 2); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0 || nbArg == 1 || nbArg == 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { if (values.size() == 0) diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Dec2hex.java b/src/net/sourceforge/plantuml/tim/stdlib/Dec2hex.java index 1c317299699..3dc6f7b634a 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Dec2hex.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Dec2hex.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%dec2hex", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { try { diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Dirpath.java b/src/net/sourceforge/plantuml/tim/stdlib/Dirpath.java index 54fabb43d62..1c918c4e8a1 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Dirpath.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Dirpath.java @@ -59,10 +59,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%dirpath", 0); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { if (value == null) { diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Eval.java b/src/net/sourceforge/plantuml/tim/stdlib/Eval.java index 7175e2ffc06..ee7ad6e4618 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Eval.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Eval.java @@ -53,10 +53,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%eval", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String exp = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Feature.java b/src/net/sourceforge/plantuml/tim/stdlib/Feature.java index 088958f9ee9..f79b4ed4dda 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Feature.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Feature.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%feature", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String arg = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/FileExists.java b/src/net/sourceforge/plantuml/tim/stdlib/FileExists.java index 47355c4dd44..d7b68e42309 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/FileExists.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/FileExists.java @@ -53,10 +53,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%file_exists", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { // ::comment when __CORE__ diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Filename.java b/src/net/sourceforge/plantuml/tim/stdlib/Filename.java index 02e0f2d565c..49fd6b6c848 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Filename.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Filename.java @@ -59,10 +59,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%filename", 0); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { if (value == null) { diff --git a/src/net/sourceforge/plantuml/tim/stdlib/FunctionExists.java b/src/net/sourceforge/plantuml/tim/stdlib/FunctionExists.java index c7ccef03003..43442f82ec5 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/FunctionExists.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/FunctionExists.java @@ -53,10 +53,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%function_exists", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String name = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/GetAllTheme.java b/src/net/sourceforge/plantuml/tim/stdlib/GetAllTheme.java new file mode 100644 index 00000000000..e0b2d0281a7 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/stdlib/GetAllTheme.java @@ -0,0 +1,78 @@ +/* ======================================================================== + * 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.tim.stdlib; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import net.sourceforge.plantuml.log.Logme; +import net.sourceforge.plantuml.json.JsonArray; +import net.sourceforge.plantuml.theme.ThemeUtils; +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; +import net.sourceforge.plantuml.utils.LineLocation; + +public class GetAllTheme extends SimpleReturnFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%get_all_theme", 0); + } + + @Override + public boolean canCover(int nbArg, Set namedArgument) { + return nbArg == 0; + } + + @Override + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { + final JsonArray result = new JsonArray(); + try { + for (String theme : ThemeUtils.getAllThemeNames()) { + result.add(theme); + } + return TValue.fromJson(result); + } catch (IOException e) { + Logme.error(e); + return TValue.fromJson(result); + } + } +} diff --git a/src/net/sourceforge/plantuml/tim/stdlib/GetJsonKey.java b/src/net/sourceforge/plantuml/tim/stdlib/GetJsonKey.java index 77824aabc53..244824ee322 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/GetJsonKey.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/GetJsonKey.java @@ -55,10 +55,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%get_json_keys", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final TValue data = values.get(0); @@ -76,9 +78,11 @@ public TValue executeReturnFunction(TContext context, TMemory memory, LineLocati final JsonArray array = (JsonArray) json; final JsonArray result = new JsonArray(); for (JsonValue tmp : array) { - final JsonObject object = (JsonObject) tmp; - for (String key : object.names()) - result.add(key); + if (tmp.isObject()) { + final JsonObject object = (JsonObject) tmp; + for (String key : object.names()) + result.add(key); + } } return TValue.fromJson(result); } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/GetJsonType.java b/src/net/sourceforge/plantuml/tim/stdlib/GetJsonType.java index e44b7ce55f2..33d3b5b6489 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/GetJsonType.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/GetJsonType.java @@ -53,10 +53,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%get_json_type", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final TValue data = values.get(0); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/GetVariableValue.java b/src/net/sourceforge/plantuml/tim/stdlib/GetVariableValue.java index ac926179350..082921acbe2 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/GetVariableValue.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/GetVariableValue.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%get_variable_value", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String name = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/GetVersion.java b/src/net/sourceforge/plantuml/tim/stdlib/GetVersion.java index 960fd1fb27f..c206538cbf9 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/GetVersion.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/GetVersion.java @@ -53,10 +53,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%version", 0); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { return TValue.fromString(Version.versionString()); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Getenv.java b/src/net/sourceforge/plantuml/tim/stdlib/Getenv.java index 6e947d0501c..88fd8a6382c 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Getenv.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Getenv.java @@ -53,10 +53,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%getenv", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { // ::comment when __CORE__ diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Hex2dec.java b/src/net/sourceforge/plantuml/tim/stdlib/Hex2dec.java index 622023df22e..27f5102486a 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Hex2dec.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Hex2dec.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%hex2dec", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { try { diff --git a/src/net/sourceforge/plantuml/tim/stdlib/HslColor.java b/src/net/sourceforge/plantuml/tim/stdlib/HslColor.java index fae231c88c4..cc1173882c3 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/HslColor.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/HslColor.java @@ -55,10 +55,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%hsl_color", 3); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 3 || nbArg == 4; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final int h = values.get(0).toInt(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/IntVal.java b/src/net/sourceforge/plantuml/tim/stdlib/IntVal.java index b9540e5dd1c..27e19db7ab4 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/IntVal.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/IntVal.java @@ -53,10 +53,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%intval", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String s = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/InvokeProcedure.java b/src/net/sourceforge/plantuml/tim/stdlib/InvokeProcedure.java index c9079986afc..5331f7b2e19 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/InvokeProcedure.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/InvokeProcedure.java @@ -54,6 +54,7 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%invoke_procedure", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg > 0; } @@ -62,11 +63,7 @@ public TFunctionType getFunctionType() { return TFunctionType.PROCEDURE; } - public void executeProcedure(TContext context, TMemory memory, LineLocation location, String s) - throws EaterException, EaterExceptionLocated { - throw new UnsupportedOperationException(); - } - + @Override public void executeProcedureInternal(TContext context, TMemory memory, List args, Map named) throws EaterException, EaterExceptionLocated { final String fname = args.get(0).toString(); @@ -79,6 +76,7 @@ public void executeProcedureInternal(TContext context, TMemory memory, List values, Map named) { throw new UnsupportedOperationException(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/IsDark.java b/src/net/sourceforge/plantuml/tim/stdlib/IsDark.java index 23a4ccc6724..efc4299da9b 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/IsDark.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/IsDark.java @@ -56,10 +56,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%is_dark", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String colorString = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/IsLight.java b/src/net/sourceforge/plantuml/tim/stdlib/IsLight.java index b75e781efc7..deff7b24d9a 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/IsLight.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/IsLight.java @@ -56,10 +56,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%is_light", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String colorString = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/JsonKeyExists.java b/src/net/sourceforge/plantuml/tim/stdlib/JsonKeyExists.java index 64be7d60f2d..85eafc5400f 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/JsonKeyExists.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/JsonKeyExists.java @@ -54,10 +54,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%json_key_exists", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final TValue arg0 = values.get(0); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Lighten.java b/src/net/sourceforge/plantuml/tim/stdlib/Lighten.java index 8519054c3b9..e4de200feef 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Lighten.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Lighten.java @@ -56,10 +56,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%lighten", 2); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String colorString = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/LoadJson.java b/src/net/sourceforge/plantuml/tim/stdlib/LoadJson.java index 19dffd4622d..a5021562ce6 100755 --- a/src/net/sourceforge/plantuml/tim/stdlib/LoadJson.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/LoadJson.java @@ -102,10 +102,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%load_json", 3); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1 || nbArg == 2 || nbArg == 3; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String path = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/LogicalAnd.java b/src/net/sourceforge/plantuml/tim/stdlib/LogicalAnd.java index b674b4b4688..4fe2d2a143d 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/LogicalAnd.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/LogicalAnd.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%and", 2); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg >= 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { for (TValue v : values) diff --git a/src/net/sourceforge/plantuml/tim/stdlib/LogicalNand.java b/src/net/sourceforge/plantuml/tim/stdlib/LogicalNand.java index c4f5ea8e0d0..9b018d3c072 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/LogicalNand.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/LogicalNand.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%nand", 2); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg >= 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { for (TValue v : values) diff --git a/src/net/sourceforge/plantuml/tim/stdlib/LogicalNor.java b/src/net/sourceforge/plantuml/tim/stdlib/LogicalNor.java index de7a99644aa..95c4e3c6ddd 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/LogicalNor.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/LogicalNor.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%nor", 2); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg >= 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { for (TValue v : values) diff --git a/src/net/sourceforge/plantuml/tim/stdlib/LogicalNot.java b/src/net/sourceforge/plantuml/tim/stdlib/LogicalNot.java index b2385ee3818..ca6d5ab3a56 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/LogicalNot.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/LogicalNot.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%not", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final boolean arg = values.get(0).toBoolean(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/LogicalNxor.java b/src/net/sourceforge/plantuml/tim/stdlib/LogicalNxor.java index 61f8ab06a56..e83c05b1eef 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/LogicalNxor.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/LogicalNxor.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%nxor", 2); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg >= 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { int cpt = 0; diff --git a/src/net/sourceforge/plantuml/tim/stdlib/LogicalOr.java b/src/net/sourceforge/plantuml/tim/stdlib/LogicalOr.java index 3460a368301..41026ac89d6 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/LogicalOr.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/LogicalOr.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%or", 2); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg >= 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { for (TValue v : values) diff --git a/src/net/sourceforge/plantuml/tim/stdlib/LogicalXor.java b/src/net/sourceforge/plantuml/tim/stdlib/LogicalXor.java index 1736b6cde30..14ad07a5e5d 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/LogicalXor.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/LogicalXor.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%xor", 2); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg >= 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { int cpt = 0; diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Lower.java b/src/net/sourceforge/plantuml/tim/stdlib/Lower.java index 463c272d839..d0dbcb7315a 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Lower.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Lower.java @@ -50,10 +50,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%lower", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) { return TValue.fromString(values.get(0).toString().toLowerCase()); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Newline.java b/src/net/sourceforge/plantuml/tim/stdlib/Newline.java index 8b3cc66597a..2f5c7abb71a 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Newline.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Newline.java @@ -50,10 +50,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%newline", 0); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) { return TValue.fromString("\n"); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Now.java b/src/net/sourceforge/plantuml/tim/stdlib/Now.java index 866e90f0ede..c90eb25d104 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Now.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Now.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%now", 0); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 0; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final long now = System.currentTimeMillis() / 1000L; diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Ord.java b/src/net/sourceforge/plantuml/tim/stdlib/Ord.java index 6e526218901..bf0f7d767f3 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Ord.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Ord.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%ord", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { try { diff --git a/src/net/sourceforge/plantuml/tim/stdlib/RandomFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/RandomFunction.java new file mode 100644 index 00000000000..a165f00a400 --- /dev/null +++ b/src/net/sourceforge/plantuml/tim/stdlib/RandomFunction.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.tim.stdlib; + +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TFunctionSignature; +import net.sourceforge.plantuml.tim.TMemory; +import net.sourceforge.plantuml.tim.expression.TValue; +import net.sourceforge.plantuml.utils.LineLocation; + +public class RandomFunction extends SimpleReturnFunction { + + public TFunctionSignature getSignature() { + return new TFunctionSignature("%random", 2); + } + + @Override + public boolean canCover(int nbArg, Set namedArgument) { + return nbArg == 0 || nbArg == 1 || nbArg == 2; + } + + private final Random random = new Random(); + + @Override + public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, + Map named) throws EaterException, EaterExceptionLocated { + switch (values.size()) { + case 0: + return TValue.fromInt(random.nextInt(2)); + + case 1: + final Integer mx = values.get(0).toInt(); + return TValue.fromInt(random.nextInt(mx)); + + case 2: + final Integer min = values.get(0).toInt(); + final Integer max = values.get(1).toInt(); + return TValue.fromInt(random.nextInt(max - min) + min); + + default: + throw EaterException.located("Error on Random: Too many argument"); + } + } +} diff --git a/src/net/sourceforge/plantuml/tim/stdlib/RetrieveProcedure.java b/src/net/sourceforge/plantuml/tim/stdlib/RetrieveProcedure.java index 94a98ec8158..fa75ab9466b 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/RetrieveProcedure.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/RetrieveProcedure.java @@ -54,10 +54,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%retrieve_procedure", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg > 0; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String fname = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/ReverseColor.java b/src/net/sourceforge/plantuml/tim/stdlib/ReverseColor.java index 3a5d5e7184d..6084e16d1cf 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/ReverseColor.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/ReverseColor.java @@ -55,10 +55,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%reverse_color", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String colorString = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/ReverseHsluvColor.java b/src/net/sourceforge/plantuml/tim/stdlib/ReverseHsluvColor.java index d9599aecc35..6a42843f74f 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/ReverseHsluvColor.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/ReverseHsluvColor.java @@ -55,10 +55,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%reverse_hsluv_color", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String colorString = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java b/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java index 31897f6087b..a35ec7786e7 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/SetVariableValue.java @@ -53,10 +53,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%set_variable_value", 2); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { // if (memory instanceof TMemoryLocal) { diff --git a/src/net/sourceforge/plantuml/tim/stdlib/SimpleReturnFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/SimpleReturnFunction.java index 14607759703..f276bcbdd26 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/SimpleReturnFunction.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/SimpleReturnFunction.java @@ -51,11 +51,7 @@ final public TFunctionType getFunctionType() { return TFunctionType.RETURN_FUNCTION; } - final public void executeProcedure(TContext context, TMemory memory, LineLocation location, String s) - throws EaterException { - throw new UnsupportedOperationException(); - } - + @Override final public void executeProcedureInternal(TContext context, TMemory memory, List args, Map named) throws EaterException { throw new UnsupportedOperationException(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Size.java b/src/net/sourceforge/plantuml/tim/stdlib/Size.java index ecc0891bfd5..0794bca42bd 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Size.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Size.java @@ -55,10 +55,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%size", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final TValue value = values.get(0); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/SplitStr.java b/src/net/sourceforge/plantuml/tim/stdlib/SplitStr.java index 2158332eed1..d9aa2fdedfc 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/SplitStr.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/SplitStr.java @@ -54,10 +54,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%splitstr", 3); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final JsonArray result = new JsonArray(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/StringFunction.java b/src/net/sourceforge/plantuml/tim/stdlib/StringFunction.java index ef87d8cb94b..f2b972a8058 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/StringFunction.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/StringFunction.java @@ -50,10 +50,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%string", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) { return TValue.fromString(values.get(0).toString()); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java b/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java index 432c6a42d62..3e1578fba23 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Strlen.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%strlen", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { return TValue.fromInt(values.get(0).toString().length()); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Strpos.java b/src/net/sourceforge/plantuml/tim/stdlib/Strpos.java index 7b7b58f1b91..09a5c43a995 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Strpos.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Strpos.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%strpos", 2); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 2; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String full = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Substr.java b/src/net/sourceforge/plantuml/tim/stdlib/Substr.java index 2a94fcab6f5..ba0c0e8ce64 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Substr.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Substr.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%substr", 3); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 2 || nbArg == 3; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String full = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/Upper.java b/src/net/sourceforge/plantuml/tim/stdlib/Upper.java index f3901fb8a9c..98caf89ffe4 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/Upper.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/Upper.java @@ -50,10 +50,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%upper", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) { return TValue.fromString(values.get(0).toString().toUpperCase()); diff --git a/src/net/sourceforge/plantuml/tim/stdlib/VariableExists.java b/src/net/sourceforge/plantuml/tim/stdlib/VariableExists.java index f1911011405..a63730447f5 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/VariableExists.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/VariableExists.java @@ -52,10 +52,12 @@ public TFunctionSignature getSignature() { return new TFunctionSignature("%variable_exists", 1); } + @Override public boolean canCover(int nbArg, Set namedArgument) { return nbArg == 1; } + @Override public TValue executeReturnFunction(TContext context, TMemory memory, LineLocation location, List values, Map named) throws EaterException, EaterExceptionLocated { final String name = values.get(0).toString(); diff --git a/src/net/sourceforge/plantuml/timingdiagram/TimingDiagram.java b/src/net/sourceforge/plantuml/timingdiagram/TimingDiagram.java index 0847489b3dd..03d10d12785 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/TimingDiagram.java +++ b/src/net/sourceforge/plantuml/timingdiagram/TimingDiagram.java @@ -99,11 +99,11 @@ public TimingDiagram(UmlSource source) { 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/timingdiagram/command/CommandAnalog.java b/src/net/sourceforge/plantuml/timingdiagram/command/CommandAnalog.java index ebbaf7a68e1..2c16fc6c293 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/command/CommandAnalog.java +++ b/src/net/sourceforge/plantuml/timingdiagram/command/CommandAnalog.java @@ -43,6 +43,7 @@ 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.timingdiagram.PlayerAnalog; import net.sourceforge.plantuml.timingdiagram.TimingDiagram; import net.sourceforge.plantuml.utils.LineLocation; @@ -62,9 +63,7 @@ private static IRegex getRegexConcat() { new RegexLeaf("analog"), // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("FULL", "[%g]([^%g]+)[%g]"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceOneOrMore(), // + StereotypePattern.optional("STEREOTYPE"), // new RegexOptional(// new RegexConcat( // new RegexLeaf("between"), // @@ -78,9 +77,7 @@ private static IRegex getRegexConcat() { new RegexLeaf("as"), // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("CODE", "([%pLN_.@]+)"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREOTYPE2", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREOTYPE2"), // RegexLeaf.end()); } diff --git a/src/net/sourceforge/plantuml/timingdiagram/command/CommandBinary.java b/src/net/sourceforge/plantuml/timingdiagram/command/CommandBinary.java index 8feb151ab79..e46b9d0771f 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/command/CommandBinary.java +++ b/src/net/sourceforge/plantuml/timingdiagram/command/CommandBinary.java @@ -43,6 +43,7 @@ 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.timingdiagram.TimingDiagram; import net.sourceforge.plantuml.utils.LineLocation; @@ -61,15 +62,11 @@ private static IRegex getRegexConcat() { new RegexLeaf("binary"), // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("FULL", "[%g]([^%g]+)[%g]"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceOneOrMore(), // + StereotypePattern.optional("STEREOTYPE"), // new RegexLeaf("as"), // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("CODE", "([%pLN_.@]+)"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREOTYPE2", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREOTYPE2"), // RegexLeaf.end()); } diff --git a/src/net/sourceforge/plantuml/timingdiagram/command/CommandRobustConcise.java b/src/net/sourceforge/plantuml/timingdiagram/command/CommandRobustConcise.java index 432b0fde1f6..51716350c3f 100644 --- a/src/net/sourceforge/plantuml/timingdiagram/command/CommandRobustConcise.java +++ b/src/net/sourceforge/plantuml/timingdiagram/command/CommandRobustConcise.java @@ -43,6 +43,7 @@ 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.timingdiagram.TimingDiagram; import net.sourceforge.plantuml.timingdiagram.TimingStyle; import net.sourceforge.plantuml.utils.LineLocation; @@ -64,15 +65,11 @@ private static IRegex getRegexConcat() { new RegexOptional( // new RegexConcat( // new RegexLeaf("FULL", "[%g]([^%g]+)[%g]"), // - RegexLeaf.spaceOneOrMore(), // - new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREOTYPE"), // new RegexLeaf("as"), // RegexLeaf.spaceOneOrMore())), // new RegexLeaf("CODE", "([%pLN_.@]+)"), // - RegexLeaf.spaceZeroOrMore(), // - new RegexLeaf("STEREOTYPE2", "(\\<\\<.*\\>\\>)?"), // - RegexLeaf.spaceZeroOrMore(), // + StereotypePattern.optional("STEREOTYPE2"), // RegexLeaf.end()); } diff --git a/src/net/sourceforge/plantuml/version/PSystemLicense.java b/src/net/sourceforge/plantuml/version/PSystemLicense.java index 50cebbdee89..d3ecb24e8ef 100644 --- a/src/net/sourceforge/plantuml/version/PSystemLicense.java +++ b/src/net/sourceforge/plantuml/version/PSystemLicense.java @@ -76,7 +76,7 @@ public DiagramDescription getDescription() { } @Override - public void exportDiagramGraphic(UGraphic ug) { + public void exportDiagramGraphic(UGraphic ug, FileFormatOption fileFormatOption) { final LicenseInfo licenseInfo = LicenseInfo.retrieveQuick(); getTextBlock(licenseInfo).drawU(ug); } diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index 94229743791..50dd4b24ed0 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -46,7 +46,7 @@ public class Version { // Warning, "version" should be the same in gradle.properties and Version.java // Any idea anyone how to magically synchronize those :-) ? - private static final String version = "1.2023.13beta3"; + private static final String version = "1.2024.4beta1"; public static String versionString() { return version; @@ -80,7 +80,7 @@ public static String turningId() { } public static long compileTime() { - return 1697809794384L; + return 1708026005000L; } public static String compileTimeString() { diff --git a/src/net/sourceforge/plantuml/version/version.txt b/src/net/sourceforge/plantuml/version/version.txt deleted file mode 100644 index 3dfd733c501..00000000000 --- a/src/net/sourceforge/plantuml/version/version.txt +++ /dev/null @@ -1,2 +0,0 @@ -1.2023.6-beta-3 -1680642535564 \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/wbs/CommandWBSLink.java b/src/net/sourceforge/plantuml/wbs/CommandWBSLink.java index a8ca6d4692a..0a88bb07e38 100644 --- a/src/net/sourceforge/plantuml/wbs/CommandWBSLink.java +++ b/src/net/sourceforge/plantuml/wbs/CommandWBSLink.java @@ -46,6 +46,7 @@ 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 CommandWBSLink extends SingleLineCommand2 { @@ -64,9 +65,7 @@ static IRegex getRegexConcat() { new RegexLeaf("CODE2", "([%pLN_]+)"), // 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/wbs/WBSDiagram.java b/src/net/sourceforge/plantuml/wbs/WBSDiagram.java index 6d3e036635f..192d9e3b481 100644 --- a/src/net/sourceforge/plantuml/wbs/WBSDiagram.java +++ b/src/net/sourceforge/plantuml/wbs/WBSDiagram.java @@ -92,11 +92,11 @@ public WBSDiagram(UmlSource source) { 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/wire/WireDiagram.java b/src/net/sourceforge/plantuml/wire/WireDiagram.java index 12cf30cc34d..7919be884e1 100644 --- a/src/net/sourceforge/plantuml/wire/WireDiagram.java +++ b/src/net/sourceforge/plantuml/wire/WireDiagram.java @@ -76,11 +76,11 @@ public WireDiagram(UmlSource source) { 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/stdlib/awslib14-abx.repx b/stdlib/awslib14-abx.repx index df02cc14234..515704a8794 100644 Binary files a/stdlib/awslib14-abx.repx and b/stdlib/awslib14-abx.repx differ diff --git a/stdlib/azure-abx.repx b/stdlib/azure-abx.repx index ec8a89f67de..d765e254e52 100644 Binary files a/stdlib/azure-abx.repx and b/stdlib/azure-abx.repx differ diff --git a/stdlib/c4-abx.repx b/stdlib/c4-abx.repx index 24cd069abdd..10ef9117eb1 100644 Binary files a/stdlib/c4-abx.repx and b/stdlib/c4-abx.repx differ diff --git a/stdlib/edgy-abx.repx b/stdlib/edgy-abx.repx new file mode 100644 index 00000000000..d3ea483fefa Binary files /dev/null and b/stdlib/edgy-abx.repx differ diff --git a/stdlib/edgy-dex.repx b/stdlib/edgy-dex.repx new file mode 100644 index 00000000000..1c8a0e79762 --- /dev/null +++ b/stdlib/edgy-dex.repx @@ -0,0 +1 @@ +; \ No newline at end of file diff --git a/stdlib/eip-abx.repx b/stdlib/eip-abx.repx new file mode 100644 index 00000000000..79df260821e Binary files /dev/null and b/stdlib/eip-abx.repx differ diff --git a/stdlib/eip-dex.repx b/stdlib/eip-dex.repx new file mode 100644 index 00000000000..d550fd7b341 Binary files /dev/null and b/stdlib/eip-dex.repx differ diff --git a/stdlib/gcp-abx.repx b/stdlib/gcp-abx.repx new file mode 100644 index 00000000000..df8f296e8fe Binary files /dev/null and b/stdlib/gcp-abx.repx differ diff --git a/stdlib/gcp-dex.repx b/stdlib/gcp-dex.repx new file mode 100644 index 00000000000..e7efda0e3f8 Binary files /dev/null and b/stdlib/gcp-dex.repx differ diff --git a/stdlib/home.repx b/stdlib/home.repx index 5a3cd00a5fd..f2ba66b23a3 100644 --- a/stdlib/home.repx +++ b/stdlib/home.repx @@ -8,8 +8,12 @@ classy-c4 cloudinsight cloudogu domainstory +edgy +eip elastic +gcp kubernetes +k8s logos material office diff --git a/stdlib/k8s-abx.repx b/stdlib/k8s-abx.repx new file mode 100644 index 00000000000..c8f870c8c7d Binary files /dev/null and b/stdlib/k8s-abx.repx differ diff --git a/stdlib/k8s-dex.repx b/stdlib/k8s-dex.repx new file mode 100644 index 00000000000..1a528ba86a3 Binary files /dev/null and b/stdlib/k8s-dex.repx differ diff --git a/stdlib/office-abx.repx b/stdlib/office-abx.repx index f0069b29f55..7a4ee4f97d8 100644 Binary files a/stdlib/office-abx.repx and b/stdlib/office-abx.repx differ diff --git a/test/net/sourceforge/plantuml/LoadJsonTest.java b/test/net/sourceforge/plantuml/LoadJsonTest.java index cd5302be774..3ff4c3bb943 100644 --- a/test/net/sourceforge/plantuml/LoadJsonTest.java +++ b/test/net/sourceforge/plantuml/LoadJsonTest.java @@ -1,9 +1,9 @@ package net.sourceforge.plantuml; import static java.nio.charset.StandardCharsets.UTF_8; -import static net.sourceforge.plantuml.test.TestUtils.writeUtf8File; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.util.Lists.newArrayList; +import static test.utils.TestUtils.writeUtf8File; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; diff --git a/test/net/sourceforge/plantuml/PipeTest.java b/test/net/sourceforge/plantuml/PipeTest.java index a975bf26ceb..6db686723d7 100644 --- a/test/net/sourceforge/plantuml/PipeTest.java +++ b/test/net/sourceforge/plantuml/PipeTest.java @@ -127,7 +127,7 @@ static List managePipeTestCases() { false, false)); l.add(TestCase.of("-syntax", "@startuml\na->b\n@enduml\n@startuml\na->b\nb->c\n@enduml\n", "SEQUENCE\n(2 participants)\nSEQUENCE\n(3 participants)\n", Verification.EXACT, false, false)); - l.add(TestCase.of("-syntax", "@startgantt\n[a] lasts 1 day\n@endgantt", "OTHER\n(Project)\n", + l.add(TestCase.of("-syntax", "@startgantt\n[a] lasts 1 day\n@endgantt", "OTHER\n(Gantt)\n", Verification.EXACT, false, false)); // invalid syntax diff --git a/test/net/sourceforge/plantuml/TestFileDirOption.java b/test/net/sourceforge/plantuml/TestFileDirOption.java index d68165ef690..5e71d19373f 100644 --- a/test/net/sourceforge/plantuml/TestFileDirOption.java +++ b/test/net/sourceforge/plantuml/TestFileDirOption.java @@ -1,9 +1,9 @@ package net.sourceforge.plantuml; import static java.nio.charset.StandardCharsets.UTF_8; -import static net.sourceforge.plantuml.test.TestUtils.writeUtf8File; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.util.Lists.newArrayList; +import static test.utils.TestUtils.writeUtf8File; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; diff --git a/test/net/sourceforge/plantuml/help/CommandHelpThemeTest.java b/test/net/sourceforge/plantuml/help/CommandHelpThemeTest.java new file mode 100644 index 00000000000..caef807b615 --- /dev/null +++ b/test/net/sourceforge/plantuml/help/CommandHelpThemeTest.java @@ -0,0 +1,23 @@ +package net.sourceforge.plantuml.help; + +import static org.assertj.core.api.Assertions.assertThat; +import static test.utils.PlantUmlTestUtils.exportDiagram; + +import org.junit.jupiter.api.Test; + +class CommandHelpThemeTest { + + @Test + public void command_help_theme() throws Exception { + + final String output = exportDiagram( + "@startuml", + "help themes", + "@enduml" + ).asString(); + + assertThat(output) + .contains("Help on themes") + .contains("bluegray", "hacker"); + } +} \ No newline at end of file diff --git a/test/net/sourceforge/plantuml/tim/EaterTest.java b/test/net/sourceforge/plantuml/tim/EaterTest.java index 3dbdbe57f15..fc370e459ed 100644 --- a/test/net/sourceforge/plantuml/tim/EaterTest.java +++ b/test/net/sourceforge/plantuml/tim/EaterTest.java @@ -31,7 +31,9 @@ class EaterTest { "'@startuml\n!$a={\"k\": \"exampleValue\"}\ntitle $a.k\na -> b\n@enduml\n' , exampleValue", "'@startuml\n!$a=[1, 2, 3]\ntitle xx $a[2] yy\na -> a\n' , xx 3 yy", "'@startuml\ntitle\n!foreach $i in [1, 2, 3]\nxx $i yy\n!endfor\nendtitle\na -> a\n' , xx 2 yy", - "'@startuml\ntitle\n!foreach $i in [\"a\", \"b\", \"c\"]\nxx $i yy\n!endfor\nendtitle\na -> a\n' , xx b yy", + "'@startuml\ntitle\n!foreach $i in [\"a\", \"b\", \"c\"]\nxx $i yy\n!endfor\nendtitle\na -> a\n' , xx b yy", +// TODO: fix code to allow test to access on stdlib, the corresponding (not working) test is here: +// "'@startuml\nstdlib\n@enduml', archimate", }) void Test_EaterTest(String input, String expected) throws Exception { assertRenderExpectedOutput(input, expected); diff --git a/test/net/sourceforge/plantuml/tim/stdlib/ChrTest.java b/test/net/sourceforge/plantuml/tim/stdlib/ChrTest.java index cf3886aaaab..6659ecd950f 100644 --- a/test/net/sourceforge/plantuml/tim/stdlib/ChrTest.java +++ b/test/net/sourceforge/plantuml/tim/stdlib/ChrTest.java @@ -1,29 +1,31 @@ package net.sourceforge.plantuml.tim.stdlib; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Collections; -import java.util.List; +import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutputFromInput; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.IndicativeSentencesGeneration; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.tim.EaterExceptionLocated; -import net.sourceforge.plantuml.tim.expression.TValue; +import net.sourceforge.plantuml.tim.TFunction; /** * Tests the builtin function %chr. */ -class ChrTest { +@IndicativeSentencesGeneration(separator = ": ", generator = ReplaceUnderscores.class) +class ChrTest { + TFunction cut = new Chr(); + final String cutName = "Chr"; /** * Tests chr according to a list of input / expected output * * @throws EaterException should not * @throws EaterExceptionLocated should not */ - @ParameterizedTest + @ParameterizedTest(name = "[{index}] " + cutName + "({0}) = ''{1}''") @CsvSource(nullValues = "null", value = { " 65 , A ", " 9 , '\t' ", @@ -32,15 +34,11 @@ class ChrTest { " 34 , '\"' ", " 224 , à ", " 233 , é ", -// TODO: fix `%chr` to allow Unicode chars, the corresponding tests are here: -// " 128512 , 😀 ", -// " 128512 , \uD83D\uDE00 ", +// DONE: fix `%chr` to allow Unicode chars, the corresponding tests are here: + " 128512 , 😀 ", + " 128512 , \uD83D\uDE00 ", }) - void executeReturnFunctionChrTest(Integer input, String expected) throws EaterException, EaterExceptionLocated { - Chr cut = new Chr(); - - List values = Collections.singletonList(TValue.fromInt(input)); - TValue tValue = cut.executeReturnFunction(null, null, null, values, null); - assertEquals(expected, tValue.toString()); + void Test_with_Integer(Integer input, String expected) throws EaterException, EaterExceptionLocated { + assertTimExpectedOutputFromInput(cut, input, expected); } } \ No newline at end of file diff --git a/test/net/sourceforge/plantuml/tim/stdlib/FeatureTest.java b/test/net/sourceforge/plantuml/tim/stdlib/FeatureTest.java index 74bdf712af7..52507fb51ba 100644 --- a/test/net/sourceforge/plantuml/tim/stdlib/FeatureTest.java +++ b/test/net/sourceforge/plantuml/tim/stdlib/FeatureTest.java @@ -1,8 +1,8 @@ package net.sourceforge.plantuml.tim.stdlib; -import static net.sourceforge.plantuml.test.JunitUtils.StringJsonConverter; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutput; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutputFromInput; +import static test.utils.JunitUtils.StringJsonConverter; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; diff --git a/test/net/sourceforge/plantuml/tim/stdlib/GetAllThemeTest.java b/test/net/sourceforge/plantuml/tim/stdlib/GetAllThemeTest.java new file mode 100644 index 00000000000..c17bc33d22f --- /dev/null +++ b/test/net/sourceforge/plantuml/tim/stdlib/GetAllThemeTest.java @@ -0,0 +1,30 @@ +package net.sourceforge.plantuml.tim.stdlib; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collections; + +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.IndicativeSentencesGeneration; +import org.junit.jupiter.api.Test; + +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; +import net.sourceforge.plantuml.tim.TFunction; +import net.sourceforge.plantuml.tim.expression.TValue; + +/** + * Tests the builtin function. + */ +@IndicativeSentencesGeneration(separator = ": ", generator = ReplaceUnderscores.class) + +class GetAllThemeTest { + TFunction cut = new GetAllTheme(); + final String cutName = "GetAllTheme"; + + @Test + void Test_without_Param() throws EaterException, EaterExceptionLocated { + final TValue tValue = cut.executeReturnFunction(null, null, null, Collections.emptyList(), null); + assertThat(tValue.toString()).contains("_none_", "amiga", "vibrant"); + } +} diff --git a/test/net/sourceforge/plantuml/tim/stdlib/GetJsonKeyTest.java b/test/net/sourceforge/plantuml/tim/stdlib/GetJsonKeyTest.java index c9985befd64..80635e4569d 100644 --- a/test/net/sourceforge/plantuml/tim/stdlib/GetJsonKeyTest.java +++ b/test/net/sourceforge/plantuml/tim/stdlib/GetJsonKeyTest.java @@ -1,8 +1,8 @@ package net.sourceforge.plantuml.tim.stdlib; -import static net.sourceforge.plantuml.test.JunitUtils.StringJsonConverter; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutput; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutputFromInput; +import static test.utils.JunitUtils.StringJsonConverter; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; @@ -61,11 +61,11 @@ void Test_with_Integer(Integer input, String expected) throws EaterException, Ea " '{\"a\":\"abc\"}' , [\"a\"]", " '[{\"a\":[1, 2]}, {\"b\":[3, 4]}]' , '[\"a\",\"b\"]'", " '{\"a\":[1, 2], \"b\":\"abc\", \"b\":true}' , '[\"a\",\"b\",\"b\"]'", - // TODO: Manage Array with different type inside + // DONE: Manage Array with different type inside // Ref.: // - https://datatracker.ietf.org/doc/html/rfc8259#section-5 // - https://json-schema.org/understanding-json-schema/reference/array.html - //" '[3, \"different\", { \"types\" : \"of values\" }]', [\"types\"]", + " '[3, \"different\", { \"types\" : \"of values\" }]', [\"types\"]", }) void Test_with_Json(@ConvertWith(StringJsonConverter.class) JsonValue input, String expected) throws EaterException, EaterExceptionLocated { assertTimExpectedOutputFromInput(cut, input, expected); diff --git a/test/net/sourceforge/plantuml/tim/stdlib/GetJsonTypeTest.java b/test/net/sourceforge/plantuml/tim/stdlib/GetJsonTypeTest.java index 1b720c9e5cb..0fe35543c05 100644 --- a/test/net/sourceforge/plantuml/tim/stdlib/GetJsonTypeTest.java +++ b/test/net/sourceforge/plantuml/tim/stdlib/GetJsonTypeTest.java @@ -1,8 +1,8 @@ package net.sourceforge.plantuml.tim.stdlib; -import static net.sourceforge.plantuml.test.JunitUtils.StringJsonConverter; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutput; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutputFromInput; +import static test.utils.JunitUtils.StringJsonConverter; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; diff --git a/test/net/sourceforge/plantuml/tim/stdlib/LowerTest.java b/test/net/sourceforge/plantuml/tim/stdlib/LowerTest.java index d149c26b9f7..3b50a2d3000 100644 --- a/test/net/sourceforge/plantuml/tim/stdlib/LowerTest.java +++ b/test/net/sourceforge/plantuml/tim/stdlib/LowerTest.java @@ -1,8 +1,8 @@ package net.sourceforge.plantuml.tim.stdlib; -import static net.sourceforge.plantuml.test.JunitUtils.StringJsonConverter; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutput; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutputFromInput; +import static test.utils.JunitUtils.StringJsonConverter; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; diff --git a/test/net/sourceforge/plantuml/tim/stdlib/OrdTest.java b/test/net/sourceforge/plantuml/tim/stdlib/OrdTest.java index 3d4c2f2037b..4fd0411abc2 100644 --- a/test/net/sourceforge/plantuml/tim/stdlib/OrdTest.java +++ b/test/net/sourceforge/plantuml/tim/stdlib/OrdTest.java @@ -1,29 +1,31 @@ package net.sourceforge.plantuml.tim.stdlib; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Collections; -import java.util.List; +import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutputFromInput; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.IndicativeSentencesGeneration; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import net.sourceforge.plantuml.tim.EaterException; import net.sourceforge.plantuml.tim.EaterExceptionLocated; -import net.sourceforge.plantuml.tim.expression.TValue; +import net.sourceforge.plantuml.tim.TFunction; /** * Tests the builtin function %ord. */ -class OrdTest { +@IndicativeSentencesGeneration(separator = ": ", generator = ReplaceUnderscores.class) +class OrdTest { + TFunction cut = new Ord(); + final String cutName = "Ord"; /** * Tests ord according to a list of input / expected output * * @throws EaterException should not * @throws EaterExceptionLocated should not */ - @ParameterizedTest + @ParameterizedTest(name = "[{index}] " + cutName + "(''{0}'') = {1}") @CsvSource(nullValues = "null", value = { " A , 65 ", " ABC , 65 ", @@ -39,11 +41,7 @@ class OrdTest { " 😀 , 128512 ", " \uD83D\uDE00 , 128512 ", }) - void executeReturnFunctionOrdTest(String input, String expected) throws EaterException, EaterExceptionLocated { - Ord cut = new Ord(); - - List values = Collections.singletonList(TValue.fromString(input)); - TValue tValue = cut.executeReturnFunction(null, null, null, values, null); - assertEquals(expected, tValue.toString()); + void Test_with_String(String input, String expected) throws EaterException, EaterExceptionLocated { + assertTimExpectedOutputFromInput(cut, input, expected); } } \ No newline at end of file diff --git a/test/net/sourceforge/plantuml/tim/stdlib/RandomFuntionTest.java b/test/net/sourceforge/plantuml/tim/stdlib/RandomFuntionTest.java new file mode 100644 index 00000000000..c8505449ea7 --- /dev/null +++ b/test/net/sourceforge/plantuml/tim/stdlib/RandomFuntionTest.java @@ -0,0 +1,50 @@ +package net.sourceforge.plantuml.tim.stdlib; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.Collections; + +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.IndicativeSentencesGeneration; +import org.junit.jupiter.api.RepeatedTest; + +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterExceptionLocated; +import net.sourceforge.plantuml.tim.TFunction; +import net.sourceforge.plantuml.tim.expression.TValue; + +/** + * Tests the builtin function. + */ +@IndicativeSentencesGeneration(separator = ": ", generator = ReplaceUnderscores.class) + +class RandomFunctionTest { + TFunction cut = new RandomFunction(); + final String cutName = "Random"; + final String repetitionLabel = "[{currentRepetition}/{totalRepetitions}] "; + + @RepeatedTest(value = 10, name = repetitionLabel + cutName + "()") + void test_with_no_argument() throws EaterException, EaterExceptionLocated { + final TValue tValue = cut.executeReturnFunction(null, null, null, Collections.emptyList(), null); + assertThat(tValue.toInt()).isIn(0, 1); + } + + @RepeatedTest(value = 10, name = repetitionLabel + cutName + "(7)") + void test_with_one_argument() throws EaterException, EaterExceptionLocated { + final TValue tValue = cut.executeReturnFunction(null, null, null, Arrays.asList(TValue.fromInt(7)), null); + assertThat(tValue.toInt()).isBetween(0, 7-1); + } + + @RepeatedTest(value = 10, name = repetitionLabel + cutName + "(0, 7)") + void test_with_two_argument_first_zero() throws EaterException, EaterExceptionLocated { + final TValue tValue = cut.executeReturnFunction(null, null, null, Arrays.asList(TValue.fromInt(0), TValue.fromInt(7)), null); + assertThat(tValue.toInt()).isBetween(0, 7-1); + } + + @RepeatedTest(value = 10, name = repetitionLabel + cutName + "(3, 7)") + void test_with_two_argument() throws EaterException, EaterExceptionLocated { + final TValue tValue = cut.executeReturnFunction(null, null, null, Arrays.asList(TValue.fromInt(3), TValue.fromInt(7)), null); + assertThat(tValue.toInt()).isBetween(3, 7-1); + } +} \ No newline at end of file diff --git a/test/net/sourceforge/plantuml/tim/stdlib/SizeTest.java b/test/net/sourceforge/plantuml/tim/stdlib/SizeTest.java index 137ff9beff2..6bcfd105e10 100644 --- a/test/net/sourceforge/plantuml/tim/stdlib/SizeTest.java +++ b/test/net/sourceforge/plantuml/tim/stdlib/SizeTest.java @@ -1,8 +1,8 @@ package net.sourceforge.plantuml.tim.stdlib; -import static net.sourceforge.plantuml.test.JunitUtils.StringJsonConverter; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutput; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutputFromInput; +import static test.utils.JunitUtils.StringJsonConverter; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; diff --git a/test/net/sourceforge/plantuml/tim/stdlib/UpperTest.java b/test/net/sourceforge/plantuml/tim/stdlib/UpperTest.java index 049f0b53182..35c1e2e8738 100644 --- a/test/net/sourceforge/plantuml/tim/stdlib/UpperTest.java +++ b/test/net/sourceforge/plantuml/tim/stdlib/UpperTest.java @@ -1,8 +1,8 @@ package net.sourceforge.plantuml.tim.stdlib; -import static net.sourceforge.plantuml.test.JunitUtils.StringJsonConverter; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutput; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutputFromInput; +import static test.utils.JunitUtils.StringJsonConverter; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; diff --git a/test/net/sourceforge/plantuml/tim/stdlib/_TemplateStdlibTest.template b/test/net/sourceforge/plantuml/tim/stdlib/_TemplateStdlibTest.template index a949f6023b5..d85b08db050 100644 --- a/test/net/sourceforge/plantuml/tim/stdlib/_TemplateStdlibTest.template +++ b/test/net/sourceforge/plantuml/tim/stdlib/_TemplateStdlibTest.template @@ -1,8 +1,8 @@ package net.sourceforge.plantuml.tim.stdlib; -import static net.sourceforge.plantuml.test.JunitUtils.StringJsonConverter; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutput; import static net.sourceforge.plantuml.tim.TimTestUtils.assertTimExpectedOutputFromInput; +import static test.utils.JunitUtils.StringJsonConverter; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; diff --git a/test/nonreg/RenderViaApiTest.java b/test/nonreg/RenderViaApiTest.java new file mode 100644 index 00000000000..295eb1a5631 --- /dev/null +++ b/test/nonreg/RenderViaApiTest.java @@ -0,0 +1,56 @@ +package nonreg; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.util.Lists.newArrayList; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.io.PrintStream; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.SourceStringReader; +import net.sourceforge.plantuml.core.DiagramDescription; + +/** + * Tests the Render + */ +class RenderViaApiTest { + + @ParameterizedTest(name = "[{index}] {1}") + @CsvSource(nullValues = "null", value = { + "'@startuml\n!$a={\"k\": \"exampleValue\"}\ntitle $a.k\na -> b\n@enduml\n' , exampleValue", + "'@startuml\n!$a=[1, 2, 3]\ntitle xx $a[2] yy\na -> a\n@enduml' , xx 3 yy", + "'@startuml\ntitle\n!foreach $i in [1, 2, 3]\nxx $i yy\n!endfor\nendtitle\na -> a\n@enduml' , xx 2 yy", + "'@startuml\ntitle\n!foreach $i in [\"a\", \"b\", \"c\"]\nxx $i yy\n!endfor\nendtitle\na -> a\n@enduml' , xx b yy", + }) + void RenderTest(String input, String expected) throws Exception { + assertRenderExpectedOutput(input, expected); + } + + // TODO: to Factorize on a specific test package... + + private String RenderViaApiTest(String diagram, FileFormat format) throws IOException, UnsupportedEncodingException { + final SourceStringReader ssr = new SourceStringReader(diagram, UTF_8); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final DiagramDescription diagramDescription = ssr.outputImage(baos, 0, new FileFormatOption(format)); + final String rendered = new String(baos.toByteArray(), UTF_8); + // System.out.println(rendered); + return rendered; + } + + public void assertRenderExpectedOutput(String input, String expected) throws Exception { + final String rendered = RenderViaApiTest(input, FileFormat.PREPROC); + // OK with: + // final String rendered = RenderViaApiTest(input, FileFormat.UTXT); + assertThat(rendered).doesNotContain("syntax").contains(expected); + } +} diff --git a/test/nonreg/RenderViaPipeTest.java b/test/nonreg/RenderViaPipeTest.java new file mode 100644 index 00000000000..9a76078b965 --- /dev/null +++ b/test/nonreg/RenderViaPipeTest.java @@ -0,0 +1,63 @@ +package nonreg; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.util.Lists.newArrayList; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import net.sourceforge.plantuml.ErrorStatus; +import net.sourceforge.plantuml.Option; +import net.sourceforge.plantuml.Pipe; + +/** + * Tests the Render + */ +class RenderViaPipeTest { + + @ParameterizedTest(name = "[{index}] {1}") + @CsvSource(nullValues = "null", value = { + "'@startuml\n!$a={\"k\": \"exampleValue\"}\ntitle $a.k\na -> b\n@enduml\n' , exampleValue", + "'@startuml\n!$a=[1, 2, 3]\ntitle xx $a[2] yy\na -> a\n' , xx 3 yy", + "'@startuml\ntitle\n!foreach $i in [1, 2, 3]\nxx $i yy\n!endfor\nendtitle\na -> a\n' , xx 2 yy", + "'@startuml\ntitle\n!foreach $i in [\"a\", \"b\", \"c\"]\nxx $i yy\n!endfor\nendtitle\na -> a\n' , xx b yy", + }) + void RenderTest(String input, String expected) throws Exception { + assertRenderExpectedOutput(input, expected); + } + + // TODO: to Factorize on a specific test package... + private static final String[] COMMON_OPTIONS = {"-preproc"}; + // OK with "-tutxt" + // private static final String[] COMMON_OPTIONS = {"-tutxt"}; + + private String[] optionArray(String... extraOptions) { + final List list = newArrayList(COMMON_OPTIONS); + Collections.addAll(list, extraOptions); + return list.toArray(new String[0]); + } + + private String renderViaPipe(String diagram, String... extraOptions) throws Exception { + final Option option = new Option(optionArray(extraOptions)); + final ByteArrayInputStream bais = new ByteArrayInputStream(diagram.getBytes(UTF_8)); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final Pipe pipe = new Pipe(option, new PrintStream(baos), bais, option.getCharset()); + pipe.managePipe(ErrorStatus.init()); + final String rendered = new String(baos.toByteArray(), UTF_8); + // System.out.println(rendered); + return rendered; + } + + public void assertRenderExpectedOutput(String input, String expected) throws Exception { + final String rendered = renderViaPipe(input); + assertThat(rendered).doesNotContain("syntax").contains(expected); + } +} diff --git a/test/nonreg/simple/A0003_Test.java b/test/nonreg/simple/A0003_Test.java index 5d78367bdfb..99bbf588818 100644 --- a/test/nonreg/simple/A0003_Test.java +++ b/test/nonreg/simple/A0003_Test.java @@ -29,6 +29,6 @@ public class A0003_Test extends BasicTest { @Test void testSimple() throws IOException { - checkImage("(Project)"); + checkImage("(Gantt)"); } } diff --git a/test/nonreg/xmi/XmiTest.java b/test/nonreg/xmi/XmiTest.java index db85e694ddf..760a2ae6a67 100644 --- a/test/nonreg/xmi/XmiTest.java +++ b/test/nonreg/xmi/XmiTest.java @@ -12,9 +12,12 @@ import java.nio.file.Paths; import java.util.Collection; import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.concurrent.atomic.AtomicInteger; + +import org.xmlunit.builder.DiffBuilder; +import org.xmlunit.builder.Input; +import org.xmlunit.diff.DefaultNodeMatcher; +import org.xmlunit.diff.Diff; +import org.xmlunit.diff.ElementSelectors; import net.sourceforge.plantuml.FileFormat; import net.sourceforge.plantuml.FileFormatOption; @@ -30,44 +33,31 @@ protected void checkXmlAndDescription(final String expectedDescription) final String star = removeVersion(runPlantUML(expectedDescription, FileFormat.XMI_STAR)); final String starExpected = readStringFromSourceFile(getDiagramFile(), "{{{star", "}}}star"); - // This is really a hack. Since XML generation does not guarantee the order of - // attributes, we make an easy to do check by sorting characters. - // Of course, this is really incomplete: a faulty String may match the expected - // result if, for example, an attribute is moved from a node to another. - // However, we consider that it is a good start. - if (sortString(star).equals(sortString(starExpected)) == false) { - assertEquals(starExpected, star, "XmiStar: Generated GraphML is not ok"); - } + assertXMIEqual(star, starExpected); final String argo = removeVersion(runPlantUML(expectedDescription, FileFormat.XMI_ARGO)); final String argoExpected = readStringFromSourceFile(getDiagramFile(), "{{{argo", "}}}argo"); - if (sortString(argo).equals(sortString(argoExpected)) == false) { - assertEquals(argoExpected, argo, "XmiArgo: Generated GraphML is not ok"); - } + assertXMIEqual(argo, argoExpected); + } + private void assertXMIEqual(final String actual, final String expected) { + // XMI is XML, so we can just use the xmlunit diffbuilder + // Compare elements with the same xmi ID + // checkForSimilar required to ignore order + Diff diff = DiffBuilder.compare(Input.fromString(actual)).withTest(Input.fromString(expected)) + .ignoreWhitespace().ignoreComments().checkForSimilar() + .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndAttributes("xmi.id"))).build(); + + if (diff.hasDifferences()) { + assertTrue(false, diff.fullDescription()); + } } private String removeVersion(String xmi) { return xmi.replaceFirst("\\.*\\", ""); } - private String sortString(String s) { - final Map map = new TreeMap<>(); - for (int i = 0; i < s.length(); i++) { - final char ch = s.charAt(i); - // We ignore non writable characters - if (ch <= ' ') - continue; - - AtomicInteger count = map.get(ch); - if (count == null) - map.put(ch, new AtomicInteger(1)); - else - count.addAndGet(1); - } - return map.toString(); - } private String getLocalFolder() { return "test/" + getPackageName().replace(".", "/"); diff --git a/test/test/example/TestExample.java b/test/test/example/TestExample.java new file mode 100644 index 00000000000..eeedbb088bd --- /dev/null +++ b/test/test/example/TestExample.java @@ -0,0 +1,23 @@ +package test.example; + +import static test.utils.PlantUmlTestUtils.exportDiagram; +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class TestExample { + + @Test + public void test_help_themes() throws Exception { + + final String output = exportDiagram( + "@startuml", + "help themes", + "@enduml" + ).asString(); + + assertThat(output) + .contains("Help on themes") + .contains("bluegray", "hacker"); + } +} \ No newline at end of file diff --git a/test/net/sourceforge/plantuml/test/ImageTestUtils.java b/test/test/utils/ImageTestUtils.java similarity index 98% rename from test/net/sourceforge/plantuml/test/ImageTestUtils.java rename to test/test/utils/ImageTestUtils.java index cd989f3a7e4..21dcd284a34 100644 --- a/test/net/sourceforge/plantuml/test/ImageTestUtils.java +++ b/test/test/utils/ImageTestUtils.java @@ -1,4 +1,4 @@ -package net.sourceforge.plantuml.test; +package test.utils; import static org.assertj.core.api.Assertions.assertThat; diff --git a/test/net/sourceforge/plantuml/test/ImageTestUtilsTest.java b/test/test/utils/ImageTestUtilsTest.java similarity index 93% rename from test/net/sourceforge/plantuml/test/ImageTestUtilsTest.java rename to test/test/utils/ImageTestUtilsTest.java index 5d96a85a7ea..c29cb1687a1 100644 --- a/test/net/sourceforge/plantuml/test/ImageTestUtilsTest.java +++ b/test/test/utils/ImageTestUtilsTest.java @@ -1,9 +1,9 @@ -package net.sourceforge.plantuml.test; +package test.utils; -import static net.sourceforge.plantuml.test.ImageTestUtils.assertImageSizeEqual; -import static net.sourceforge.plantuml.test.ImageTestUtils.assertImagesEqual; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; +import static test.utils.ImageTestUtils.assertImageSizeEqual; +import static test.utils.ImageTestUtils.assertImagesEqual; import java.awt.image.BufferedImage; diff --git a/test/net/sourceforge/plantuml/test/JunitUtils.java b/test/test/utils/JunitUtils.java similarity index 95% rename from test/net/sourceforge/plantuml/test/JunitUtils.java rename to test/test/utils/JunitUtils.java index 8064ba1fc3a..e0b6add4127 100644 --- a/test/net/sourceforge/plantuml/test/JunitUtils.java +++ b/test/test/utils/JunitUtils.java @@ -1,4 +1,4 @@ -package net.sourceforge.plantuml.test; +package test.utils; import org.junit.jupiter.params.converter.ArgumentConversionException; import org.junit.jupiter.params.converter.SimpleArgumentConverter; diff --git a/test/net/sourceforge/plantuml/test/PlantUmlTestUtils.java b/test/test/utils/PlantUmlTestUtils.java similarity index 98% rename from test/net/sourceforge/plantuml/test/PlantUmlTestUtils.java rename to test/test/utils/PlantUmlTestUtils.java index e4bac23ce70..f1f5774adc5 100644 --- a/test/net/sourceforge/plantuml/test/PlantUmlTestUtils.java +++ b/test/test/utils/PlantUmlTestUtils.java @@ -1,4 +1,4 @@ -package net.sourceforge.plantuml.test; +package test.utils; import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; diff --git a/test/net/sourceforge/plantuml/test/StringTestUtils.java b/test/test/utils/StringTestUtils.java similarity index 96% rename from test/net/sourceforge/plantuml/test/StringTestUtils.java rename to test/test/utils/StringTestUtils.java index 2248dc201ac..df3705a8540 100644 --- a/test/net/sourceforge/plantuml/test/StringTestUtils.java +++ b/test/test/utils/StringTestUtils.java @@ -1,4 +1,4 @@ -package net.sourceforge.plantuml.test; +package test.utils; import static java.util.Objects.requireNonNull; diff --git a/test/net/sourceforge/plantuml/test/TestUtils.java b/test/test/utils/TestUtils.java similarity index 89% rename from test/net/sourceforge/plantuml/test/TestUtils.java rename to test/test/utils/TestUtils.java index 2506ddf4adf..d381f545ea2 100644 --- a/test/net/sourceforge/plantuml/test/TestUtils.java +++ b/test/test/utils/TestUtils.java @@ -1,4 +1,4 @@ -package net.sourceforge.plantuml.test; +package test.utils; import static java.nio.charset.StandardCharsets.UTF_8; diff --git a/themes/puml-theme-sunlust.puml b/themes/puml-theme-sunlust.puml new file mode 100644 index 00000000000..9001ba947f9 --- /dev/null +++ b/themes/puml-theme-sunlust.puml @@ -0,0 +1,133 @@ +'' NAME = Sunlust +'' DESCRIPTION = sunlust theme based off of the [solarized theme](https://ethanschoonover.com/solarized) +'' AUTHOR = Artem V. Ageev +'' LICENCE = GPL 3+ + +!$THEME = 'sunlust' +!if %not(%variable_exists("$BGCOLOR")) +!$BGCOLOR = '#fdf6e3' +!endif +scale max 2000 * 2000 +!$colors = { + "font" : "#657b83", + "bg" : "#fdf6e3", + "yellow" : "#b58900", + "yellow_bg" : "#BUSINESS", + "orange" : "#cb4b16", + "orange_bg" : "#STRATEGY", + "red" : "#dc322f", + "red_bg" : "#IMPLEMENTATION", + "violet" : "#6c71c4", + "violet_bg" : "#MOTIVATION", + "blue" : "#268bd2", + "blue_bg" : "#APPLICATION", + "green" : "#859900", + "green_bg" : "#TECHNOLOGY" +} +!$shapes = { + "TECHNOLOGY" : { + "color" : "#859900", + "shapes" : [ "Node", "File"] + }, + "APPLICATION" : { + "color" : "#268bd2", + "shapes" : [ "Participant", "Rectangle", "Component" ] + }, + "BUSINESS" : { + "color" : "#b58900", + "shapes" : [ "Actor", "Note", "Hexagon", "Boundary", "Control", "Entity" ] + }, + "IMPLEMENTATION" : { + "color" : "#dc322f", + "shapes" : [ "Class", "Map", "Json" ] + }, + "MOTIVATION" : { + "color" : "#6c71c4", + "shapes" : [ "Cloud", "Frame", "Collections", "Database", "Queue" ] + }, + "STRATEGY" : { + "color" : "#STRATEGY", + "shapes" : [ "Partition", "Folder", "Card" ] + } +} +!$thickness = 2 + +skinparam { + noteTextAlignment left + actorStyle awesome + Dpi 100 + Shadowing false + BackgroundColor $colors.bg + WrapWidth 200 + RoundCorner 15 + Swimlane { + BorderColor $colors.font + Thickness $thickness + WrapTitleWidth 150 + } + Arrow { + Color $colors.font + Thickness $thickness + } + Default { + TextAlignment center + FontName Dejavu Serif + } + Legend { + FontName VL Gothic + BorderColor transparent + BackgroundColor transparent + } + Sequence { + MessageAlign direction + ArrowThickness $thickness + LifeLineBorderColor $colors.yellow + BoxBorderThickness $thickness + } + !foreach $shape in %splitstr('Activity.State', '.') + $shape { + BackgroundColor transparent + Border { + Color $colors.violet + Thickness $thickness + } + Diamond { + BorderColor $colors.red + BackgroundColor transparent + } + } + !endfor + !foreach $key in %get_json_keys($shapes) + !foreach $shape in $shapes[$key].shapes + $shape { + BackgroundColor #$key + Border { + Color $shapes[$key].color + Thickness $thickness + } + } + !endfor + !endfor +}