@@ -106,7 +106,7 @@ jobs:
106106
107107 echo "LT_JAR=${LT_JAR}" >> "$GITHUB_ENV"
108108
109- - name : Run LanguageTool + build PR comment
109+ - name : Run LanguageTool + build PR comment (collapsible + exact word)
110110 env :
111111 BASE_SHA : ${{ github.event.pull_request.base.sha }}
112112 HEAD_SHA : ${{ github.event.pull_request.head.sha }}
@@ -149,13 +149,16 @@ jobs:
149149 jq -c \
150150 --arg file "$f" \
151151 --argjson words "$WORDS_JSON" '
152- def badtoken :
152+ def bad_raw :
153153 (.context.offset // 0) as $o
154154 | (.context.length // 0) as $l
155155 | (.context.text // "") as $t
156- | ($t[$o:($o+$l)]
157- | gsub("^[^[:alnum:]]+|[^[:alnum:]]+$";"")
158- | ascii_downcase);
156+ | ($t[$o:($o+$l)]);
157+
158+ def badtoken:
159+ (bad_raw
160+ | gsub("^[^[:alnum:]]+|[^[:alnum:]]+$";"")
161+ | ascii_downcase);
159162
160163 (.matches // [])
161164 | map(
@@ -171,6 +174,7 @@ jobs:
171174 | {
172175 message: ($m.message // "LanguageTool finding"),
173176 rule: $rid,
177+ bad: (bad_raw),
174178 replacements: (($m.replacements // []) | map(.value) | .[0:3]),
175179 context: ($m.context.text // ""),
176180 context_offset: ($m.context.offset // 0),
@@ -182,7 +186,7 @@ jobs:
182186 done
183187 fi
184188
185- # Build markdown body (stored as a file)
189+ # Build markdown body (stored as a file) - collapsible per file
186190 node <<'NODE'
187191 const fs = require("fs");
188192
@@ -199,7 +203,19 @@ jobs:
199203 let total = 0;
200204 for (const f of Object.keys(byFile)) total += byFile[f].length;
201205
202- let body = `${marker}
206+ function inlineCode(s) {
207+ if (s == null) return "";
208+ return String(s).replace(/`/g, "\\`").replace(/\n/g, " ").trim();
209+ }
210+
211+ function shortContext(text, maxLen=220) {
212+ const t = (text || "").replace(/\s+/g, " ").trim();
213+ if (t.length <= maxLen) return t;
214+ return t.slice(0, maxLen - 1) + "…";
215+ }
216+
217+ let body =
218+ `${marker}
203219 ## LanguageTool report
204220
205221 **Language:** \`${process.env.LT_LANGUAGE || "en-US"}\`
@@ -214,16 +230,23 @@ jobs:
214230 } else {
215231 body += `\n---\n`;
216232 for (const [file, issues] of Object.entries(byFile)) {
217- body += `\n### ${file}\n`;
233+ body += `\n<details>\n<summary><strong> ${file}</strong> — ${issues.length} finding(s)</summary>\n \n`;
218234 for (const it of issues.slice(0, 200)) {
219- const ctx = (it.context || "").replace(/\s+/g, " ").trim( );
220- const snippet = ctx ? `\n> ${ctx}\n` : "" ;
235+ const found = inlineCode (it.bad );
236+ const ctx = shortContext(it.context) ;
221237 const sug = (it.replacements && it.replacements.length)
222- ? `\nSuggested : ${it.replacements.map(s => `\`${s }\``).join(", ")}\n`
238+ ? `Suggested : ${it.replacements.map(s => `\`${inlineCode(s) }\``).join(", ")}\n`
223239 : "";
224- body += `\n- **${it.rule || "RULE"}**: ${it.message}${sug}${snippet}`;
240+ body +=
241+ `- **${inlineCode(it.rule || "RULE")}**: ${inlineCode(it.message)}
242+ - Found: \`${found}\`
243+ - ${sug ? sug.trimEnd() : "Suggested: (none)"}
244+ - Context: ${ctx ? `> ${ctx}` : "(none)"}
245+
246+ `;
225247 }
226- if (issues.length > 200) body += `\n…(${issues.length - 200} more in this file)\n`;
248+ if (issues.length > 200) body += `…(${issues.length - 200} more in this file)\n\n`;
249+ body += `</details>\n`;
227250 }
228251 }
229252
0 commit comments