enhance page parsing using json output and html
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user