Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
1155f0c
Initial plan
Copilot Feb 26, 2026
74eb2ee
Hide ⌘K keyboard shortcut on mobile screens
Copilot Feb 26, 2026
66b9b3f
Merge pull request #100 from javaevolved/copilot/hide-keyboard-key-mo…
brunoborges Feb 26, 2026
5c2108f
Initial plan
Copilot Feb 26, 2026
04a3e82
Add Italian (it) translations for all 112 patterns
Copilot Feb 26, 2026
b303be9
Add "learn more →" text to index card arrow links
brunoborges Feb 26, 2026
365c9bc
Merge pull request #102 from javaevolved/add-learn-more-to-cards
brunoborges Feb 26, 2026
ea485eb
Fix corrupted emoji icons in Italian translation files
Copilot Feb 26, 2026
85dfcd9
Merge pull request #101 from javaevolved/copilot/translate-site-conte…
brunoborges Feb 27, 2026
6d7ccf7
feat(i18n): add initial Polish locale translations
ArturSkowronski Feb 27, 2026
2c017c1
Merge branch 'main' into feat/pl-translation-bootstrap
ArturSkowronski Feb 27, 2026
6108c84
Update README.md
ArturSkowronski Feb 27, 2026
2e003d8
Update completablefuture-chaining.yaml
ArturSkowronski Feb 27, 2026
75ed66c
Update date-formatting.yaml
ArturSkowronski Feb 27, 2026
fbc3684
chore(i18n): keep pragmatic Polish wording with natural anglicisms
ArturSkowronski Feb 27, 2026
3318085
Update French tagline for clarity
brunoborges Feb 27, 2026
6cfcca4
Merge pull request #105 from javaevolved/fr-fix-title
brunoborges Feb 27, 2026
6321b13
Merge pull request #103 from ArturSkowronski/feat/pl-translation-boot…
brunoborges Feb 27, 2026
a7b7e63
Fix French translation for tagline consistency
brunoborges Feb 27, 2026
f290197
Initial plan
Copilot Feb 27, 2026
fae0e36
Initial plan
Copilot Feb 27, 2026
0d19451
feat: replace System.out.println with IO.println in modern code slugs
Copilot Feb 27, 2026
9125109
Merge pull request #109 from javaevolved/copilot/update-modern-slugs-…
brunoborges Feb 27, 2026
0a827e5
Add Turkish (tr) translations for collections and concurrency patterns
Copilot Feb 27, 2026
78f9ab7
Initial plan
Copilot Feb 27, 2026
82b56b5
Add missing cards.learnMore key to Italian translations
Copilot Feb 27, 2026
875ccf0
Add Turkish (tr) translations for datetime and enterprise patterns
Copilot Feb 27, 2026
d607766
Add Turkish (tr) translations for errors, io, and security categories
Copilot Feb 27, 2026
b1b4043
Merge pull request #111 from javaevolved/copilot/add-italian-ui-strings
brunoborges Feb 27, 2026
706e75a
Add Turkish (tr) translations for language category (22 files)
Copilot Feb 27, 2026
df8f4a8
Add Turkish (tr) translations for streams, strings, and tooling patterns
Copilot Feb 27, 2026
6a6ddde
Rewrite generate.py to match generate.java with full i18n support
brunoborges Feb 27, 2026
6fb06fa
Merge pull request #107 from javaevolved/copilot/add-turkish-translat…
brunoborges Feb 27, 2026
6d0fa87
Initial plan
Copilot Feb 27, 2026
fc86786
Add automated proof script for code snippet verification
Copilot Feb 27, 2026
16567bd
Fix text block assertion to check for real newlines instead of absenc…
Copilot Feb 27, 2026
2564051
Rework proof script to use existing proof/ Java files instead of YAML…
Copilot Feb 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 7 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ Run `jbang html-generators/generate.java` to rebuild all generated files from th

