enhance page parsing using json output and html

This commit is contained in:
Adrien
2026-04-05 21:55:30 +02:00
parent ea1276dc2e
commit 5c641f4bcc
9 changed files with 292 additions and 258 deletions
+5 -2
View File
@@ -64,11 +64,11 @@ body {
Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
background: #f0f4f8;
color: #2d3748;
min-height: 100vh;
height: 100vh;
}
#app {
min-height: 100vh;
height: 100vh;
display: flex;
flex-direction: column;
}
@@ -133,6 +133,9 @@ body {
.main-content {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
padding: 2rem;
max-width: 1200px;
margin: 0 auto;
+14 -11
View File
@@ -44,7 +44,6 @@
<script setup lang="ts">
import { ref, watch, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { marked } from 'marked'
import { api } from '@/services/api'
import { useBookStore } from '@/stores/bookStore'
import type { Book } from '@/stores/bookStore'
@@ -104,15 +103,11 @@ async function loadPage(page: number) {
activeBlobUrls = []
try {
const res = await api.get<string>(`/books/${bookId}/pages/${page}/markdown`, {
headers: { Accept: 'text/plain' },
const res = await api.get<string>(`/books/${bookId}/pages/${page}/html`, {
headers: { Accept: 'text/html' },
responseType: 'text'
})
const markdownText = res.data
// Render markdown to HTML, then resolve image src via authenticated fetch
let html = await marked.parse(markdownText) as string
html = await resolveImages(html)
let html = await resolveImages(res.data)
renderedHtml.value = html
} catch (e: any) {
error.value = e.message ?? 'Failed to load page.'
@@ -123,8 +118,8 @@ async function loadPage(page: number) {
/**
* Finds <img src="/api/v1/figures/..."> in the HTML, fetches each image
* with the authenticated axios instance (which carries Basic auth headers),
* and replaces the src with a temporary blob URL so the browser can display it.
* through the authenticated axios instance, and replaces the src with a
* temporary blob URL so the browser can render it without re-authenticating.
*/
async function resolveImages(html: string): Promise<string> {
const srcPattern = /src="(\/api\/v1\/figures\/[^"]+)"/g
@@ -137,7 +132,7 @@ async function resolveImages(html: string): Promise<string> {
await Promise.all(
unique.map(async (src) => {
try {
const res = await api.get(src, { responseType: 'blob' })
const res = await api.get(src.replace(/^\/api\/v1/, ''), { responseType: 'blob' })
const blobUrl = URL.createObjectURL(res.data)
activeBlobUrls.push(blobUrl)
blobMap[src] = blobUrl
@@ -160,6 +155,8 @@ async function resolveImages(html: string): Promise<string> {
gap: 1rem;
max-width: 860px;
margin: 0 auto;
flex: 1;
min-height: 0;
}
.reader-header {
@@ -238,6 +235,9 @@ async function resolveImages(html: string): Promise<string> {
.reader-body {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.reader-loading {
@@ -255,6 +255,9 @@ async function resolveImages(html: string): Promise<string> {
}
.reader-content {
flex: 1;
min-height: 0;
overflow-y: auto;
padding: 2rem;
}