Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1090,7 +1090,7 @@ const MainApp: React.FC = () => {
}

const renderMainContent = () => {
if (view === 'info') return <InfoView />;
if (view === 'info') return <InfoView settings={settings} />;
if (view === 'settings') return <SettingsView settings={settings} onSave={saveSettings} discoveredServices={discoveredServices} onDetectServices={handleDetectServices} isDetecting={isDetecting} commands={enrichedCommands} />;

if (activeTemplate) {
Expand Down
13 changes: 12 additions & 1 deletion FUNCTIONAL_MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,25 @@ Accessed via the gear icon in the title bar. The settings are organized into cat
- **LLM Provider:** Configure your connection to a local AI service. You can detect running services and select a model.
- **Appearance:** Change the UI scale and choose from different icon sets.
- **Keyboard Shortcuts:** View and customize keyboard shortcuts for all major application actions. You can record a new key combination for any command.
- **General:** Configure application behavior, like auto-saving logs and opting into pre-release updates.
- **General:** Configure application behavior, like auto-saving logs, opting into pre-release updates, and choosing how PlantUML diagrams are rendered.
- **Database:** View detailed statistics about your local database file, and perform maintenance tasks such as creating a compressed backup, checking file integrity, and optimizing the database size (`VACUUM`).
- **Advanced:** View and edit the raw JSON configuration file using an interactive tree or a raw text editor, and import/export your settings.

### Info View

Accessed via the info icon in the title bar. This view contains tabs for reading the application's `README.md`, this `FUNCTIONAL_MANUAL.md`, the `TECHNICAL_MANUAL.md`, and the `VERSION_LOG.md`.

#### PlantUML Rendering Modes

The **General** settings category includes a **PlantUML Rendering** selector. Choose between:

- **Remote (plantuml.com):** Encodes the diagram and requests the SVG from the public PlantUML server.
- **Offline (local renderer):** Invokes the bundled PlantUML engine inside the desktop application. This mode requires a local Java Runtime Environment and access to Graphviz (or the bundled `viz.js` assets) so the renderer can generate diagrams without contacting plantuml.com.

If the Java runtime is unavailable, DocForge will report the error in the preview and you can switch back to remote rendering at any time.

The chosen rendering mode is used for PlantUML code blocks inside Markdown documents *and* for standalone `.puml` documents rendered through the dedicated PlantUML previewer.

### Logger Panel

Accessed via the terminal icon in the title bar, this panel is your primary tool for debugging and monitoring application activity.
Expand Down
4 changes: 3 additions & 1 deletion TECHNICAL_MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This document provides a technical overview of the DocForge application's archit
- **Bundler:** [esbuild](https://esbuild.github.io/) for fast and efficient bundling of the application's source code.
- **Styling:** [Tailwind CSS](https://tailwindcss.com/) for a utility-first CSS framework.
- **Packaging:** [electron-builder](https://www.electron.build/) for creating distributable application packages.
- **Diagram Rendering:** [PlantUML](https://plantuml.com/) via either the public plantuml.com service or the bundled [`node-plantuml`](https://www.npmjs.com/package/node-plantuml) renderer. Offline rendering requires a locally installed Java Runtime Environment and access to Graphviz (or the cached `viz.js` binary) so that diagrams can be rendered without network access.

---

Expand Down Expand Up @@ -93,7 +94,8 @@ This system provides a consistent and extensible editing experience for all docu
- **`CodeEditor.tsx`:** A React component that wraps and configures the Monaco Editor instance. It's responsible for managing the editor's content, theme, and language for syntax highlighting based on props.
- **`PreviewPane.tsx`:** This component is responsible for displaying the rendered output of a document. It debounces content updates for performance and uses the `PreviewService` to get the correct output.
- **`services/previewService.ts`:** This service acts as a registry for all available renderer "plugins." It exposes a method, `getRendererForLanguage()`, which finds and returns the appropriate renderer for a given language ID (e.g., 'markdown').
- **Renderer Plugins (`services/preview/`):** Each file format with a preview is supported by a dedicated renderer class that implements the `IRenderer` interface. This makes the system highly extensible: to support a new format, one only needs to create a new renderer class and add it to the `previewService` registry. Currently, renderers for Markdown, HTML, and plaintext (fallback) are implemented.
- **Renderer Plugins (`services/preview/`):** Each file format with a preview is supported by a dedicated renderer class that implements the `IRenderer` interface. This makes the system highly extensible: to support a new format, one only needs to create a new renderer class and add it to the `previewService` registry. The bundled plugins cover Markdown (with Mermaid + PlantUML support), standalone PlantUML documents, HTML, PDFs, common image formats, and a plaintext fallback renderer.
- Both the Markdown renderer and the standalone PlantUML renderer share the `PlantUMLDiagram` component, which routes diagrams through either the remote plantuml.com server or the offline `node-plantuml` IPC bridge depending on the active setting.

### LLM Service (`services/llmService.ts`)

Expand Down
9 changes: 7 additions & 2 deletions components/InfoView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import PreviewPane from './PreviewPane';
import Spinner from './Spinner';
import { useLogger } from '../hooks/useLogger';
import type { Settings } from '../types';

type DocTab = 'Readme' | 'Functional Manual' | 'Technical Manual' | 'Version Log';

Expand All @@ -12,7 +13,11 @@ const docFiles: Record<DocTab, string> = {
'Version Log': 'VERSION_LOG.md',
};

const InfoView: React.FC = () => {
interface InfoViewProps {
settings: Settings;
}

const InfoView: React.FC<InfoViewProps> = ({ settings }) => {
const [activeTab, setActiveTab] = useState<DocTab>('Readme');
const [documents, setDocuments] = useState<Record<DocTab, string>>({
'Readme': 'Loading...',
Expand Down Expand Up @@ -100,7 +105,7 @@ const InfoView: React.FC = () => {
<span>Loading documentation...</span>
</div>
) : (
<PreviewPane content={documents[activeTab]} language="markdown" addLog={addLog} />
<PreviewPane content={documents[activeTab]} language="markdown" addLog={addLog} settings={settings} />
)}
</div>
</div>
Expand Down
9 changes: 5 additions & 4 deletions components/PreviewPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ import React, { useState, useEffect } from 'react';
import { previewService } from '../services/previewService';
import Spinner from './Spinner';
import { useTheme } from '../hooks/useTheme';
import type { LogLevel } from '../types';
import type { LogLevel, Settings } from '../types';

interface PreviewPaneProps {
content: string;
language: string | null;
onScroll?: (event: React.UIEvent<HTMLDivElement>) => void;
addLog: (level: LogLevel, message: string) => void;
settings: Settings;
}

const PreviewPane = React.forwardRef<HTMLDivElement, PreviewPaneProps>(({ content, language, onScroll, addLog }, ref) => {
const PreviewPane = React.forwardRef<HTMLDivElement, PreviewPaneProps>(({ content, language, onScroll, addLog, settings }, ref) => {
const [renderedOutput, setRenderedOutput] = useState<React.ReactElement | null>(null);
const [error, setError] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(true);
Expand All @@ -28,7 +29,7 @@ const PreviewPane = React.forwardRef<HTMLDivElement, PreviewPaneProps>(({ conten

setError(null);
const renderer = previewService.getRendererForLanguage(language);
const result = await renderer.render(content, addLog, language);
const result = await renderer.render(content, addLog, language, settings);

clearTimeout(loadingTimer);
if (!isCancelled) {
Expand Down Expand Up @@ -57,7 +58,7 @@ const PreviewPane = React.forwardRef<HTMLDivElement, PreviewPaneProps>(({ conten
isCancelled = true;
clearTimeout(debounceTimer);
};
}, [content, language, addLog, ref, onScroll]);
}, [content, language, addLog, ref, onScroll, settings]);

return (
<div className="w-full h-full bg-secondary">
Expand Down
8 changes: 7 additions & 1 deletion components/PromptEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ interface DocumentEditorProps {
const PREVIEWABLE_LANGUAGES = new Set<string>([
'markdown',
'html',
'plantuml',
'puml',
'uml',
'pdf',
'application/pdf',
'image',
Expand Down Expand Up @@ -62,6 +65,9 @@ const resolveDefaultViewMode = (mode: ViewMode | null | undefined, languageHint:
if (normalizedHint === 'image' || normalizedHint.startsWith('image/')) {
return 'preview';
}
if (normalizedHint === 'plantuml' || normalizedHint === 'puml' || normalizedHint === 'uml') {
return 'preview';
}
return 'edit';
};

Expand Down Expand Up @@ -482,7 +488,7 @@ const DocumentEditor: React.FC<DocumentEditorProps> = ({ documentNode, onSave, o
fontSize={settings.editorFontSize}
/>
);
const preview = <PreviewPane ref={previewScrollRef} content={content} language={language} onScroll={handlePreviewScroll} addLog={addLog} />;
const preview = <PreviewPane ref={previewScrollRef} content={content} language={language} onScroll={handlePreviewScroll} addLog={addLog} settings={settings} />;

switch(viewMode) {
case 'edit': return editor;
Expand Down
29 changes: 28 additions & 1 deletion components/SettingsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1369,8 +1369,10 @@ requests"
};

const GeneralSettingsSection: React.FC<Pick<SectionProps, 'settings' | 'setCurrentSettings' | 'sectionRef'>> = ({ settings, setCurrentSettings, sectionRef }) => {
const isOfflineRendererAvailable = typeof window !== 'undefined' && !!window.electronAPI?.renderPlantUML;
const offlineRendererMessage = 'Offline rendering requires the desktop application with a local Java runtime.';
return (
<div id="general" ref={sectionRef} className="py-6">
<div id="general" ref={sectionRef} className="py-6">
<h2 className="text-lg font-semibold text-text-main mb-4">General</h2>
<div className="space-y-6">
<SettingRow htmlFor="allowPrerelease" label="Receive Pre-releases" description="Get notified about new beta versions and test features early.">
Expand All @@ -1379,6 +1381,31 @@ const GeneralSettingsSection: React.FC<Pick<SectionProps, 'settings' | 'setCurre
<SettingRow htmlFor="autoSaveLogs" label="Auto-save Logs" description="Automatically save all logs to a daily file on your computer for debugging.">
<ToggleSwitch id="autoSaveLogs" checked={settings.autoSaveLogs} onChange={(val) => setCurrentSettings(s => ({...s, autoSaveLogs: val}))} />
</SettingRow>
<SettingRow
htmlFor="plantumlRendererMode"
label="PlantUML Rendering"
description="Choose whether PlantUML diagrams are rendered via the public server or the local renderer."
>
<div className="flex flex-col items-end w-full md:items-end">
<select
id="plantumlRendererMode"
value={settings.plantumlRendererMode}
onChange={(event) => setCurrentSettings(prev => ({
...prev,
plantumlRendererMode: event.target.value as Settings['plantumlRendererMode'],
}))}
className="w-full md:w-64 px-3 py-2 text-sm rounded-md border border-border-color bg-background text-text-main focus:outline-none focus:ring-2 focus:ring-primary/50"
>
<option value="remote">Remote (plantuml.com)</option>
<option value="offline">Offline (local renderer)</option>
</select>
{!isOfflineRendererAvailable && (
<p className={`mt-2 text-xs ${settings.plantumlRendererMode === 'offline' ? 'text-destructive-text' : 'text-text-secondary'} text-right md:text-left md:w-full`}>
{offlineRendererMessage}
</p>
)}
</div>
</SettingRow>
</div>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const DEFAULT_SETTINGS: Settings = {
iconSet: 'heroicons',
autoSaveLogs: false,
allowPrerelease: false,
plantumlRendererMode: 'remote',
uiScale: 100,
documentTreeIndent: 16,
documentTreeVerticalSpacing: 4,
Expand Down
13 changes: 12 additions & 1 deletion docs/FUNCTIONAL_MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,25 @@ Accessed via the gear icon in the title bar. The settings are organized into cat
- **LLM Provider:** Configure your connection to a local AI service. You can detect running services and select a model.
- **Appearance:** Change the UI scale and choose from different icon sets.
- **Keyboard Shortcuts:** View and customize keyboard shortcuts for all major application actions. You can record a new key combination for any command.
- **General:** Configure application behavior, like auto-saving logs and opting into pre-release updates.
- **General:** Configure application behavior, like auto-saving logs, opting into pre-release updates, and choosing how PlantUML diagrams are rendered.
- **Database:** View detailed statistics about your local database file, and perform maintenance tasks such as creating a compressed backup, checking file integrity, and optimizing the database size (`VACUUM`).
- **Advanced:** View and edit the raw JSON configuration file using an interactive tree or a raw text editor, and import/export your settings.

### Info View

Accessed via the info icon in the title bar. This view contains tabs for reading the application's `README.md`, this `FUNCTIONAL_MANUAL.md`, the `TECHNICAL_MANUAL.md`, and the `VERSION_LOG.md`.

#### PlantUML Rendering Modes

The **General** settings category includes a **PlantUML Rendering** selector. Choose between:

- **Remote (plantuml.com):** Encodes the diagram and requests the SVG from the public PlantUML server.
- **Offline (local renderer):** Invokes the bundled PlantUML engine inside the desktop application. This mode requires a local Java Runtime Environment and access to Graphviz (or the bundled `viz.js` assets) so the renderer can generate diagrams without contacting plantuml.com.

If the Java runtime is unavailable, DocForge will report the error in the preview and you can switch back to remote rendering at any time.

The chosen rendering mode is used for PlantUML code blocks inside Markdown documents *and* for standalone `.puml` documents rendered through the dedicated PlantUML previewer.

### Logger Panel

Accessed via the terminal icon in the title bar, this panel is your primary tool for debugging and monitoring application activity.
Expand Down
4 changes: 3 additions & 1 deletion docs/TECHNICAL_MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This document provides a technical overview of the DocForge application's archit
- **Bundler:** [esbuild](https://esbuild.github.io/) for fast and efficient bundling of the application's source code.
- **Styling:** [Tailwind CSS](https://tailwindcss.com/) for a utility-first CSS framework.
- **Packaging:** [electron-builder](https://www.electron.build/) for creating distributable application packages.
- **Diagram Rendering:** [PlantUML](https://plantuml.com/) via either the public plantuml.com service or the bundled [`node-plantuml`](https://www.npmjs.com/package/node-plantuml) renderer. Offline rendering requires a locally installed Java Runtime Environment and access to Graphviz (or the cached `viz.js` binary) so that diagrams can be rendered without network access.

---

Expand Down Expand Up @@ -93,7 +94,8 @@ This system provides a consistent and extensible editing experience for all docu
- **`CodeEditor.tsx`:** A React component that wraps and configures the Monaco Editor instance. It's responsible for managing the editor's content, theme, and language for syntax highlighting based on props.
- **`PreviewPane.tsx`:** This component is responsible for displaying the rendered output of a document. It debounces content updates for performance and uses the `PreviewService` to get the correct output.
- **`services/previewService.ts`:** This service acts as a registry for all available renderer "plugins." It exposes a method, `getRendererForLanguage()`, which finds and returns the appropriate renderer for a given language ID (e.g., 'markdown').
- **Renderer Plugins (`services/preview/`):** Each file format with a preview is supported by a dedicated renderer class that implements the `IRenderer` interface. This makes the system highly extensible: to support a new format, one only needs to create a new renderer class and add it to the `previewService` registry. Currently, renderers for Markdown, HTML, and plaintext (fallback) are implemented.
- **Renderer Plugins (`services/preview/`):** Each file format with a preview is supported by a dedicated renderer class that implements the `IRenderer` interface. This makes the system highly extensible: to support a new format, one only needs to create a new renderer class and add it to the `previewService` registry. The bundled plugins cover Markdown (with Mermaid + PlantUML support), standalone PlantUML documents, HTML, PDFs, common image formats, and a plaintext fallback renderer.
- Both the Markdown renderer and the standalone PlantUML renderer share the `PlantUMLDiagram` component, which routes diagrams through either the remote plantuml.com server or the offline `node-plantuml` IPC bridge depending on the active setting.

### LLM Service (`services/llmService.ts`)

Expand Down
Loading