The rendering doc's running log of finished work is folded into the architecture section and the rest dropped: what remains is why the code is the way it is, the harness, and what is next. The highlights bug is bigger than the backwards span we already drop. The library pairs every `/*` with an `*/` by ordinal position and uses the same delimiters for every language, so a shell glob opens a comment and `//` in any URL comments out the rest of its line, taking the keywords and strings inside it with it. highlights-repro.sh asks the library directly, outside the app, since none of this is visible on a phone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
60 lines
2.7 KiB
Bash
Executable File
60 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# What dev.snipme:highlights actually answers for a piece of code, outside the app.
|
|
#
|
|
# The lexer's mistakes are invisible on a phone -- a line greyed out as a comment looks
|
|
# like a comment -- so this asks it directly and prints every span with the text under
|
|
# it. It is how the `/*`-pairing and URL-comment bugs in TRANSCRIPT_RENDERING.md were
|
|
# measured, and it is what any fix has to be checked against.
|
|
#
|
|
# Usage: ./highlights-repro.sh [LANGUAGE FILE] (default: the known-bad cases)
|
|
set -euo pipefail
|
|
|
|
cache=~/.gradle/caches/modules-2/files-2.1
|
|
jar() { find "$cache/$1" -name "$2" ! -name '*sources*' | sort | tail -1; }
|
|
|
|
cp=$(jar dev.snipme/highlights-jvm/1.1.0 '*.jar')
|
|
cp=$cp:$(jar org.jetbrains.kotlin/kotlin-stdlib '*[0-9].jar')
|
|
cp=$cp:$(jar org.jetbrains.kotlinx/kotlinx-coroutines-core-jvm '*.jar')
|
|
cp=$cp:$(jar org.jetbrains.kotlinx/kotlinx-serialization-core-jvm '*.jar')
|
|
cp=$cp:$(jar org.jetbrains.kotlinx/kotlinx-serialization-json-jvm '*.jar')
|
|
for entry in ${cp//:/ }; do
|
|
[ -f "$entry" ] || { echo "missing jar in the gradle cache: build the app once first" >&2; exit 1; }
|
|
done
|
|
|
|
out=$(mktemp -d)
|
|
trap 'rm -rf "$out"' EXIT
|
|
cat > "$out/Repro.java" <<'JAVA'
|
|
import dev.snipme.highlights.Highlights;
|
|
import dev.snipme.highlights.model.*;
|
|
import java.nio.file.*;
|
|
|
|
public class Repro {
|
|
public static void main(String[] args) throws Exception {
|
|
if (args.length == 2) {
|
|
report(SyntaxLanguage.valueOf(args[0].toUpperCase()), Files.readString(Path.of(args[1])));
|
|
return;
|
|
}
|
|
report(SyntaxLanguage.SHELL, "x '*/a/*'");
|
|
report(SyntaxLanguage.SHELL, "find . -path '*/.git/*' -prune -o -name '*.kt' -print");
|
|
report(SyntaxLanguage.SHELL, "curl https://example.com/x && echo done");
|
|
report(SyntaxLanguage.KOTLIN, "val url = \"https://example.com\"\nfun f() = 1");
|
|
}
|
|
|
|
static void report(SyntaxLanguage language, String code) {
|
|
System.out.println("== [" + language + "] " + code.replace("\n", "\\n"));
|
|
for (CodeHighlight highlight : new Highlights.Builder().code(code).language(language)
|
|
.build().getHighlights()) {
|
|
PhraseLocation at = highlight instanceof ColorHighlight
|
|
? ((ColorHighlight) highlight).getLocation()
|
|
: ((BoldHighlight) highlight).getLocation();
|
|
boolean sane = at.getStart() >= 0 && at.getStart() <= at.getEnd()
|
|
&& at.getEnd() <= code.length();
|
|
System.out.println((sane ? " " : " BAD ") + at + " "
|
|
+ (sane ? "\"" + code.substring(at.getStart(), at.getEnd()) + "\"" : ""));
|
|
}
|
|
}
|
|
}
|
|
JAVA
|
|
javac -cp "$cp" -d "$out" "$out/Repro.java"
|
|
java -cp "$cp:$out" Repro "$@"
|