Files
ERitors-Scribe-Desktop/lib/models/Chapter.ts
natreex b4eafca3bc Add comprehensive models and script for handling inline scripts and structured data
- Implement `remove-inline-scripts.js` to externalize Next.js inline scripts, enhancing CSP compliance.
- Add models for `Book`, `Character`, `Story`, `Editor`, `System`, and `BookSerie` with relevant properties and utilities.
- Include macOS entitlements plist for app development with advanced permissions.
- Add utility functions to handle script hashing, cookie management, and content formatting.
2025-11-16 19:56:14 -05:00

197 lines
5.9 KiB
TypeScript

import {SelectBoxProps} from "@/shared/interface";
export interface ActChapter {
chapterInfoId: string;
chapterId: string;
title: string;
chapterOrder: number;
actId: number;
incidentId?: string;
plotPointId?: string;
summary: string;
goal: string;
}
export interface ChapterListProps {
chapterId: string;
title: string;
summary?: string;
chapterOrder?: number;
goal?: string;
}
export interface ChapterProps {
chapterId: string;
chapterOrder: number;
title: string;
chapterContent: ChapterContent;
}
export interface ChapterContent {
version: number;
content: string;
wordsCount: number;
}
export interface ChapterVersion {
value: number;
label: 'Invite' | 'Brouillon' | 'Perfectionnement' | 'Révision' | 'Finale';
}
export type TiptapNode = {
type: string;
content?: TiptapNode[];
text?: string;
attrs?: {
[key: string]: any;
};
};
export const chapterVersions: SelectBoxProps[] = [
{value: '1', label: 'chapterVersions.prompt'},
{value: '2', label: 'chapterVersions.draft'},
{value: '3', label: 'chapterVersions.refine'},
{value: '4', label: 'chapterVersions.review'},
{value: '5', label: 'chapterVersions.final'},
];
export default class Chapter {
public static getPageCount(text: string): number {
const charactersPerLine = 90;
const linesPerPage = 40;
const lines: string[] = text.split('\n');
let totalLines: number = 0;
lines.forEach((line: string) => {
const lineLength: number = line.length;
const estimatedLines: number = Math.ceil(lineLength / charactersPerLine);
totalLines += estimatedLines;
});
// Calcul du nombre de pages
return Math.ceil(totalLines / linesPerPage);
}
static convertTiptapToHTML(node: TiptapNode): string {
let html = '';
switch (node.type) {
case 'doc':
if (node.content) {
node.content.forEach(childNode => {
html += this.convertTiptapToHTML(childNode);
});
}
break;
case 'paragraph':
html += '<p>';
if (node.content) {
node.content.forEach(childNode => {
html += this.convertTiptapToHTML(childNode);
});
}
html += '</p>';
break;
case 'text':
let textContent = node.text || '';
// Apply attributes like bold, italic, etc.
if (node.attrs) {
if (node.attrs.bold) {
textContent = `<strong>${textContent}</strong>`;
}
if (node.attrs.italic) {
textContent = `<em>${textContent}</em>`;
}
if (node.attrs.underline) {
textContent = `<u>${textContent}</u>`;
}
if (node.attrs.strike) {
textContent = `<s>${textContent}</s>`;
}
if (node.attrs.link) {
textContent = `<a href="${node.attrs.link.href}">${textContent}</a>`;
}
}
html += textContent;
break;
case 'heading':
const level = node.attrs?.level || 1;
html += `<h${level}>`;
if (node.content) {
node.content.forEach(childNode => {
html += this.convertTiptapToHTML(childNode);
});
}
html += `</h${level}>`;
break;
case 'bulletList':
html += '<ul>';
if (node.content) {
node.content.forEach(childNode => {
html += this.convertTiptapToHTML(childNode);
});
}
html += '</ul>';
break;
case 'orderedList':
html += '<ol>';
if (node.content) {
node.content.forEach(childNode => {
html += this.convertTiptapToHTML(childNode);
});
}
html += '</ol>';
break;
case 'listItem':
html += '<li>';
if (node.content) {
node.content.forEach(childNode => {
html += this.convertTiptapToHTML(childNode);
});
}
html += '</li>';
break;
case 'blockquote':
html += '<blockquote>';
if (node.content) {
node.content.forEach(childNode => {
html += this.convertTiptapToHTML(childNode);
});
}
html += '</blockquote>';
break;
case 'codeBlock':
html += '<pre><code>';
if (node.content) {
node.content.forEach(childNode => {
html += this.convertTiptapToHTML(childNode);
});
}
html += '</code></pre>';
break;
default:
console.warn(`Unhandled node type: ${node.type}`);
if (node.content) {
node.content.forEach(childNode => {
html += this.convertTiptapToHTML(childNode);
});
}
break;
}
return html;
}
}