| 1 | package pro.verron.officestamper.asciidoc; | |
| 2 | ||
| 3 | import javafx.geometry.Insets; | |
| 4 | import javafx.scene.Scene; | |
| 5 | import javafx.scene.control.ScrollPane; | |
| 6 | import javafx.scene.layout.Priority; | |
| 7 | import javafx.scene.layout.VBox; | |
| 8 | import javafx.scene.text.*; | |
| 9 | import javafx.scene.text.Text; | |
| 10 | ||
| 11 | import java.util.List; | |
| 12 | ||
| 13 | import static pro.verron.officestamper.asciidoc.AsciiDocModel.*; | |
| 14 | ||
| 15 | /// Renders [AsciiDocModel] into a JavaFX [Scene]. | |
| 16 | public final class AsciiDocToFx { | |
| 17 | private AsciiDocToFx() {} | |
| 18 | ||
| 19 | /// Compiles the model into a simple scrollable Scene using a VBox of TextFlow nodes. | |
| 20 | /// | |
| 21 | /// Headings are rendered with larger font sizes; bold/italic are applied per inline fragment. | |
| 22 | /// | |
| 23 | /// @param model parsed AsciiDoc model | |
| 24 | /// | |
| 25 | /// @return JavaFX scene containing the rendered content | |
| 26 | public static Scene compileToScene(AsciiDocModel model) { | |
| 27 | var rootBox = new VBox(8.0); | |
| 28 |
1
1. compileToScene : removed call to javafx/scene/layout/VBox::setPadding → NO_COVERAGE |
rootBox.setPadding(new Insets(16)); |
| 29 | ||
| 30 | for (Block block : model.getBlocks()) { | |
| 31 | TextFlow flow = new TextFlow(); | |
| 32 |
2
1. compileToScene : negated conditional → NO_COVERAGE 2. compileToScene : negated conditional → NO_COVERAGE |
if (block instanceof Heading(int level, List<Inline> inlines)) { |
| 33 | for (Inline inline : inlines) { | |
| 34 |
1
1. compileToScene : removed call to pro/verron/officestamper/asciidoc/AsciiDocToFx::emitInline → NO_COVERAGE |
emitInline(flow, inline, fontForHeading(level), FontWeight.NORMAL, FontPosture.REGULAR); |
| 35 | } | |
| 36 | } | |
| 37 |
1
1. compileToScene : negated conditional → NO_COVERAGE |
else if (block instanceof Paragraph(List<Inline> inlines)) { |
| 38 | for (Inline inline : inlines) { | |
| 39 |
1
1. compileToScene : removed call to pro/verron/officestamper/asciidoc/AsciiDocToFx::emitInline → NO_COVERAGE |
emitInline(flow, inline, Font.getDefault(), FontWeight.NORMAL, FontPosture.REGULAR); |
| 40 | } | |
| 41 | } | |
| 42 | rootBox.getChildren() | |
| 43 | .add(flow); | |
| 44 | } | |
| 45 | ||
| 46 | var scroll = new ScrollPane(rootBox); | |
| 47 |
1
1. compileToScene : removed call to javafx/scene/control/ScrollPane::setFitToWidth → NO_COVERAGE |
scroll.setFitToWidth(true); |
| 48 |
1
1. compileToScene : removed call to javafx/scene/layout/VBox::setVgrow → NO_COVERAGE |
VBox.setVgrow(scroll, Priority.ALWAYS); |
| 49 |
1
1. compileToScene : replaced return value with null for pro/verron/officestamper/asciidoc/AsciiDocToFx::compileToScene → NO_COVERAGE |
return new Scene(scroll, 800, 600); |
| 50 | } | |
| 51 | ||
| 52 | private static void emitInline(TextFlow flow, Inline inline, Font base, FontWeight weight, FontPosture posture) { | |
| 53 |
1
1. emitInline : negated conditional → NO_COVERAGE |
if (inline instanceof AsciiDocModel.Text(String text)) { |
| 54 | flow.getChildren() | |
| 55 | .add(styledText(text, base, weight, posture)); | |
| 56 | return; | |
| 57 | } | |
| 58 |
1
1. emitInline : negated conditional → NO_COVERAGE |
if (inline instanceof Bold(List<Inline> children)) { |
| 59 | FontWeight nextW = FontWeight.BOLD; // bold overrides | |
| 60 | for (Inline child : children) { | |
| 61 |
1
1. emitInline : removed call to pro/verron/officestamper/asciidoc/AsciiDocToFx::emitInline → NO_COVERAGE |
emitInline(flow, child, base, nextW, posture); |
| 62 | } | |
| 63 | return; | |
| 64 | } | |
| 65 |
1
1. emitInline : negated conditional → NO_COVERAGE |
if (inline instanceof Italic(List<Inline> children)) { |
| 66 | FontPosture nextP = FontPosture.ITALIC; | |
| 67 | for (Inline child : children) { | |
| 68 |
1
1. emitInline : removed call to pro/verron/officestamper/asciidoc/AsciiDocToFx::emitInline → NO_COVERAGE |
emitInline(flow, child, base, weight, nextP); |
| 69 | } | |
| 70 | } | |
| 71 | } | |
| 72 | ||
| 73 | private static Font fontForHeading(int level) { | |
| 74 | double size = switch (level) { | |
| 75 | case 1 -> 24; | |
| 76 | case 2 -> 20; | |
| 77 | case 3 -> 18; | |
| 78 | case 4 -> 16; | |
| 79 | case 5 -> 14; | |
| 80 | default -> 13; | |
| 81 | }; | |
| 82 |
1
1. fontForHeading : replaced return value with null for pro/verron/officestamper/asciidoc/AsciiDocToFx::fontForHeading → NO_COVERAGE |
return Font.font(Font.getDefault() |
| 83 | .getFamily(), FontWeight.BOLD, size); | |
| 84 | } | |
| 85 | ||
| 86 | private static Text styledText(String value, Font base, FontWeight weight, FontPosture posture) { | |
| 87 |
1
1. styledText : negated conditional → NO_COVERAGE |
FontWeight w = weight != null ? weight : FontWeight.NORMAL; |
| 88 |
1
1. styledText : negated conditional → NO_COVERAGE |
FontPosture p = posture != null ? posture : FontPosture.REGULAR; |
| 89 | Text t = new Text(value); | |
| 90 |
1
1. styledText : removed call to javafx/scene/text/Text::setFont → NO_COVERAGE |
t.setFont(Font.font(base.getFamily(), w, p, base.getSize())); |
| 91 |
1
1. styledText : replaced return value with null for pro/verron/officestamper/asciidoc/AsciiDocToFx::styledText → NO_COVERAGE |
return t; |
| 92 | } | |
| 93 | } | |
Mutations | ||
| 28 |
1.1 |
|
| 32 |
1.1 2.2 |
|
| 34 |
1.1 |
|
| 37 |
1.1 |
|
| 39 |
1.1 |
|
| 47 |
1.1 |
|
| 48 |
1.1 |
|
| 49 |
1.1 |
|
| 53 |
1.1 |
|
| 58 |
1.1 |
|
| 61 |
1.1 |
|
| 65 |
1.1 |
|
| 68 |
1.1 |
|
| 82 |
1.1 |
|
| 87 |
1.1 |
|
| 88 |
1.1 |
|
| 90 |
1.1 |
|
| 91 |
1.1 |