From 99f6afe4fbe1f156057b8274e6a143e01701e413 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Fri, 15 Nov 2024 11:47:40 -0800 Subject: [PATCH] Added capitalizeWords renderer --- README.md | 19 +++---- .../java/rife/render/CapitalizeWords.java | 50 +++++++++++++++++++ src/main/java/rife/render/RenderUtils.java | 32 ++++++++++++ .../java/rife/render/TestRenderUtils.java | 11 ++++ 4 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 src/main/java/rife/render/CapitalizeWords.java diff --git a/README.md b/README.md index df26021..45c7030 100644 --- a/README.md +++ b/README.md @@ -51,15 +51,16 @@ This project provides a collection of useful template renderers. ## Text Renderers -| Renderer | Description | -|:------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------| -| [rife.render.Capitalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Capitalize) | Capitalizes a template value | -| [rife.render.Lowercase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Lowercase) | Converts a template value to lowercase | -| [rife.render.Rot13](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Rot13) | Translates a template value to/from ROT13 | -| [rife.render.SwapCase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.SwapCase) | Swaps case of a template value | -| [rife.render.Trim](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Trim) | Removes leading and trailing whitespace from a template value | -| [rife.render.Uncapitalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uncapitalize) | Uncapitalizes a template value | -| [rife.render.Uppercase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uppercase) | Converts a template value to uppercase | +| Renderer | Description | +|:------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------| +| [rife.render.Capitalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Capitalize) | Capitalizes a template value | +| [rife.render.CapitalizeWords](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.CapitalizeWords) | Capitalizes words of a template value | +| [rife.render.Lowercase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Lowercase) | Converts a template value to lowercase | +| [rife.render.Rot13](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Rot13) | Translates a template value to/from ROT13 | +| [rife.render.SwapCase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.SwapCase) | Swaps case of a template value | +| [rife.render.Trim](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Trim) | Removes leading and trailing whitespace from a template value | +| [rife.render.Uncapitalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uncapitalize) | Uncapitalizes a template value | +| [rife.render.Uppercase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uppercase) | Converts a template value to uppercase | ## Documentation diff --git a/src/main/java/rife/render/CapitalizeWords.java b/src/main/java/rife/render/CapitalizeWords.java new file mode 100644 index 0000000..e95e6f8 --- /dev/null +++ b/src/main/java/rife/render/CapitalizeWords.java @@ -0,0 +1,50 @@ +/* + * Copyright 2023-2024 the original author or authors. + * + * Licensed 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 + * + * https://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. + * + */ + +package rife.render; + +import rife.template.Template; +import rife.template.ValueRenderer; + +/** + *

Capitalizes words of a template value.

+ * + *

Usage:

+ * + *
+ *   <!--v render:rife.render.CapitalizeWords:valueId/-->
+ *   {{v render:rife.render.CapitalizeWords:valueId/}}
+ * 
+ * + * @author Erik C. Thauvin + * @see rife.render.CapitalizeWords + * @since 1.2 + */ +public class CapitalizeWords implements ValueRenderer { + /** + * Returns the template value by capitalizing it. + * + * @param template the template containing the value to be rendered + * @param valueId the identifier of the value to render + * @param differentiator a string used to differentiate the rendering + * @return the capitalized and encoded value + */ + @Override + public String render(Template template, String valueId, String differentiator) { + return template.getEncoder().encode(RenderUtils.capitalizeWords(template.getValueOrAttribute(differentiator))); + } +} diff --git a/src/main/java/rife/render/RenderUtils.java b/src/main/java/rife/render/RenderUtils.java index 50b4576..b6d831f 100644 --- a/src/main/java/rife/render/RenderUtils.java +++ b/src/main/java/rife/render/RenderUtils.java @@ -124,6 +124,38 @@ public final class RenderUtils { return String.format("@%03d", beats); } + /** + * Returns a {@code String} with the first letter of each word capitalized. + * + * @param src the source {@code String} + * @return the capitalized {@code String} + */ + public static String capitalizeWords(String src) { + if (src == null || src.isBlank()) { + return src; + } + + var result = new StringBuilder(); + var capitalizeNext = true; + + for (var i = 0; i < src.length(); i++) { + char c = src.charAt(i); + if (Character.isWhitespace(c)) { + capitalizeNext = true; + result.append(c); + } else { + if (capitalizeNext) { + result.append(Character.toUpperCase(c)); + } else { + result.append(Character.toLowerCase(c)); + } + capitalizeNext = false; + } + } + + return result.toString(); + } + /** *

Encodes the source {@code String} to the specified encoding.

* diff --git a/src/test/java/rife/render/TestRenderUtils.java b/src/test/java/rife/render/TestRenderUtils.java index 747e87c..f1f8c46 100644 --- a/src/test/java/rife/render/TestRenderUtils.java +++ b/src/test/java/rife/render/TestRenderUtils.java @@ -40,6 +40,17 @@ class TestRenderUtils { assertThat(RenderUtils.abbreviate("", 10, "")).as("").isEmpty(); } + @Test + void testCapitalizeWords() { + assertThat(RenderUtils.capitalizeWords("hello world")).isEqualTo("Hello World"); + assertThat(RenderUtils.capitalizeWords("java programming")).isEqualTo("Java Programming"); + assertThat(RenderUtils.capitalizeWords("TEST")).isEqualTo("Test"); + assertThat(RenderUtils.capitalizeWords("multiple spaces")).isEqualTo("Multiple Spaces"); + assertThat(RenderUtils.capitalizeWords("white\t\fspaces")).isEqualTo("White\t\fSpaces"); + assertThat(RenderUtils.capitalizeWords("")).isEmpty(); + assertThat(RenderUtils.capitalizeWords(null)).isNull(); + } + @Test void testEncode() { var p = new Properties();