```
content/ # English content JSON files (source of truth, one per pattern)
proof/ # Proof scripts — one JBang .java file per pattern, proving it compiles
language/ # e.g. proof/language/TypeInferenceWithVar.java
collections/ # e.g. proof/collections/ImmutableListCreation.java
... # mirrors content/ category structure
translations/ # All i18n artifacts
strings/ # UI strings per locale (en.yaml, es.yaml, pt-BR.yaml)
content/ # Translated pattern files per locale (partial, translatable fields only)
Expand Down Expand Up @@ -113,6 +117,7 @@ Each `content/category/slug.json` file has this structure:
- `docs` must have at least **1** entry linking to Javadoc or Oracle documentation
- `prev`/`next` are `category/slug` paths or `null` for first/last
- Code in `oldCode`/`modernCode` uses `\n` for newlines
- `proofCode` is optional — a self-contained JShell snippet (with default imports available) that proves the modern approach compiles and runs correctly. Run `jbang html-generators/proof.java` to verify all proof snippets.

## Category Display Names

Expand All @@ -137,7 +142,8 @@ Categories and their display names are defined in `html-generators/categories.pr
1. Create `content/category/new-slug.json` with all required fields
2. Update `prev`/`next` in the adjacent patterns' JSON files
3. Run `jbang html-generators/generate.java`
4. (Optional) Create translated content files under `translations/content/{locale}/category/new-slug.json` with only translatable fields — or let the AI translation workflow handle it
4. Add a proof script at `proof/category/SlugName.java` (JBang, `//JAVA 25+`) — run `jbang html-generators/proof.java` to verify
5. (Optional) Create translated content files under `translations/content/{locale}/category/new-slug.json` with only translatable fields — or let the AI translation workflow handle it

## Internationalization (i18n)

Expand Down
33 changes: 33 additions & 0 deletions .github/workflows/proof.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Proof

on:
push:
branches: [main]
paths:
- 'proof/**'
- 'html-generators/proof.java'
- '.github/workflows/proof.yml'
pull_request:
paths:
- 'proof/**'
- 'html-generators/proof.java'
workflow_dispatch:

permissions:
contents: read

jobs:
proof:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '25'

- uses: jbangdev/setup-jbang@main

- name: Run proof
run: jbang html-generators/proof.java
3 changes: 2 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Contributions are welcome! Content is managed as YAML files — never edit gener
3. Copy [`content/template.json`](content/template.json) as a starting point for all required fields (see the [snippet schema](.github/copilot-instructions.md) for details)
4. Update the `prev`/`next` fields in adjacent pattern files to maintain navigation
5. Run `jbang html-generators/generate.java` to verify your changes build correctly
6. Open a pull request
6. Add a proof script at `proof/<category>/SlugName.java` that uses the modern approach and run `jbang html-generators/proof.java` to verify it passes
7. Open a pull request

