diff options
| author | Joe Mou <dev@mou.fo> | 2026-01-28 13:05:02 -0500 |
|---|---|---|
| committer | Joe Mou <dev@mou.fo> | 2026-01-28 15:17:54 -0500 |
| commit | dd8d686c9eb9a68eb057aaf86206bc930e22d09a (patch) | |
| tree | df34df851c57e2d268fba42ecff0708bfd8a8e18 | |
| parent | 200defaa5c769b4603f9256e943821344cadbe82 (diff) | |
Render Markdown blobs
| -rw-r--r-- | src/scraper.test.ts | 38 | ||||
| -rw-r--r-- | src/scraper.ts | 39 | ||||
| -rw-r--r-- | static/style.css | 10 | ||||
| -rw-r--r-- | views/blob.eta | 10 |
4 files changed, 64 insertions, 33 deletions
diff --git a/src/scraper.test.ts b/src/scraper.test.ts index e7e65ba..f3a472d 100644 --- a/src/scraper.test.ts +++ b/src/scraper.test.ts @@ -59,7 +59,7 @@ describe("GitHub scraper", () => { ]); }); - it("should fetch blob", async () => { + it("should fetch text blob", async () => { const data = await getGitHubBlob("actions", "deploy-pages", "main", "LICENSE"); assert.strictEqual(data.repo.owner, "actions"); @@ -67,10 +67,40 @@ describe("GitHub scraper", () => { assert.strictEqual(data.branch, "main"); assert.strictEqual(data.path, "LICENSE"); - assert.strictEqual(data.size, 1068); + assert.strictEqual(data.size, "1.04 KB / 21 lines / 17 loc"); assert.strictEqual(data.language, "Text"); - assert.match(data.rawContent, /^MIT License\n\n/); - assert.match(data.content, /^MIT License\n\n/); + assert.strictEqual(data.rawLines?.[0], "MIT License"); + assert.strictEqual(data.htmlContent, null); + }); + + it("should fetch Markdown blob", async () => { + const data = await getGitHubBlob("actions", "deploy-pages", "main", "README.md"); + + assert.strictEqual(data.repo.owner, "actions"); + assert.strictEqual(data.repo.name, "deploy-pages"); + assert.strictEqual(data.branch, "main"); + assert.strictEqual(data.path, "README.md"); + + assert.strictEqual(data.size, "8.95 KB / 133 lines / 94 loc"); + assert.strictEqual(data.language, "Markdown"); + assert.strictEqual(data.rawLines, null); + const firstLine = + /^<article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">deploy-pages 🚀<\/h1>/; + assert.match(data.htmlContent ?? "", firstLine); + }); + + it("should fetch code blob", async () => { + const data = await getGitHubBlob("actions", "deploy-pages", "main", ".gitattributes"); + + assert.strictEqual(data.repo.owner, "actions"); + assert.strictEqual(data.repo.name, "deploy-pages"); + assert.strictEqual(data.branch, "main"); + assert.strictEqual(data.path, ".gitattributes"); + + assert.strictEqual(data.size, "39 Bytes / 1 lines / 1 loc"); + assert.strictEqual(data.language, "Git Attributes"); + assert.deepStrictEqual(data.rawLines, ["dist/** -diff linguist-generated=true "]); + assert.strictEqual(data.htmlContent, null); }); it("should fetch issues", async () => { diff --git a/src/scraper.ts b/src/scraper.ts index bbf7511..c2983c9 100644 --- a/src/scraper.ts +++ b/src/scraper.ts @@ -16,7 +16,6 @@ interface TreeItem { interface OverviewFile { displayName: string; - preferredFileType: string; richText?: string; loaded: boolean; } @@ -64,12 +63,17 @@ interface RawPayload { items: TreeItem[]; }; blob?: { + headerInfo: { + blobSize: string; + lineInfo: { + truncatedLoc: string; + truncatedSloc: string; + }; + }; language?: string; - rawLines?: string[]; - highlightedLines?: { - text?: string; - }[]; - size: number; + rawLines: string[] | null; + colorizedLines: string[] | null; + richText: string | null; }; overview?: { overviewFiles?: OverviewFile[]; @@ -110,9 +114,9 @@ export interface GitHubRepo extends GitHubTree { export interface GitHubBlob extends GitHubNav { language: string | null; - size: number | null; - content: string; - rawContent: string; + size: string; + rawLines: string[] | null; + htmlContent: string | null; } interface Issue { @@ -265,20 +269,15 @@ export async function getGitHubBlob( throw new Error("Could not find blob data in embedded JSON"); } - const blob = payload.blob; - const rawLines = blob.rawLines || []; - const rawContent = rawLines.join("\n"); - const highlightedLines = blob.highlightedLines || []; - const content = highlightedLines.map((line) => line.text || "").join("\n"); - - // Calculate size from raw content if not provided - const size = blob.size ?? (rawContent.length > 0 ? Buffer.byteLength(rawContent, "utf8") : null); + const { headerInfo, language, rawLines, richText } = payload.blob; + // TODO fine tune + const size = `${headerInfo.blobSize} / ${headerInfo.lineInfo.truncatedLoc} lines / ${headerInfo.lineInfo.truncatedSloc} loc`; return extractGitHub(payload, { - content: content || rawContent, - rawContent, - language: blob.language || null, + language: language || null, size, + rawLines, + htmlContent: richText, }); } diff --git a/static/style.css b/static/style.css index 7618937..1efbb12 100644 --- a/static/style.css +++ b/static/style.css @@ -163,14 +163,14 @@ pre.box { code { background: var(--shade-background); } - - /* TODO Strip permalinks? */ - svg.octicon-link { - display: none; - } } .timestamp { white-space: nowrap; font-size: .8rem; } + +/* TODO Strip permalinks? */ +svg.octicon-link { + display: none; +} diff --git a/views/blob.eta b/views/blob.eta index 277b46d..346afab 100644 --- a/views/blob.eta +++ b/views/blob.eta @@ -6,12 +6,14 @@ <% if (it.language) { %> <div>language: <%= it.language %></div> <% } %> - <% if (it.size !== undefined) { %> - <div>size: <%= it.size %> bytes</div> - <% } %> + <div><%= it.size %></div> <div> <a href="/<%= it.repo.owner %>/<%= it.repo.name %>/raw/<%= it.branch %>/<%= it.path %>">Raw</a> </div> </div> -<pre class="box"><code><%= it.rawContent %></code></pre> +<% if (it.htmlContent) { %> + <div class="box"><%~ it.htmlContent %></div> +<% } else { %> + <pre class="box"><code><%= it.rawLines.join("\n") %></code></pre> +<% } %> |
