diff --git a/src/main/java/io/jenkins/plugins/prism/SourcePrinter.java b/src/main/java/io/jenkins/plugins/prism/SourcePrinter.java index 5549e8c..09f32f9 100644 --- a/src/main/java/io/jenkins/plugins/prism/SourcePrinter.java +++ b/src/main/java/io/jenkins/plugins/prism/SourcePrinter.java @@ -31,9 +31,11 @@ class SourcePrinter { private static final ColumnMarker COLUMN_MARKER = new ColumnMarker("-n/a-"); private static final String QT_LINGUIST_PATTERN = ""; + private static final int MAX_LINES_FOR_SYNTAX_HIGHLIGHTING = 5_000; private static final String LINE_NUMBERS = "line-numbers"; private static final String MATCH_BRACES = "match-braces"; private static final String ICON_MD = "icon-md"; + private static final char NEW_LINE = '\n'; private final JenkinsFacade jenkinsFacade; @@ -72,20 +74,47 @@ String render(final String fileName, final Stream lines, final Marker ma StringBuilder after = readBlockUntilLine(stream, Integer.MAX_VALUE); String language = selectLanguageClass(fileName, before); - String code = asCode(before, language, LINE_NUMBERS, MATCH_BRACES) - + asMarkedCode(marked, marker, language, LINE_NUMBERS, "highlight", MATCH_BRACES) + boolean enableSyntaxHighlighting = shouldEnableSyntaxHighlighting(before, marked, after); + String code = asCode(before, getCodeClasses(language, enableSyntaxHighlighting)) + + asMarkedCode(marked, marker, getMarkedCodeClasses(language, enableSyntaxHighlighting)) + createInfoPanel(marker) - + asCode(after, language, LINE_NUMBERS, MATCH_BRACES); + + asCode(after, getCodeClasses(language, enableSyntaxHighlighting)); return pre().with(new UnescapedText(code)).renderFormatted(); } } + private boolean shouldEnableSyntaxHighlighting( + final StringBuilder before, final StringBuilder marked, final StringBuilder after) { + return countLines(before) + countLines(marked) + countLines(after) <= MAX_LINES_FOR_SYNTAX_HIGHLIGHTING; + } + + private int countLines(final StringBuilder text) { + if (text.isEmpty()) { + return 0; + } + return (int) text.chars().filter(c -> c == NEW_LINE).count(); + } + + private String[] getCodeClasses(final String language, final boolean enableSyntaxHighlighting) { + if (enableSyntaxHighlighting) { + return new String[] {language, LINE_NUMBERS, MATCH_BRACES}; + } + return new String[0]; + } + + private String[] getMarkedCodeClasses(final String language, final boolean enableSyntaxHighlighting) { + if (enableSyntaxHighlighting) { + return new String[] {language, LINE_NUMBERS, "highlight", MATCH_BRACES}; + } + return new String[] {"highlight"}; + } + private StringBuilder readBlockUntilLine(final LookaheadStream stream, final int end) { StringBuilder marked = new StringBuilder(); while (stream.hasNext() && stream.getLine() < end) { marked.append(stream.next()); - marked.append("\n"); + marked.append(NEW_LINE); } return marked; } diff --git a/src/test/java/io/jenkins/plugins/prism/SourcePrinterTest.java b/src/test/java/io/jenkins/plugins/prism/SourcePrinterTest.java index d491464..b57cb3f 100644 --- a/src/test/java/io/jenkins/plugins/prism/SourcePrinterTest.java +++ b/src/test/java/io/jenkins/plugins/prism/SourcePrinterTest.java @@ -266,6 +266,38 @@ void shouldRenderQtTranslationFileAsMarkup() { .contains("language-markup"); } + @Test + @org.junitpioneer.jupiter.Issue("JENKINS-73298") + void shouldSkipSyntaxHighlightingForLargeFiles() { + Marker issue = new MarkerBuilder().withLineStart(2_500).build(); + SourcePrinter printer = new SourcePrinter(); + + Document document = Jsoup.parse(printer.render("sample.xml", + Stream.generate(() -> "line").limit(5_001), issue)); + + assertThat(document.getElementsByTag("code").first()) + .isNotNull(); + assertThat(document.getElementsByTag("code").first().classNames()) + .doesNotContain("language-markup", "line-numbers", "match-braces"); + assertThat(document.getElementsByTag("code").get(1).classNames()) + .containsExactly("highlight"); + } + + @Test + @org.junitpioneer.jupiter.Issue("JENKINS-73298") + void shouldKeepSyntaxHighlightingForFilesWithinLimit() { + Marker issue = new MarkerBuilder().withLineStart(2_500).build(); + SourcePrinter printer = new SourcePrinter(); + + Document document = Jsoup.parse(printer.render("sample.xml", + Stream.generate(() -> "line").limit(5_000), issue)); + + assertThat(document.getElementsByTag("code").first()) + .isNotNull(); + assertThat(document.getElementsByTag("code").first().classNames()) + .contains("language-markup", "line-numbers", "match-braces"); + } + private JenkinsFacade createJenkinsFacade() { JenkinsFacade jenkinsFacade = mock(JenkinsFacade.class); when(jenkinsFacade.getImagePath(anyString())).thenReturn("/path/to/icon");