From 3eb3641288cab9310c4a4514e1ee10aec821eb96 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Sun, 22 Dec 2024 01:34:04 -0500 Subject: [PATCH 1/9] literate: add `FrontMatter` --- .../src/main/java/org/aya/literate/Literate.java | 6 ++++++ .../java/org/aya/literate/LiterateConsumer.java | 9 +++++---- .../org/aya/literate/parser/BaseMdParser.java | 2 +- .../test/java/org/aya/literate/MarkdownTest.java | 15 +++++++++++++++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/tools-md/src/main/java/org/aya/literate/Literate.java b/tools-md/src/main/java/org/aya/literate/Literate.java index c03d39690e..1075ed766c 100644 --- a/tools-md/src/main/java/org/aya/literate/Literate.java +++ b/tools-md/src/main/java/org/aya/literate/Literate.java @@ -53,6 +53,12 @@ record Many(@Nullable Style style, @NotNull ImmutableSeq children) imp } } + record FrontMatter(@NotNull ImmutableSeq children) implements Literate { + @Override public @NotNull Doc toDoc() { + return Doc.cat(this.children().map(Literate::toDoc)); + } + } + class InlineCode implements Literate { /** * The content of this inline code diff --git a/tools-md/src/main/java/org/aya/literate/LiterateConsumer.java b/tools-md/src/main/java/org/aya/literate/LiterateConsumer.java index 28567c3545..b0d6727121 100644 --- a/tools-md/src/main/java/org/aya/literate/LiterateConsumer.java +++ b/tools-md/src/main/java/org/aya/literate/LiterateConsumer.java @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2023 Tesla (Yinsen) Zhang. +// Copyright (c) 2020-2024 Tesla (Yinsen) Zhang. // Use of this source code is governed by the MIT license that can be found in the LICENSE.md file. package org.aya.literate; @@ -13,10 +13,11 @@ public interface LiterateConsumer extends Consumer { @MustBeInvokedByOverriders default void accept(@NotNull Literate literate) { switch (literate) { - case Literate.Many many -> many.children().forEach(this); - case Literate.List items -> items.items().forEach(this); + case Literate.Many(_, var children) -> children.forEach(this); + case Literate.FrontMatter(var children) -> children.forEach(this); + case Literate.List(var items, _) -> items.forEach(this); case Literate.Unsupported(var children) -> children.forEach(this); - default -> {} + default -> { } } } diff --git a/tools-md/src/main/java/org/aya/literate/parser/BaseMdParser.java b/tools-md/src/main/java/org/aya/literate/parser/BaseMdParser.java index d2e737e979..9e87bc8206 100644 --- a/tools-md/src/main/java/org/aya/literate/parser/BaseMdParser.java +++ b/tools-md/src/main/java/org/aya/literate/parser/BaseMdParser.java @@ -271,7 +271,7 @@ protected record InlineLinkData(@Nullable String title, @NotNull String destinat } if (type == FrontMatterHeaderProvider.FRONT_MATTER_HEADER) { - return new Literate.Many(null, mapChildren(node)); + return new Literate.FrontMatter(mapChildren(node)); } if (type == FrontMatterHeaderProvider.FRONT_MATTER_HEADER_DELIMITER) { diff --git a/tools-md/src/test/java/org/aya/literate/MarkdownTest.java b/tools-md/src/test/java/org/aya/literate/MarkdownTest.java index 7da8224958..d973f76ffd 100644 --- a/tools-md/src/test/java/org/aya/literate/MarkdownTest.java +++ b/tools-md/src/test/java/org/aya/literate/MarkdownTest.java @@ -81,6 +81,21 @@ public class Main {} """); } + @Test public void frontMatter() { + assertInstanceOf(Literate.FrontMatter.class, parse(""" + --- + title: "Hello, World!" + --- + """, ImmutableSeq.empty())); + var many = assertInstanceOf(Literate.Many.class, parse(""" + --- + title: "Hello, World!" + --- + # Content + """, ImmutableSeq.empty())); + assertInstanceOf(Literate.FrontMatter.class, many.children().get(0)); + } + @Test public void markdownInMarkdown() { // The code block is treated as plain text if the language is not interesting. // Arbitrary nesting level of markdown is supported. From 875ca450b8bbbf06a80110d2f5ef96e097369a84 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Sun, 22 Dec 2024 02:10:57 -0500 Subject: [PATCH 2/9] literate: pass parameter around --- .../main/java/org/aya/cli/console/Main.java | 32 +++++++++---------- .../java/org/aya/cli/console/MainArgs.java | 2 ++ .../org/aya/cli/library/LibraryCompiler.java | 5 ++- .../aya/cli/library/json/LibraryConfig.java | 3 +- .../cli/library/json/LibraryConfigData.java | 19 +++++------ .../aya/cli/library/source/LibrarySource.java | 9 ++++-- .../org/aya/cli/single/CompilerFlags.java | 3 +- .../org/aya/cli/single/SingleAyaFile.java | 7 ++-- .../java/org/aya/cli/utils/LiterateData.java | 16 ++++++++++ .../aya/test/literate/AyaMdParserTest.java | 3 +- .../java/org/aya/lsp/library/WsLibrary.java | 2 +- .../main/java/org/aya/literate/Literate.java | 12 +++++-- .../org/aya/literate/parser/BaseMdParser.java | 2 +- 13 files changed, 75 insertions(+), 40 deletions(-) diff --git a/cli-console/src/main/java/org/aya/cli/console/Main.java b/cli-console/src/main/java/org/aya/cli/console/Main.java index 91907672d4..7a32fcbcf3 100644 --- a/cli-console/src/main/java/org/aya/cli/console/Main.java +++ b/cli-console/src/main/java/org/aya/cli/console/Main.java @@ -106,25 +106,23 @@ private int doCompile(@NotNull CompileAction compile) throws IOException { return compiler.compile(filePath, null); } - private @Nullable CompilerFlags.PrettyInfo - computePrettyInfo( + private @Nullable CompilerFlags.PrettyInfo computePrettyInfo( @Nullable Path outputPath, RenderOptions renderOptions, AyaPrettierOptions prettierOptions ) { - return prettyStage == null - ? (outputPath != null ? CompilerFlags.prettyInfoFromOutput( - outputPath, renderOptions, prettyNoCodeStyle, prettyInlineCodeStyle, prettySSR) : null) - : new CompilerFlags.PrettyInfo( - asciiOnly, - prettyNoCodeStyle, - prettyInlineCodeStyle, - prettySSR, - prettyStage, - prettyFormat, - prettierOptions, - renderOptions, - prettyDir - ); + if (prettyStage == null) + return outputPath != null ? CompilerFlags.prettyInfoFromOutput( + outputPath, renderOptions, prettyNoCodeStyle, prettyInlineCodeStyle, prettySSR) : null; + return new CompilerFlags.PrettyInfo( + asciiOnly, + prettyNoCodeStyle, + prettyInlineCodeStyle, + prettySSR, + prettyStage, + prettyFormat, + prettierOptions, renderOptions, + datetimeFrontMatterKey, prettyDir + ); } private @NotNull RenderOptions createRenderOptions(@NotNull ReplConfig replConfig) { @@ -132,7 +130,7 @@ private int doCompile(@NotNull CompileAction compile) throws IOException { switch (prettyColor) { case emacs -> renderOptions.colorScheme = RenderOptions.ColorSchemeName.Emacs; case intellij -> renderOptions.colorScheme = RenderOptions.ColorSchemeName.IntelliJ; - case null -> {} + case null -> { } } return renderOptions; } diff --git a/cli-console/src/main/java/org/aya/cli/console/MainArgs.java b/cli-console/src/main/java/org/aya/cli/console/MainArgs.java index 08655ef887..0a4603efd0 100644 --- a/cli-console/src/main/java/org/aya/cli/console/MainArgs.java +++ b/cli-console/src/main/java/org/aya/cli/console/MainArgs.java @@ -81,6 +81,8 @@ public static class Action { public PrettyFormat prettyFormat; @Option(names = {"--pretty-dir"}, description = "Specify output directory of pretty printing.") public String prettyDir; + @Option(names = {"--datetime-front-matter-key"}, description = "If set, add datetime in the front matter using the value as YAML key.") + public String datetimeFrontMatterKey; @Option(names = {"--pretty-color"}, description = "The color theme of pretty printing." + CANDIDATES, defaultValue = "emacs") public PredefinedStyle prettyColor; @Option(names = {"--pretty-no-code-style"}, description = "Do not include default highlight styles.") diff --git a/cli-impl/src/main/java/org/aya/cli/library/LibraryCompiler.java b/cli-impl/src/main/java/org/aya/cli/library/LibraryCompiler.java index d092eb068e..8bdd581f06 100644 --- a/cli-impl/src/main/java/org/aya/cli/library/LibraryCompiler.java +++ b/cli-impl/src/main/java/org/aya/cli/library/LibraryCompiler.java @@ -171,6 +171,9 @@ private void pretty(ImmutableSeq modified) throws IOException { var litPretty = litConfig.pretty(); var prettierOptions = litPretty != null ? litPretty.prettierOptions : cmdPretty.prettierOptions(); var renderOptions = litPretty != null ? litPretty.renderOptions : cmdPretty.renderOptions(); + var datetimeFrontMatterKey = cmdPretty.datetimeFrontMatterKey() != null + ? cmdPretty.datetimeFrontMatterKey() + : litConfig.datetimeFrontMatterKey(); // always use the backend options from the command line, like output format, server-side rendering, etc. var outputTarget = cmdPretty.prettyFormat().target; var setup = cmdPretty.backendOpts(true).then(new RenderOptions.BackendSetup() { @@ -187,7 +190,7 @@ private void pretty(ImmutableSeq modified) throws IOException { // THE BIG GAME modified.forEachChecked(src -> { // reportNest(STR."[Pretty] \{QualifiedID.join(src.moduleName())}"); - var doc = src.pretty(ImmutableSeq.empty(), prettierOptions); + var doc = src.pretty(ImmutableSeq.empty(), datetimeFrontMatterKey, prettierOptions); var text = renderOptions.render(outputTarget, doc, setup); var outputFileName = AyaFiles.stripAyaSourcePostfix(src.displayPath().toString()) + outputTarget.fileExt; var outputFile = outputDir.resolve(outputFileName); diff --git a/cli-impl/src/main/java/org/aya/cli/library/json/LibraryConfig.java b/cli-impl/src/main/java/org/aya/cli/library/json/LibraryConfig.java index 5b29d12085..bc9a202036 100644 --- a/cli-impl/src/main/java/org/aya/cli/library/json/LibraryConfig.java +++ b/cli-impl/src/main/java/org/aya/cli/library/json/LibraryConfig.java @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2023 Tesla (Yinsen) Zhang. +// Copyright (c) 2020-2024 Tesla (Yinsen) Zhang. // Use of this source code is governed by the MIT license that can be found in the LICENSE.md file. package org.aya.cli.library.json; @@ -29,6 +29,7 @@ public record LibraryConfig( ) { public record LibraryLiterateConfig( @Nullable LiteratePrettierOptions pretty, + @Nullable String datetimeFrontMatterKey, @NotNull String linkPrefix, @NotNull Path outputPath ) { diff --git a/cli-impl/src/main/java/org/aya/cli/library/json/LibraryConfigData.java b/cli-impl/src/main/java/org/aya/cli/library/json/LibraryConfigData.java index 6f01e71075..8924fb6aa5 100644 --- a/cli-impl/src/main/java/org/aya/cli/library/json/LibraryConfigData.java +++ b/cli-impl/src/main/java/org/aya/cli/library/json/LibraryConfigData.java @@ -1,10 +1,11 @@ -// Copyright (c) 2020-2023 Tesla (Yinsen) Zhang. +// Copyright (c) 2020-2024 Tesla (Yinsen) Zhang. // Use of this source code is governed by the MIT license that can be found in the LICENSE.md file. package org.aya.cli.library.json; import com.google.gson.GsonBuilder; import com.google.gson.JsonParseException; import kala.collection.immutable.ImmutableSeq; +import org.aya.cli.library.json.LibraryConfig.LibraryLiterateConfig; import org.aya.cli.utils.LiteratePrettierOptions; import org.aya.generic.Constants; import org.aya.prelude.GeneratedVersion; @@ -38,9 +39,9 @@ public void checkDeserialization() { if (linkPrefix == null) linkPrefix = "/"; } - public @NotNull LibraryConfig.LibraryLiterateConfig asConfig(@NotNull Path outputPath) { + public @NotNull LibraryLiterateConfig asConfig(@Nullable String datetimeFrontMatterKey, @NotNull Path outputPath) { checkDeserialization(); - return new LibraryConfig.LibraryLiterateConfig(pretty, linkPrefix, outputPath); + return new LibraryLiterateConfig(pretty, datetimeFrontMatterKey, linkPrefix, outputPath); } } @@ -48,6 +49,7 @@ public void checkDeserialization() { public String name; public String group; public String version; + public String datetimeFrontMatterKey; public LibraryLiterateConfigData literate; public Map dependency; @@ -67,16 +69,15 @@ public void checkDeserialization() { private @NotNull LibraryConfig asConfig( @NotNull Path libraryRoot, - @Nullable LibraryConfig.LibraryLiterateConfig literateConfig, + @Nullable LibraryLiterateConfig literateConfig, @NotNull Function buildRootGen ) { checkDeserialization(libraryRoot.resolve(Constants.AYA_JSON)); var buildRoot = FileUtil.canonicalize(buildRootGen.apply(version)); - if (literateConfig == null) literateConfig = literate.asConfig(buildRoot.resolve("pretty")); + if (literateConfig == null) literateConfig = literate.asConfig(datetimeFrontMatterKey, + buildRoot.resolve("pretty")); return new LibraryConfig( - Version.create(ayaVersion), - name, - version, + Version.create(ayaVersion), name, version, libraryRoot, libraryRoot.resolve("src"), buildRoot, @@ -109,7 +110,7 @@ public void checkDeserialization() { public static @NotNull LibraryConfig fromDependencyRoot( @NotNull Path dependencyRoot, - @Nullable LibraryConfig.LibraryLiterateConfig literateConfig, + @Nullable LibraryLiterateConfig literateConfig, @NotNull Function buildRoot ) throws IOException, BadConfig { var canonicalPath = FileUtil.canonicalize(dependencyRoot); diff --git a/cli-impl/src/main/java/org/aya/cli/library/source/LibrarySource.java b/cli-impl/src/main/java/org/aya/cli/library/source/LibrarySource.java index 2061d7a285..a6ae1717fb 100644 --- a/cli-impl/src/main/java/org/aya/cli/library/source/LibrarySource.java +++ b/cli-impl/src/main/java/org/aya/cli/library/source/LibrarySource.java @@ -22,6 +22,7 @@ import org.aya.util.reporter.Problem; import org.jetbrains.annotations.Debug; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.nio.file.Files; @@ -77,8 +78,12 @@ public void notifyTycked(@NotNull ResolveInfo moduleResolve, @NotNull ImmutableS } } - public @NotNull Doc pretty(@NotNull ImmutableSeq problems, @NotNull PrettierOptions options) throws IOException { - return LiterateData.toDoc(this, moduleName(), program.get(), problems, options); + public @NotNull Doc pretty( + @NotNull ImmutableSeq problems, + @Nullable String datetimeFrontMatterKey, + @NotNull PrettierOptions options + ) throws IOException { + return LiterateData.toDoc(this, moduleName(), program.get(), problems, datetimeFrontMatterKey, options); } @Override public @NotNull ImmutableSeq parseMe(@NotNull GenericAyaParser parser) throws IOException { diff --git a/cli-impl/src/main/java/org/aya/cli/single/CompilerFlags.java b/cli-impl/src/main/java/org/aya/cli/single/CompilerFlags.java index 6ee82a1ed8..21625cb545 100644 --- a/cli-impl/src/main/java/org/aya/cli/single/CompilerFlags.java +++ b/cli-impl/src/main/java/org/aya/cli/single/CompilerFlags.java @@ -32,7 +32,7 @@ public record CompilerFlags( CliEnums.detectFormat(outputFile), AyaPrettierOptions.pretty(), renderOptions, - null); + null, null); return null; } @@ -45,6 +45,7 @@ public record PrettyInfo( @NotNull CliEnums.PrettyFormat prettyFormat, @NotNull PrettierOptions prettierOptions, @NotNull RenderOptions renderOptions, + @Nullable String datetimeFrontMatterKey, @Nullable String prettyDir ) { public @NotNull RenderOptions.DefaultSetup backendOpts(boolean headerCode) { diff --git a/cli-impl/src/main/java/org/aya/cli/single/SingleAyaFile.java b/cli-impl/src/main/java/org/aya/cli/single/SingleAyaFile.java index ed0b0e3135..2773fe0ce2 100644 --- a/cli-impl/src/main/java/org/aya/cli/single/SingleAyaFile.java +++ b/cli-impl/src/main/java/org/aya/cli/single/SingleAyaFile.java @@ -64,7 +64,8 @@ public sealed interface SingleAyaFile extends GenericAyaFile { var renderOptions = flags.renderOptions(); if (currentStage == CliEnums.PrettyStage.literate) { - var d = toDoc((ImmutableSeq) doc, reporter.problems().toImmutableSeq(), flags.prettierOptions()); + var d = toDoc((ImmutableSeq) doc, reporter.problems().toImmutableSeq(), + flags.datetimeFrontMatterKey(), flags.prettierOptions()); var text = renderOptions.render(out, d, flags.backendOpts(true)); FileUtil.writeString(prettyDir.resolve(fileName), text); } else { @@ -75,9 +76,9 @@ public sealed interface SingleAyaFile extends GenericAyaFile { @VisibleForTesting default @NotNull Doc toDoc( @NotNull ImmutableSeq program, @NotNull ImmutableSeq problems, - @NotNull PrettierOptions options + @Nullable String datetimeFrontMatterKey, @NotNull PrettierOptions options ) throws IOException { - return LiterateData.toDoc(this, null, program, problems, options); + return LiterateData.toDoc(this, null, program, problems, datetimeFrontMatterKey, options); } private void doWrite( diff --git a/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java b/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java index 2ddbb70ea6..1edea96ea2 100644 --- a/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java +++ b/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java @@ -4,6 +4,7 @@ import kala.collection.Seq; import kala.collection.immutable.ImmutableSeq; +import kala.collection.mutable.MutableList; import kala.control.Option; import org.aya.cli.literate.AyaMdParser; import org.aya.cli.literate.LiterateFaithfulPrettier; @@ -36,6 +37,8 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; public record LiterateData( @NotNull Literate literate, @@ -107,10 +110,23 @@ public void tyck(@NotNull ResolveInfo info) { @Nullable ModulePath currentFileModule, @NotNull ImmutableSeq program, @NotNull ImmutableSeq problems, + @Nullable String datetimeFrontMatterKey, @NotNull PrettierOptions options ) throws IOException { var highlights = SyntaxHighlight.highlight(currentFileModule, Option.some(ayaFile.codeFile()), program); var literate = ayaFile.literate(); + if (datetimeFrontMatterKey != null) { + var datetime = ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss X")); + var frontMatter = literate.findFrontMatter(); + var label = new Literate.Raw(Doc.plain(datetimeFrontMatterKey + ": " + datetime)); + if (frontMatter != null) { + frontMatter.children().append(label); + } else { + literate = new Literate.Many(null, ImmutableSeq.of( + new Literate.FrontMatter(MutableList.of( + label)), literate)); + } + } var prettier = new LiterateFaithfulPrettier(problems, highlights, options); prettier.accept(literate); return literate.toDoc(); diff --git a/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java b/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java index 45f7c7b110..60af79536c 100644 --- a/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java +++ b/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java @@ -97,7 +97,8 @@ public void testHighlight(String caseName) throws IOException { loader.tyckModule(info, null); literate.tyckAdditional(info); - var doc = literate.toDoc(stmts, reporter.problems().toImmutableSeq(), AyaPrettierOptions.pretty()).toDoc(); + var doc = literate.toDoc(stmts, reporter.problems().toImmutableSeq(), + null, AyaPrettierOptions.pretty()).toDoc(); reporter.problems().clear(); // save some coverage var actualTexInlinedStyle = doc.renderToTeX(); diff --git a/ide-lsp/src/main/java/org/aya/lsp/library/WsLibrary.java b/ide-lsp/src/main/java/org/aya/lsp/library/WsLibrary.java index 8eff98530d..a278d448a4 100644 --- a/ide-lsp/src/main/java/org/aya/lsp/library/WsLibrary.java +++ b/ide-lsp/src/main/java/org/aya/lsp/library/WsLibrary.java @@ -45,7 +45,7 @@ public record WsLibrary( folder, folder.resolve("build"), folder.resolve("build"), - new LibraryConfig.LibraryLiterateConfig(null, "/", folder.resolve("build")), + new LibraryConfig.LibraryLiterateConfig(null, null, "/", folder.resolve("build")), ImmutableSeq.empty() ); } diff --git a/tools-md/src/main/java/org/aya/literate/Literate.java b/tools-md/src/main/java/org/aya/literate/Literate.java index 1075ed766c..4c82f19012 100644 --- a/tools-md/src/main/java/org/aya/literate/Literate.java +++ b/tools-md/src/main/java/org/aya/literate/Literate.java @@ -3,6 +3,7 @@ package org.aya.literate; import kala.collection.immutable.ImmutableSeq; +import kala.collection.mutable.MutableList; import org.aya.pretty.doc.*; import org.aya.util.error.SourcePos; import org.jetbrains.annotations.NotNull; @@ -13,8 +14,9 @@ * @see LiterateConsumer */ public interface Literate extends Docile { - record Raw(@NotNull Doc toDoc) implements Literate { - } + default @Nullable FrontMatter findFrontMatter() { return null; } + + record Raw(@NotNull Doc toDoc) implements Literate { } record List(@NotNull ImmutableSeq items, boolean ordered) implements Literate { @Override public @NotNull Doc toDoc() { @@ -51,12 +53,16 @@ record Many(@Nullable Style style, @NotNull ImmutableSeq children) imp var child = Doc.cat(this.children().map(Literate::toDoc)); return style == null ? child : Doc.styled(style, child); } + @Override public @Nullable FrontMatter findFrontMatter() { + return children.view().filterIsInstance(FrontMatter.class).getFirstOrNull(); + } } - record FrontMatter(@NotNull ImmutableSeq children) implements Literate { + record FrontMatter(@NotNull MutableList children) implements Literate { @Override public @NotNull Doc toDoc() { return Doc.cat(this.children().map(Literate::toDoc)); } + @Override public @NotNull FrontMatter findFrontMatter() { return this; } } class InlineCode implements Literate { diff --git a/tools-md/src/main/java/org/aya/literate/parser/BaseMdParser.java b/tools-md/src/main/java/org/aya/literate/parser/BaseMdParser.java index 9e87bc8206..b406353c75 100644 --- a/tools-md/src/main/java/org/aya/literate/parser/BaseMdParser.java +++ b/tools-md/src/main/java/org/aya/literate/parser/BaseMdParser.java @@ -271,7 +271,7 @@ protected record InlineLinkData(@Nullable String title, @NotNull String destinat } if (type == FrontMatterHeaderProvider.FRONT_MATTER_HEADER) { - return new Literate.FrontMatter(mapChildren(node)); + return new Literate.FrontMatter(MutableList.from(mapChildren(node))); } if (type == FrontMatterHeaderProvider.FRONT_MATTER_HEADER_DELIMITER) { From bdc0883d19530b336d3f273aa9b17e44529cc01f Mon Sep 17 00:00:00 2001 From: ice1000 Date: Sun, 22 Dec 2024 02:19:27 -0500 Subject: [PATCH 3/9] literate: generate eols --- cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java | 7 ++++--- tools-md/src/main/java/org/aya/literate/Literate.java | 1 + .../main/java/org/aya/literate/parser/BaseMdParser.java | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java b/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java index 1edea96ea2..791128a801 100644 --- a/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java +++ b/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java @@ -122,9 +122,10 @@ public void tyck(@NotNull ResolveInfo info) { if (frontMatter != null) { frontMatter.children().append(label); } else { - literate = new Literate.Many(null, ImmutableSeq.of( - new Literate.FrontMatter(MutableList.of( - label)), literate)); + var delimiter = new Literate.Raw(Doc.plain("---")); + frontMatter = new Literate.FrontMatter(MutableList.of( + delimiter, Literate.EOL, label, Literate.EOL, delimiter)); + literate = new Literate.Many(null, ImmutableSeq.of(frontMatter, literate)); } } var prettier = new LiterateFaithfulPrettier(problems, highlights, options); diff --git a/tools-md/src/main/java/org/aya/literate/Literate.java b/tools-md/src/main/java/org/aya/literate/Literate.java index 4c82f19012..d22047f77a 100644 --- a/tools-md/src/main/java/org/aya/literate/Literate.java +++ b/tools-md/src/main/java/org/aya/literate/Literate.java @@ -17,6 +17,7 @@ public interface Literate extends Docile { default @Nullable FrontMatter findFrontMatter() { return null; } record Raw(@NotNull Doc toDoc) implements Literate { } + @NotNull Raw EOL = new Raw(Doc.line()); record List(@NotNull ImmutableSeq items, boolean ordered) implements Literate { @Override public @NotNull Doc toDoc() { diff --git a/tools-md/src/main/java/org/aya/literate/parser/BaseMdParser.java b/tools-md/src/main/java/org/aya/literate/parser/BaseMdParser.java index b406353c75..4283e3e27e 100644 --- a/tools-md/src/main/java/org/aya/literate/parser/BaseMdParser.java +++ b/tools-md/src/main/java/org/aya/literate/parser/BaseMdParser.java @@ -160,7 +160,7 @@ protected record InlineLinkData(@Nullable String title, @NotNull String destinat var type = node.getType(); if (type == MarkdownTokenTypes.EOL || type == MarkdownTokenTypes.HARD_LINE_BREAK) { - return new Literate.Raw(Doc.line()); + return Literate.EOL; } // do not confuse with MarkdownTokenTypes.EMPH From 0c24115bd69272ff061d257a89d53ad406328423 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Sun, 22 Dec 2024 02:39:42 -0500 Subject: [PATCH 4/9] literate: allow user specified datetime, so we can pass in the git datetime --- .../src/main/java/org/aya/cli/console/Main.java | 2 +- .../src/main/java/org/aya/cli/console/MainArgs.java | 2 ++ .../java/org/aya/cli/library/LibraryCompiler.java | 12 ++++++++---- .../org/aya/cli/library/source/LibrarySource.java | 5 ++--- .../main/java/org/aya/cli/single/CompilerFlags.java | 4 +++- .../main/java/org/aya/cli/single/SingleAyaFile.java | 10 +++++++--- .../main/java/org/aya/cli/utils/LiterateData.java | 13 +++++++------ .../java/org/aya/test/literate/AyaMdParserTest.java | 5 ++++- .../src/main/java/org/aya/util/more/StringUtil.java | 9 ++++++++- 9 files changed, 42 insertions(+), 20 deletions(-) diff --git a/cli-console/src/main/java/org/aya/cli/console/Main.java b/cli-console/src/main/java/org/aya/cli/console/Main.java index 7a32fcbcf3..b5f92d5120 100644 --- a/cli-console/src/main/java/org/aya/cli/console/Main.java +++ b/cli-console/src/main/java/org/aya/cli/console/Main.java @@ -121,7 +121,7 @@ private int doCompile(@NotNull CompileAction compile) throws IOException { prettyStage, prettyFormat, prettierOptions, renderOptions, - datetimeFrontMatterKey, prettyDir + datetimeFrontMatterKey, datetimeFrontMatterValue, prettyDir ); } diff --git a/cli-console/src/main/java/org/aya/cli/console/MainArgs.java b/cli-console/src/main/java/org/aya/cli/console/MainArgs.java index 0a4603efd0..f25c445ffc 100644 --- a/cli-console/src/main/java/org/aya/cli/console/MainArgs.java +++ b/cli-console/src/main/java/org/aya/cli/console/MainArgs.java @@ -83,6 +83,8 @@ public static class Action { public String prettyDir; @Option(names = {"--datetime-front-matter-key"}, description = "If set, add datetime in the front matter using the value as YAML key.") public String datetimeFrontMatterKey; + @Option(names = {"--datetime-front-matter"}, description = "Overwrites the datetime in the front matter.") + public String datetimeFrontMatterValue; @Option(names = {"--pretty-color"}, description = "The color theme of pretty printing." + CANDIDATES, defaultValue = "emacs") public PredefinedStyle prettyColor; @Option(names = {"--pretty-no-code-style"}, description = "Do not include default highlight styles.") diff --git a/cli-impl/src/main/java/org/aya/cli/library/LibraryCompiler.java b/cli-impl/src/main/java/org/aya/cli/library/LibraryCompiler.java index 8bdd581f06..71b311326d 100644 --- a/cli-impl/src/main/java/org/aya/cli/library/LibraryCompiler.java +++ b/cli-impl/src/main/java/org/aya/cli/library/LibraryCompiler.java @@ -13,6 +13,7 @@ import org.aya.cli.single.CompilerFlags; import org.aya.cli.utils.CliEnums; import org.aya.cli.utils.CompilerUtil; +import org.aya.cli.utils.LiterateData; import org.aya.generic.InterruptException; import org.aya.pretty.backend.string.StringPrinterConfig; import org.aya.pretty.printer.PrinterConfig; @@ -171,9 +172,12 @@ private void pretty(ImmutableSeq modified) throws IOException { var litPretty = litConfig.pretty(); var prettierOptions = litPretty != null ? litPretty.prettierOptions : cmdPretty.prettierOptions(); var renderOptions = litPretty != null ? litPretty.renderOptions : cmdPretty.renderOptions(); - var datetimeFrontMatterKey = cmdPretty.datetimeFrontMatterKey() != null - ? cmdPretty.datetimeFrontMatterKey() - : litConfig.datetimeFrontMatterKey(); + var datetimeFMKey = cmdPretty.datetimeFrontMatterKey(); + var datetimeFMValue = cmdPretty.datetimeFrontMatterValue(); + if (datetimeFMKey == null) datetimeFMKey = litConfig.datetimeFrontMatterKey(); + if (datetimeFMValue != null) datetimeFMKey = "date"; + datetimeFMValue = StringUtil.timeInGitFormat(); + var frontMatter = new LiterateData.InjectedFrontMatter(datetimeFMKey, datetimeFMValue); // always use the backend options from the command line, like output format, server-side rendering, etc. var outputTarget = cmdPretty.prettyFormat().target; var setup = cmdPretty.backendOpts(true).then(new RenderOptions.BackendSetup() { @@ -190,7 +194,7 @@ private void pretty(ImmutableSeq modified) throws IOException { // THE BIG GAME modified.forEachChecked(src -> { // reportNest(STR."[Pretty] \{QualifiedID.join(src.moduleName())}"); - var doc = src.pretty(ImmutableSeq.empty(), datetimeFrontMatterKey, prettierOptions); + var doc = src.pretty(ImmutableSeq.empty(), frontMatter, prettierOptions); var text = renderOptions.render(outputTarget, doc, setup); var outputFileName = AyaFiles.stripAyaSourcePostfix(src.displayPath().toString()) + outputTarget.fileExt; var outputFile = outputDir.resolve(outputFileName); diff --git a/cli-impl/src/main/java/org/aya/cli/library/source/LibrarySource.java b/cli-impl/src/main/java/org/aya/cli/library/source/LibrarySource.java index a6ae1717fb..fbfa20b737 100644 --- a/cli-impl/src/main/java/org/aya/cli/library/source/LibrarySource.java +++ b/cli-impl/src/main/java/org/aya/cli/library/source/LibrarySource.java @@ -22,7 +22,6 @@ import org.aya.util.reporter.Problem; import org.jetbrains.annotations.Debug; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.nio.file.Files; @@ -80,10 +79,10 @@ public void notifyTycked(@NotNull ResolveInfo moduleResolve, @NotNull ImmutableS public @NotNull Doc pretty( @NotNull ImmutableSeq problems, - @Nullable String datetimeFrontMatterKey, + @NotNull LiterateData.InjectedFrontMatter frontMatter, @NotNull PrettierOptions options ) throws IOException { - return LiterateData.toDoc(this, moduleName(), program.get(), problems, datetimeFrontMatterKey, options); + return LiterateData.toDoc(this, moduleName(), program.get(), problems, frontMatter, options); } @Override public @NotNull ImmutableSeq parseMe(@NotNull GenericAyaParser parser) throws IOException { diff --git a/cli-impl/src/main/java/org/aya/cli/single/CompilerFlags.java b/cli-impl/src/main/java/org/aya/cli/single/CompilerFlags.java index 21625cb545..6f87b635f9 100644 --- a/cli-impl/src/main/java/org/aya/cli/single/CompilerFlags.java +++ b/cli-impl/src/main/java/org/aya/cli/single/CompilerFlags.java @@ -32,10 +32,11 @@ public record CompilerFlags( CliEnums.detectFormat(outputFile), AyaPrettierOptions.pretty(), renderOptions, - null, null); + null, null, null); return null; } + /// @param datetimeFrontMatterValue see {@link org.aya.cli.utils.LiterateData.InjectedFrontMatter} public record PrettyInfo( boolean ascii, boolean prettyNoCodeStyle, @@ -46,6 +47,7 @@ public record PrettyInfo( @NotNull PrettierOptions prettierOptions, @NotNull RenderOptions renderOptions, @Nullable String datetimeFrontMatterKey, + @Nullable String datetimeFrontMatterValue, @Nullable String prettyDir ) { public @NotNull RenderOptions.DefaultSetup backendOpts(boolean headerCode) { diff --git a/cli-impl/src/main/java/org/aya/cli/single/SingleAyaFile.java b/cli-impl/src/main/java/org/aya/cli/single/SingleAyaFile.java index 2773fe0ce2..70b663f890 100644 --- a/cli-impl/src/main/java/org/aya/cli/single/SingleAyaFile.java +++ b/cli-impl/src/main/java/org/aya/cli/single/SingleAyaFile.java @@ -22,6 +22,7 @@ import org.aya.util.FileUtil; import org.aya.util.error.SourceFile; import org.aya.util.error.SourceFileLocator; +import org.aya.util.more.StringUtil; import org.aya.util.prettier.PrettierOptions; import org.aya.util.reporter.CollectingReporter; import org.aya.util.reporter.Problem; @@ -64,8 +65,11 @@ public sealed interface SingleAyaFile extends GenericAyaFile { var renderOptions = flags.renderOptions(); if (currentStage == CliEnums.PrettyStage.literate) { + var value = flags.datetimeFrontMatterValue(); + if (value == null) value = StringUtil.timeInGitFormat(); + var frontMatter = new LiterateData.InjectedFrontMatter(flags.datetimeFrontMatterKey(), value); var d = toDoc((ImmutableSeq) doc, reporter.problems().toImmutableSeq(), - flags.datetimeFrontMatterKey(), flags.prettierOptions()); + frontMatter, flags.prettierOptions()); var text = renderOptions.render(out, d, flags.backendOpts(true)); FileUtil.writeString(prettyDir.resolve(fileName), text); } else { @@ -76,9 +80,9 @@ public sealed interface SingleAyaFile extends GenericAyaFile { @VisibleForTesting default @NotNull Doc toDoc( @NotNull ImmutableSeq program, @NotNull ImmutableSeq problems, - @Nullable String datetimeFrontMatterKey, @NotNull PrettierOptions options + @NotNull LiterateData.InjectedFrontMatter frontMatter, @NotNull PrettierOptions options ) throws IOException { - return LiterateData.toDoc(this, null, program, problems, datetimeFrontMatterKey, options); + return LiterateData.toDoc(this, null, program, problems, frontMatter, options); } private void doWrite( diff --git a/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java b/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java index 791128a801..a40dbc9f54 100644 --- a/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java +++ b/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java @@ -37,8 +37,6 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; public record LiterateData( @NotNull Literate literate, @@ -105,20 +103,23 @@ public void tyck(@NotNull ResolveInfo info) { }); } + public record InjectedFrontMatter( + @Nullable String datetimeKey, + @NotNull String datetimeValue + ) { } public static @NotNull Doc toDoc( @NotNull GenericAyaFile ayaFile, @Nullable ModulePath currentFileModule, @NotNull ImmutableSeq program, @NotNull ImmutableSeq problems, - @Nullable String datetimeFrontMatterKey, + @NotNull InjectedFrontMatter injected, @NotNull PrettierOptions options ) throws IOException { var highlights = SyntaxHighlight.highlight(currentFileModule, Option.some(ayaFile.codeFile()), program); var literate = ayaFile.literate(); - if (datetimeFrontMatterKey != null) { - var datetime = ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss X")); + if (injected.datetimeKey != null) { var frontMatter = literate.findFrontMatter(); - var label = new Literate.Raw(Doc.plain(datetimeFrontMatterKey + ": " + datetime)); + var label = new Literate.Raw(Doc.plain(injected.datetimeKey + ": " + injected.datetimeValue)); if (frontMatter != null) { frontMatter.children().append(label); } else { diff --git a/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java b/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java index 60af79536c..ea43641434 100644 --- a/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java +++ b/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java @@ -7,6 +7,7 @@ import org.aya.cli.single.CompilerFlags; import org.aya.cli.single.SingleAyaFile; import org.aya.cli.single.SingleFileCompiler; +import org.aya.cli.utils.LiterateData; import org.aya.generic.Constants; import org.aya.prettier.AyaPrettierOptions; import org.aya.primitive.PrimFactory; @@ -17,6 +18,7 @@ import org.aya.util.FileUtil; import org.aya.util.error.Global; import org.aya.util.error.SourceFile; +import org.aya.util.more.StringUtil; import org.aya.util.reporter.BufferReporter; import org.aya.util.reporter.IgnoringReporter; import org.aya.util.reporter.ThrowingReporter; @@ -97,8 +99,9 @@ public void testHighlight(String caseName) throws IOException { loader.tyckModule(info, null); literate.tyckAdditional(info); + var defaultFM = new LiterateData.InjectedFrontMatter(null, StringUtil.timeInGitFormat()); var doc = literate.toDoc(stmts, reporter.problems().toImmutableSeq(), - null, AyaPrettierOptions.pretty()).toDoc(); + defaultFM, AyaPrettierOptions.pretty()).toDoc(); reporter.problems().clear(); // save some coverage var actualTexInlinedStyle = doc.renderToTeX(); diff --git a/tools-kala/src/main/java/org/aya/util/more/StringUtil.java b/tools-kala/src/main/java/org/aya/util/more/StringUtil.java index e687d09108..29511e1614 100644 --- a/tools-kala/src/main/java/org/aya/util/more/StringUtil.java +++ b/tools-kala/src/main/java/org/aya/util/more/StringUtil.java @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2023 Tesla (Yinsen) Zhang. +// Copyright (c) 2020-2024 Tesla (Yinsen) Zhang. // Use of this source code is governed by the MIT license that can be found in the LICENSE.md file. package org.aya.util.more; @@ -7,6 +7,9 @@ import kala.tuple.primitive.IntObjTuple2; import org.jetbrains.annotations.NotNull; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + public interface StringUtil { /** Arend */ static @NotNull String timeToString(long time) { @@ -16,6 +19,10 @@ public interface StringUtil { return (seconds / 60) + "m" + (seconds % 60) + "s"; } + static @NotNull String timeInGitFormat() { + return ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss X")); + } + /** * all line separators are treat as 1 character long * From 5757dddd9ad3538c5cfe9a43d321c61e2d6d69e8 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Sun, 22 Dec 2024 02:43:26 -0500 Subject: [PATCH 5/9] doc: add some comments --- .../src/main/java/org/aya/cli/library/json/LibraryConfig.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cli-impl/src/main/java/org/aya/cli/library/json/LibraryConfig.java b/cli-impl/src/main/java/org/aya/cli/library/json/LibraryConfig.java index bc9a202036..2f8947145b 100644 --- a/cli-impl/src/main/java/org/aya/cli/library/json/LibraryConfig.java +++ b/cli-impl/src/main/java/org/aya/cli/library/json/LibraryConfig.java @@ -27,6 +27,9 @@ public record LibraryConfig( @NotNull LibraryLiterateConfig literateConfig, @NotNull ImmutableSeq deps ) { + /// @param datetimeFrontMatterKey it makes little sense to specify the "values" too, + /// because a library has many files, and each file should + /// have their own modified time, which is unrealistic to retrieve. public record LibraryLiterateConfig( @Nullable LiteratePrettierOptions pretty, @Nullable String datetimeFrontMatterKey, From 9208962cb441bbea85d9d9982c725db27ac9da01 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Sun, 22 Dec 2024 02:49:20 -0500 Subject: [PATCH 6/9] misc: contrived update of copyright of some old files --- .../cli/library/json/LibraryDependency.java | 8 +++---- .../test/java/org/aya/test/LibraryTest.java | 2 +- .../org/aya/test/cli/LibraryGraphTest.java | 2 +- .../java/org/aya/pretty/printer/Printer.java | 22 +++++++++---------- .../aya/util/reporter/DelayedReporter.java | 6 ++--- 5 files changed, 18 insertions(+), 22 deletions(-) diff --git a/cli-impl/src/main/java/org/aya/cli/library/json/LibraryDependency.java b/cli-impl/src/main/java/org/aya/cli/library/json/LibraryDependency.java index ba10724bb5..a00991840e 100644 --- a/cli-impl/src/main/java/org/aya/cli/library/json/LibraryDependency.java +++ b/cli-impl/src/main/java/org/aya/cli/library/json/LibraryDependency.java @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2021 Yinsen (Tesla) Zhang. +// Copyright (c) 2020-2024 Tesla (Yinsen) Zhang. // Use of this source code is governed by the MIT license that can be found in the LICENSE.md file. package org.aya.cli.library.json; @@ -9,7 +9,7 @@ public sealed interface LibraryDependency { @NotNull String depName(); - record DepVersion(@NotNull String depName, @NotNull String version) implements LibraryDependency { } - record DepGithub(@NotNull String depName, @NotNull String repo) implements LibraryDependency { } - record DepFile(@NotNull String depName, @NotNull Path depRoot) implements LibraryDependency { } + record DepVersion(@Override @NotNull String depName, @NotNull String version) implements LibraryDependency { } + record DepGithub(@Override @NotNull String depName, @NotNull String repo) implements LibraryDependency { } + record DepFile(@Override @NotNull String depName, @NotNull Path depRoot) implements LibraryDependency { } } diff --git a/cli-impl/src/test/java/org/aya/test/LibraryTest.java b/cli-impl/src/test/java/org/aya/test/LibraryTest.java index 134b9aa962..43b3b9b371 100644 --- a/cli-impl/src/test/java/org/aya/test/LibraryTest.java +++ b/cli-impl/src/test/java/org/aya/test/LibraryTest.java @@ -73,7 +73,7 @@ public static void main(String... args) throws IOException { private static @NotNull CompilerFlags makeFlagsForPretty() { var prettyInfo = new CompilerFlags.PrettyInfo( true, false, false, false, CliEnums.PrettyStage.literate, - CliEnums.PrettyFormat.html, AyaPrettierOptions.pretty(), new RenderOptions(), null + CliEnums.PrettyFormat.html, AyaPrettierOptions.pretty(), new RenderOptions(), null, null, null ); return new CompilerFlags(CompilerFlags.Message.ASCII, false, false, prettyInfo, SeqView.empty(), null); } diff --git a/cli-impl/src/test/java/org/aya/test/cli/LibraryGraphTest.java b/cli-impl/src/test/java/org/aya/test/cli/LibraryGraphTest.java index f4eb408473..e11fe1c5ad 100644 --- a/cli-impl/src/test/java/org/aya/test/cli/LibraryGraphTest.java +++ b/cli-impl/src/test/java/org/aya/test/cli/LibraryGraphTest.java @@ -52,7 +52,7 @@ public TestLibraryOwner(@NotNull LibraryConfig underlyingLibrary) { libRoot.resolve("src"), libRoot.resolve("build"), libRoot.resolve("build/out"), - new LibraryConfig.LibraryLiterateConfig(new LiteratePrettierOptions(), "11.4.5.14", libRoot.resolve("literate")), + new LibraryConfig.LibraryLiterateConfig(new LiteratePrettierOptions(), null, "11.4.5.14", libRoot.resolve("literate")), ImmutableSeq.empty() ); } diff --git a/pretty/src/main/java/org/aya/pretty/printer/Printer.java b/pretty/src/main/java/org/aya/pretty/printer/Printer.java index f4d8fa1518..41b6039678 100644 --- a/pretty/src/main/java/org/aya/pretty/printer/Printer.java +++ b/pretty/src/main/java/org/aya/pretty/printer/Printer.java @@ -1,21 +1,19 @@ -// Copyright (c) 2020-2021 Yinsen (Tesla) Zhang. +// Copyright (c) 2020-2024 Tesla (Yinsen) Zhang. // Use of this source code is governed by the MIT license that can be found in the LICENSE.md file. package org.aya.pretty.printer; import org.aya.pretty.doc.Doc; import org.jetbrains.annotations.NotNull; -/** - * This class was designed to support various PrettyPrint backend. - * Example usage: - *
- *   public class HtmlPrinter implements Printer[HtmlPrinterConfig] {}
- * 
- *

- * For a more practical example, see {@link org.aya.pretty.backend.string.StringPrinter} - * - * @author kiva - */ +/// This class was designed to support various PrettyPrint backend. +/// Example usage: +/// ```java +/// public class HtmlPrinter implements Printer {} +/// ``` +/// +/// For a more practical example, see [org.aya.pretty.backend.string.StringPrinter] +/// +/// @author kiva public interface Printer { /** * Render a {@link Doc} object with a config. diff --git a/tools/src/main/java/org/aya/util/reporter/DelayedReporter.java b/tools/src/main/java/org/aya/util/reporter/DelayedReporter.java index 3bf58671d6..8a76036bf6 100644 --- a/tools/src/main/java/org/aya/util/reporter/DelayedReporter.java +++ b/tools/src/main/java/org/aya/util/reporter/DelayedReporter.java @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2022 Yinsen (Tesla) Zhang. +// Copyright (c) 2020-2024 Tesla (Yinsen) Zhang. // Use of this source code is governed by the MIT license that can be found in the LICENSE.md file. package org.aya.util.reporter; @@ -22,7 +22,5 @@ public void reportNow() { problems.clear(); } - @Override public void close() { - reportNow(); - } + @Override public void close() { reportNow(); } } From 3614d5f2455561d4e53850a43a15dc029141f777 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Sun, 22 Dec 2024 02:54:21 -0500 Subject: [PATCH 7/9] test: make it cook --- .../src/test/java/org/aya/test/literate/AyaMdParserTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java b/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java index ea43641434..410dff4f1f 100644 --- a/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java +++ b/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java @@ -99,7 +99,7 @@ public void testHighlight(String caseName) throws IOException { loader.tyckModule(info, null); literate.tyckAdditional(info); - var defaultFM = new LiterateData.InjectedFrontMatter(null, StringUtil.timeInGitFormat()); + var defaultFM = new LiterateData.InjectedFrontMatter("lastUpdated", StringUtil.timeInGitFormat()); var doc = literate.toDoc(stmts, reporter.problems().toImmutableSeq(), defaultFM, AyaPrettierOptions.pretty()).toDoc(); reporter.problems().clear(); From 06d59550e6408a8c4acc8331571bd387ebddc291 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Sun, 22 Dec 2024 03:07:04 -0500 Subject: [PATCH 8/9] test: revert the very stupid way to increase coverage, use a smarter way --- .../aya/test/literate/AyaMdParserTest.java | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java b/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java index 410dff4f1f..1e51a13e18 100644 --- a/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java +++ b/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java @@ -3,6 +3,7 @@ package org.aya.test.literate; import kala.collection.SeqView; +import kala.collection.immutable.ImmutableSeq; import org.aya.cli.render.RenderOptions; import org.aya.cli.single.CompilerFlags; import org.aya.cli.single.SingleAyaFile; @@ -14,6 +15,7 @@ import org.aya.producer.AyaParserImpl; import org.aya.resolve.context.EmptyContext; import org.aya.resolve.module.DumbModuleLoader; +import org.aya.syntax.concrete.stmt.Stmt; import org.aya.test.TestRunner; import org.aya.util.FileUtil; import org.aya.util.error.Global; @@ -24,6 +26,7 @@ import org.aya.util.reporter.ThrowingReporter; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -84,10 +87,7 @@ public void testExtract(String caseName) throws IOException { } } - @ParameterizedTest - @ValueSource(strings = {"hoshino-said", "wow", "test", "heading", "compiler-output"}) - public void testHighlight(String caseName) throws IOException { - var oneCase = new Case(caseName); + private static @NotNull LiterateTestCase initLiterateTestCase(Case oneCase) throws IOException { var mdFile = new SingleAyaFile.CodeAyaFile(file(oneCase.mdFile())); var reporter = new BufferReporter(); @@ -98,11 +98,23 @@ public void testHighlight(String caseName) throws IOException { var info = loader.resolveModule(new PrimFactory(), ctx, stmts, loader); loader.tyckModule(info, null); literate.tyckAdditional(info); + return new LiterateTestCase(reporter, literate, stmts); + } + private record LiterateTestCase( + BufferReporter reporter, SingleAyaFile.MarkdownAyaFile literate, + ImmutableSeq stmts + ) { } - var defaultFM = new LiterateData.InjectedFrontMatter("lastUpdated", StringUtil.timeInGitFormat()); - var doc = literate.toDoc(stmts, reporter.problems().toImmutableSeq(), + @ParameterizedTest + @ValueSource(strings = {"hoshino-said", "wow", "test", "heading", "compiler-output"}) + public void testHighlight(String caseName) throws IOException { + var oneCase = new Case(caseName); + var data = initLiterateTestCase(oneCase); + + var defaultFM = new LiterateData.InjectedFrontMatter(null, StringUtil.timeInGitFormat()); + var doc = data.literate().toDoc(data.stmts(), data.reporter().problems().toImmutableSeq(), defaultFM, AyaPrettierOptions.pretty()).toDoc(); - reporter.problems().clear(); + data.reporter().problems().clear(); // save some coverage var actualTexInlinedStyle = doc.renderToTeX(); var expectedMd = doc.renderToAyaMd(); @@ -131,6 +143,15 @@ public void testHighlight(String caseName) throws IOException { assertFalse(actualTexButKa.isEmpty()); } + @Test public void testTime() throws IOException { + var oneCase = new Case("heading"); + var data = initLiterateTestCase(oneCase); + var defaultFM = new LiterateData.InjectedFrontMatter("lastUpdated", StringUtil.timeInGitFormat()); + var doc = data.literate().toDoc(data.stmts(), data.reporter().problems().toImmutableSeq(), + defaultFM, AyaPrettierOptions.pretty()).toDoc(); + assertTrue(doc.renderToMd().startsWith("---\nlastUpdated: ")); + } + private @NotNull String trim(@NotNull String input) { return input.replaceAll("id=\"[^\"]+\"", "id=\"\"") .replaceAll("href=\"[^\"]+\"", "href=\"\"") From 87f05c1955eaa174c481dc7c41d8ac3611705432 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Sun, 22 Dec 2024 03:13:10 -0500 Subject: [PATCH 9/9] test: also test with preexisting --- .../main/java/org/aya/cli/utils/LiterateData.java | 5 ++++- .../java/org/aya/test/literate/AyaMdParserTest.java | 13 ++++++++++--- .../src/test/resources/literate/frontmatter.aya.md | 4 ++++ 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 cli-impl/src/test/resources/literate/frontmatter.aya.md diff --git a/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java b/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java index a40dbc9f54..709a3ec491 100644 --- a/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java +++ b/cli-impl/src/main/java/org/aya/cli/utils/LiterateData.java @@ -121,7 +121,10 @@ public record InjectedFrontMatter( var frontMatter = literate.findFrontMatter(); var label = new Literate.Raw(Doc.plain(injected.datetimeKey + ": " + injected.datetimeValue)); if (frontMatter != null) { - frontMatter.children().append(label); + // They must be non-empty because the front matter starts with a --- + var secondLast = frontMatter.children().size() - 2; + frontMatter.children().insert(secondLast, label); + frontMatter.children().insert(secondLast, Literate.EOL); } else { var delimiter = new Literate.Raw(Doc.plain("---")); frontMatter = new Literate.FrontMatter(MutableList.of( diff --git a/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java b/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java index 1e51a13e18..df0605ef3b 100644 --- a/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java +++ b/cli-impl/src/test/java/org/aya/test/literate/AyaMdParserTest.java @@ -11,6 +11,7 @@ import org.aya.cli.utils.LiterateData; import org.aya.generic.Constants; import org.aya.prettier.AyaPrettierOptions; +import org.aya.pretty.doc.Doc; import org.aya.primitive.PrimFactory; import org.aya.producer.AyaParserImpl; import org.aya.resolve.context.EmptyContext; @@ -144,12 +145,18 @@ public void testHighlight(String caseName) throws IOException { } @Test public void testTime() throws IOException { - var oneCase = new Case("heading"); + var doc = lastUpdatedTest("heading"); + assertTrue(doc.renderToMd().startsWith("---\nlastUpdated: ")); + doc = lastUpdatedTest("frontmatter"); + assertTrue(doc.renderToMd().startsWith("---\ntitle: Twitter\nlastUpdated: ")); + } + + private static @NotNull Doc lastUpdatedTest(String caseName) throws IOException { + var oneCase = new Case(caseName); var data = initLiterateTestCase(oneCase); var defaultFM = new LiterateData.InjectedFrontMatter("lastUpdated", StringUtil.timeInGitFormat()); - var doc = data.literate().toDoc(data.stmts(), data.reporter().problems().toImmutableSeq(), + return data.literate().toDoc(data.stmts(), data.reporter().problems().toImmutableSeq(), defaultFM, AyaPrettierOptions.pretty()).toDoc(); - assertTrue(doc.renderToMd().startsWith("---\nlastUpdated: ")); } private @NotNull String trim(@NotNull String input) { diff --git a/cli-impl/src/test/resources/literate/frontmatter.aya.md b/cli-impl/src/test/resources/literate/frontmatter.aya.md new file mode 100644 index 0000000000..b599c609f5 --- /dev/null +++ b/cli-impl/src/test/resources/literate/frontmatter.aya.md @@ -0,0 +1,4 @@ +--- +title: Twitter +--- +# Hello, world!