Please ensure JDK version labels only reference the version where a feature became **final** (non-preview).

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Generated files (`site/category/*.html`, `site/{locale}/`, and `site/data/snippe

### Internationalization

The site supports 9 languages: English, Deutsch, Español, Português (Brasil), 中文 (简体), العربية, Français, 日本語, and 한국어. See [`specs/i18n/i18n-spec.md`](specs/i18n/i18n-spec.md) for the full specification.
The site supports 11 languages: English, Deutsch, Español, Português (Brasil), 中文 (简体), العربية, Français, 日本語, 한국어, Italian and Polski. See [`specs/i18n/i18n-spec.md`](specs/i18n/i18n-spec.md) for the full specification.

## Build & run locally

Expand Down
2 changes: 1 addition & 1 deletion content/collections/reverse-list-iteration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ oldCode: |-
}
modernCode: |-
for (String element : list.reversed()) {
System.out.println(element);
IO.println(element);
}
summary: "Iterate over a list in reverse order with a clean for-each loop."
explanation: "The reversed() method from SequencedCollection returns a reverse-ordered\
Expand Down
2 changes: 1 addition & 1 deletion content/concurrency/completablefuture-chaining.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ modernCode: |-
this::fetchData
)
.thenApply(this::transform)
.thenAccept(System.out::println);
.thenAccept(IO::println);
summary: "Chain async operations without blocking, using CompletableFuture."
explanation: "CompletableFuture enables non-blocking async pipelines. Chain operations\
\ with thenApply, thenCompose, thenAccept. Handle errors with exceptionally(). Combine\
Expand Down
4 changes: 2 additions & 2 deletions content/concurrency/process-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ modernCode: |-
ProcessHandle.current();
long pid = ph.pid();
ph.info().command()
.ifPresent(System.out::println);
.ifPresent(IO::println);
ph.children().forEach(
c -> System.out.println(c.pid()));
c -> IO.println(c.pid()));
summary: "Inspect and manage OS processes with ProcessHandle."
explanation: "ProcessHandle provides PIDs, process info (command, arguments, start\
\ time, CPU usage), parent/child relationships, and process destruction. No more\
Expand Down
2 changes: 1 addition & 1 deletion content/concurrency/virtual-threads.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ oldCode: |-
thread.join();
modernCode: |-
Thread.startVirtualThread(() -> {
System.out.println("hello");
IO.println("hello");
}).join();
summary: "Create millions of lightweight virtual threads instead of heavy OS threads."
explanation: "Virtual threads are lightweight threads managed by the JVM, not the\
Expand Down
2 changes: 1 addition & 1 deletion content/language/default-interface-methods.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ oldCode: |-
modernCode: |-
public interface Logger {
default void log(String msg) {
System.out.println(
IO.println(
timestamp() + ": " + msg);
}
String timestamp();
Expand Down
2 changes: 1 addition & 1 deletion content/language/pattern-matching-instanceof.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ oldCode: |-
}
modernCode: |-
if (obj instanceof String s) {
System.out.println(s.length());
IO.println(s.length());
}
summary: "Combine type check and cast in one step with pattern matching."
explanation: "Pattern matching for instanceof eliminates the redundant cast after\
Expand Down
4 changes: 2 additions & 2 deletions content/language/private-interface-methods.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ modernCode: |-
return "[" + lvl + "] " + timestamp() + msg;
}
default void logInfo(String msg) {
System.out.println(format("INFO", msg));
IO.println(format("INFO", msg));
}
default void logWarn(String msg) {
System.out.println(format("WARN", msg));
IO.println(format("WARN", msg));
}
}
summary: "Extract shared logic in interfaces using private methods."
Expand Down
2 changes: 1 addition & 1 deletion content/language/record-patterns.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ oldCode: |-
}
modernCode: |-
if (obj instanceof Point(int x, int y)) {
System.out.println(x + y);
IO.println(x + y);
}
summary: "Destructure records directly in patterns — extract fields in one step."
explanation: "Record patterns let you decompose a record's components directly in\
Expand Down
2 changes: 1 addition & 1 deletion content/streams/stream-iterate-predicate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ modernCode: |-
1,
n -> n < 1000,
n -> n * 2
).forEach(System.out::println);
).forEach(IO::println);
// stops when n >= 1000
summary: "Use a predicate to stop iteration — like a for-loop in stream form."
explanation: "The three-argument Stream.iterate(seed, hasNext, next) works like a\
Expand Down
2 changes: 1 addition & 1 deletion content/strings/string-lines.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ oldCode: |-
}
modernCode: |-
String text = "one\ntwo\nthree";
text.lines().forEach(System.out::println);
text.lines().forEach(IO::println);
summary: "Use String.lines() to split text into a stream of lines without regex overhead."
explanation: "String.lines() returns a Stream<String> of lines split by \\n, \\r,\
\ or \\r\\n. It is lazier and more efficient than split(), avoids regex compilation,\
Expand Down
5 changes: 4 additions & 1 deletion html-generators/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This folder contains the build scripts that generate all HTML detail pages and `
| `generate.py` | Python equivalent — produces identical output |
| `generate.jar` | Pre-built fat JAR (no JBang/JDK setup needed) |
| `build-cds.sh` | Script to build a platform-specific AOT cache |
| `proof.java` | JBang script (Java 25) — runs all `proof/**/*.java` scripts via JBang |

## Benchmark

Expand Down Expand Up @@ -65,10 +66,12 @@ This produces a self-contained ~2.2 MB JAR with all dependencies (Jackson) bundl

## CI/CD Workflows

Two GitHub Actions workflows automate the build and deploy pipeline:
Three GitHub Actions workflows automate the build, deploy, and proof pipeline:

1. **`build-generator.yml`** — Triggered when `generate.java` changes on `main`. Uses JBang to rebuild the fat JAR and commits the updated `generate.jar` back to the repository.

2. **`deploy.yml`** — Triggered when content, templates, the JAR, or site assets change on `main`. Runs `java -jar html-generators/generate.jar` to regenerate all HTML pages, `snippets.json`, and `index.html`, then deploys the `site/` folder to GitHub Pages.

3. **`proof.yml`** — Triggered when `proof/` scripts or content changes on `main` or in pull requests. Runs `jbang html-generators/proof.java` to verify all proof scripts compile and execute correctly.

This means the deploy workflow always uses the pre-built fat JAR (no JBang required at deploy time), and the JAR stays in sync with the source automatically.
3 changes: 2 additions & 1 deletion html-generators/generate.java
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,8 @@ String renderIndexCard(String tpl, Snippet s, String locale, Map<String, String>
Map.entry("jdkVersion", s.jdkVersion()), Map.entry("cardHref", cardHref),
Map.entry("cards.old", strings.getOrDefault("cards.old", "Old")),
Map.entry("cards.modern", strings.getOrDefault("cards.modern", "Modern")),
Map.entry("cards.hoverHint", strings.getOrDefault("cards.hoverHint", "hover to see modern →"))));
Map.entry("cards.hoverHint", strings.getOrDefault("cards.hoverHint", "hover to see modern →")),
Map.entry("cards.learnMore", strings.getOrDefault("cards.learnMore", "learn more"))));
}

String renderWhyCards(String tpl, JsonNode whyList) {
Expand Down
Loading