# Payas Editor — Documentation

> Privacy-first rich-text editor that saves as Markdown · No server · Open Source  
> Developer: **Saman Wijesinghe** · License: MIT

---

## Table of Contents

1. [Project Overview](#1-project-overview)
2. [Quick Start](#2-quick-start)
3. [Interface Layout](#3-interface-layout)
4. [Toolbar Reference](#4-toolbar-reference)
5. [Text Formatting](#5-text-formatting)
6. [Document Management](#6-document-management)
7. [View Modes](#7-view-modes)
8. [Find & Replace](#8-find--replace)
9. [Keyboard Shortcuts](#9-keyboard-shortcuts)
10. [Settings Reference](#10-settings-reference)
11. [File Operations](#11-file-operations)
12. [Storage & Data](#12-storage--data)
13. [Architecture & Code Structure](#13-architecture--code-structure)
14. [JavaScript API Reference](#14-javascript-api-reference)
15. [Data Structures](#15-data-structures)
16. [Markdown Conversion](#16-markdown-conversion)
17. [License](#17-license)

---

## 1. Project Overview

**Payas Editor** is a fully client-side rich-text (WYSIWYG) editor that runs entirely in your browser — no server, no account, no build step required. Open `payas-editor.html` directly and start writing. Content is auto-saved to `localStorage` and exported as Markdown (`.md`).

### Key Facts

| Property | Value |
|---|---|
| Entry point | `payas-editor.html` |
| Stack | HTML5 · CSS3 · Vanilla JS (ES2022) |
| Dependencies | Bootstrap 5.3.3 · Bootstrap Icons 1.11.3 · Google Fonts |
| Storage | `localStorage` (auto-save every 30 s) · File download |
| Import formats | `.md`, `.txt` |
| Export formats | Markdown · Plain Text · HTML |
| Themes | Light and Dark |
| Multi-tab | Yes (unlimited documents) |

### Design Language

Payas Editor follows the **Payas design system** shared across all Payas web tools (Days, Reader, Player, Imager, FM, Omi). It uses the same colour tokens, typography, and component patterns.

---

## 2. Quick Start

No build or server needed. Open the file directly:

```bash
# Option 1 — open directly
xdg-open payas-editor.html          # Linux
open payas-editor.html              # macOS
start payas-editor.html             # Windows

# Option 2 — serve locally (avoids file:// quirks on some browsers)
python3 -m http.server 8080
# Then visit http://localhost:8080/payas-editor.html
```

A **welcome document** opens automatically on first launch, demonstrating the key features.

---

## 3. Interface Layout

```
┌─ Title Bar — Row 1 (brand + navigation) ─────────────────────┐
│ [☰] [Logo]                [Settings] [About] [☀/☽] [License] │
├─ Title Bar — Row 2 (file actions) ───────────────────────────┤
│ [New] [Open] [Save] [Save All] [Export]                       │
├─ Tab Bar ────────────────────────────────────────────────────┤
│ [+] [Tab 1 ●] [Tab 2]  …                                     │
├─ Toolbar ────────────────────────────────────────────────────┤
│ [Style▼] [Font▼] [Size] | [B][I][U][S][⌫] | [🎨][🖊] | …  │
├─ Find Bar (hidden by default) ───────────────────────────────┤
│ [Search…] [Replace…]  [n found]  [Replace] [All]  [✕]        │
├─ Body ───────────────────────────────────────────────────────┤
│  Sidebar  │  Rich Editor  │  Markdown Preview (split mode)   │
├─ Status Bar ─────────────────────────────────────────────────┤
│ Rich Text → Markdown  · 0 words · 0 chars · 0 lines · 1 tab  │
└──────────────────────────────────────────────────────────────┘
```

### Title Bar — Row 1 (Settings / About / Theme / License)

| Element | Action |
|---|---|
| ☰ Sidebar toggle | Show / hide the document sidebar |
| Logo | Brand — Payas editor |
| Settings | Open the settings panel |
| About | Version and project info |
| ☀ / ☽ toggle | Switch between dark and light theme instantly |
| License | MIT license text |
| Unsaved dot · filename | Unsaved-changes indicator and current document name |

### Title Bar — Row 2 (File Actions)

| Button | Shortcut | Action |
|---|---|---|
| New | `Ctrl+T` | Create a new empty tab |
| Open | — | Open one or more `.md` / `.txt` files |
| Save | `Ctrl+S` | Download current tab as `.md` |
| Save All | `Ctrl+Shift+S` | Download all unsaved tabs as `.md` |
| Export | — | Choose export format (Markdown / Plain Text / HTML) |

### Title Bar — Responsive Behaviour

The two-row title bar adapts cleanly across all screen sizes:

| Breakpoint | Behaviour |
|---|---|
| **≥ 769 px** (desktop / tablet) | Both rows show icon + text labels |
| **≤ 768 px** (tablet / mobile) | Both rows show **icons only** — text labels are hidden, all buttons remain visible |
| **≤ 480 px** (small phone) | Same as above with tighter padding and a shorter filename badge |

### Status Bar

Displays real-time stats: word count, character count, line count, open tab count, and selected character count.

---

## 4. Toolbar Reference

The toolbar is organised into logical groups separated by vertical dividers.

### Group 1 — Block & Font

| Control | Description |
|---|---|
| Style dropdown | Apply block-level format: Paragraph, Heading 1–4, Code Block |
| Font dropdown | Switch font face for selected text or cursor |
| Size input | Set font size in px (8–72). Press Enter or blur to apply |

### Group 2 — Inline Styling

| Button | Shortcut | Description |
|---|---|---|
| **B** Bold | `Ctrl+B` | Toggle bold |
| *I* Italic | `Ctrl+I` | Toggle italic |
| U Underline | `Ctrl+U` | Toggle underline |
| ~~S~~ Strikethrough | — | Toggle strikethrough |
| Eraser | — | **Remove all formatting** from selected text |

### Group 3 — Colour

| Control | Description |
|---|---|
| Palette icon | Text colour picker |
| Highlighter icon | Background (highlight) colour picker |

### Group 4 — Alignment

| Button | Description |
|---|---|
| Left | Align text left |
| Center | Centre text |
| Right | Align text right |
| Justify | Justify text |

### Group 5 — Lists

| Button | Description |
|---|---|
| Bullet list | Insert unordered list |
| Numbered list | Insert ordered list |
| Outdent | Decrease indent level |
| Indent | Increase indent level |

### Group 6 — Insert

| Button | Description |
|---|---|
| Link | Insert a hyperlink (prompts for URL and text) |
| Image | Insert an image (prompts for URL and alt text) |
| HR | Insert a horizontal rule |
| Table | Insert a 3×2 table |
| Blockquote | Wrap selection in a blockquote |
| Task | Insert a checkbox task item |
| **A** Drop Cap | Toggle drop cap on the current paragraph |

### Group 7 — Utilities

| Button | Shortcut | Description |
|---|---|---|
| Undo | `Ctrl+Z` | Undo last action |
| Redo | `Ctrl+Y` | Redo last undone action |
| Search | `Ctrl+F` | Open Find & Replace bar |
| Trash | — | Clear all content in current tab |

### Group 8 — View Modes

| Button | Description |
|---|---|
| Write | Editor only (default) |
| Split | Editor + Markdown preview side by side |
| MD | Markdown preview only |

---

## 5. Text Formatting

### Remove Formatting

Select any text and click the **Eraser** button (toolbar → inline styling group) to strip all inline formatting — bold, italic, underline, colour, font size, and highlight — returning the text to plain paragraph style.

- Works on the selected range only.
- If nothing is selected, no action is taken.

### Drop Cap

Place your cursor inside any paragraph and click the **A** button (toolbar → insert group) to toggle a **drop cap** on that paragraph's first letter.

- The first letter enlarges to ~3.8× the body size and floats left, creating a classic editorial look.
- The button highlights (green tint) when the cursor is in a drop-cap paragraph.
- Click again to remove the drop cap from that paragraph.
- Drop caps are stored in the document HTML and preserved across auto-save sessions.
- When exported to Markdown, drop-cap paragraphs are written as standard paragraphs (Markdown has no drop cap syntax).

---

## 6. Document Management

### Tabs

Each open document is represented by a tab. Tabs persist across browser sessions via `localStorage`.

| Action | How |
|---|---|
| New tab | Click `+` in tab bar, or `Ctrl+T`, or **New** in title bar |
| Switch tab | Click the tab, or `Ctrl+Tab` / `Ctrl+Shift+Tab` |
| Close tab | Click `✕` on the tab, or `Ctrl+W` |
| Rename tab | Double-click the tab label |
| Unsaved indicator | Orange dot on tab and title bar |

### Sidebar

Click the **sidebar toggle** (☰ icon) or press `Ctrl+\` to show/hide the document list. The sidebar shows all open tabs with word count and relative timestamp. Use the search box to filter by name.

---

## 7. View Modes

| Mode | Description |
|---|---|
| **Write** | Full-width editor |
| **Split** | Editor on the left, Markdown preview on the right |
| **MD** | Markdown preview fills the entire work area |

The Markdown preview shows the exact `.md` output that would be saved to disk. Enable **Live Markdown Sync** in settings for real-time updates while typing.

---

## 8. Find & Replace

Open with `Ctrl+F` or the search button in the toolbar.

| Control | Description |
|---|---|
| Find input | Type to search; shows match count |
| Replace input | Text to replace the match with |
| Replace | Replace the next occurrence |
| All | Replace all occurrences |
| ✕ | Close the find bar (`Escape` also works) |

---

## 9. Keyboard Shortcuts

| Shortcut | Action |
|---|---|
| `Ctrl+S` | Save current tab |
| `Ctrl+Shift+S` | Save all tabs |
| `Ctrl+T` | New tab |
| `Ctrl+W` | Close current tab |
| `Ctrl+Tab` | Switch to next tab |
| `Ctrl+Shift+Tab` | Switch to previous tab |
| `Ctrl+\` | Toggle sidebar |
| `Ctrl+F` | Open Find & Replace |
| `Ctrl+B` | Bold |
| `Ctrl+I` | Italic |
| `Ctrl+U` | Underline |
| `Ctrl+Z` | Undo |
| `Ctrl+Y` | Redo |
| `Escape` | Close modal / close find bar |

---

## 10. Settings Reference

Open via **Settings** in the title bar.

### Appearance

| Setting | Options | Default |
|---|---|---|
| Theme | Light / Dark | Light |
| Editor Font Size | 11–24 px (slider) | 15 px |
| Line Height | 1.3–2.4 (slider) | 1.8 |
| Editor Width | 100% / 820 px / 680 px | 100% |
| Sidebar Width | 200 / 240 / 280 / 320 px | 240 px |

### Behaviour

| Setting | Description | Default |
|---|---|---|
| Spell Check | Browser spell-check underlines | On |
| Auto-save | Save to `localStorage` every 30 seconds | On |
| Focus Mode | Hide toolbar while typing | Off |
| Live Markdown Sync | Update MD preview in real time | Off |
| Confirm on Close | Warn before closing unsaved tabs | On |

---

## 11. File Operations

### Opening Files

Click **Open** in the title bar. Accepts `.md` and `.txt` files (multiple selection supported). Each file opens in its own tab.

- Markdown files are converted to rich HTML using the built-in `markdownToHtml()` converter.
- Plain text files are inserted as-is.

### Saving

| Action | Result |
|---|---|
| **Save** (`Ctrl+S`) | Downloads current tab as `<name>.md` |
| **Save All** | Downloads all tabs with unsaved changes |
| **Export** | Opens dialog to choose MD / TXT / HTML format |

### Auto-save

When enabled, all tabs are serialised to `localStorage` every 30 seconds. Content is restored automatically on next page load.

---

## 12. Storage & Data

### localStorage Keys

| Key | Contents |
|---|---|
| `payas_tabs` | JSON array of all tab objects |
| `payas_active_id` | ID of the currently active tab |
| `payas_theme` | `"light"` or `"dark"` |
| `payas_sidebar` | Sidebar open/collapsed state |
| `payas_sbwidth` | Sidebar width preference |

### Tab Object

```json
{
  "id":        1,
  "name":      "my-doc.md",
  "content":   "<p>Hello <strong>world</strong></p>",
  "dirty":     false,
  "createdAt": "2025-01-01T00:00:00.000Z",
  "wordCount": 2
}
```

> Content is stored as inner HTML from the `contenteditable` editor. Drop cap classes and other inline styles are preserved.

---

## 13. Architecture & Code Structure

The editor is a **single HTML file** — no bundler, no framework, no server.

```
payas-editor.html
├── <style>          CSS custom properties, layout, toolbar, editor typography
├── <body>
│   ├── Title Bar    File actions, theme toggle
│   ├── Tab Bar      Multi-tab document navigation
│   ├── Toolbar      Formatting controls
│   ├── Find Bar     Search and replace UI
│   ├── Body Row
│   │   ├── Sidebar  Document list with search
│   │   ├── Editor   #rich-editor (contenteditable)
│   │   └── Preview  Markdown output pane
│   └── Status Bar   Live stats
└── <script>         All application logic (vanilla JS)
    ├── Tab management      createTab, switchTab, renderTabBar …
    ├── Formatting          execCmd, applyBlockFormat, applyFontSize …
    ├── New in v1.1         removeFormatting, toggleDropCap
    ├── Insert helpers      insertLink, insertImage, insertTable …
    ├── Find & Replace      openFindBar, runFind, doReplace …
    ├── File I/O            triggerOpen, loadFiles, saveTab, showExport …
    ├── Storage             scheduleAutoSave, doAutoSave …
    ├── View modes          setView, updateMdPreview …
    ├── Settings            applyEditorFont, applyFocusMode, saveSettings …
    └── Markdown            htmlToMarkdown, markdownToHtml
```

---

## 14. JavaScript API Reference

All functions are in global scope within the single HTML file.

### Formatting Functions

```js
execCmd(cmd, val?)
```
Thin wrapper around `document.execCommand()`. Focuses the editor, executes the command, then calls `onEdit()` and `syncToolbar()`.

```js
applyBlockFormat(tag)
```
Applies a block-level format (`p`, `h1`–`h4`, `pre`, `blockquote`) using `formatBlock` execCommand.

```js
applyFontSize(px)
```
Sets font size for the selected text (wraps in `<span style="font-size: Xpx">`) or for the whole editor if nothing is selected.

```js
removeFormatting()
```
Strips all inline formatting from the current selection: bold, italic, underline, colour, highlight, custom font size. Calls `document.execCommand('removeFormat')` then unwraps any remaining `<span style>` and `<font>` elements within the selection.

```js
toggleDropCap()
```
Toggles the `drop-cap` CSS class on the paragraph currently under the cursor. The first letter of that paragraph receives large, floating, coloured drop-cap styling. Updates the toolbar button's active state.

```js
syncToolbar()
```
Reads the current cursor context and updates toolbar button states (bold, italic, block format dropdown, drop-cap button).

### Insert Functions

```js
insertLink()      // Prompts for URL and link text
insertImage()     // Prompts for URL and alt text
insertHR()        // Inserts <hr/>
insertBlockquote()// Wraps selection in <blockquote>
insertTaskItem()  // Inserts a checkbox task paragraph
insertTable()     // Inserts a 3-column, 2-row table
```

### Find & Replace

```js
openFindBar()     // Show the find bar and focus the search input
closeFindBar()    // Hide the find bar and return focus to editor
runFind()         // Count matches for current query
doReplace()       // Replace next occurrence
doReplaceAll()    // Replace all occurrences
```

### Tab Management

```js
newTab()                       // Create a new empty tab
closeTab(id)                   // Close tab by ID (with dirty check)
switchTab(id)                  // Activate a tab
renderTabBar()                 // Re-render the tab bar DOM
renderSidebar()                // Re-render the sidebar document list
openRenameModal(id)            // Open the rename dialog for a tab
```

### File I/O

```js
triggerOpen()                  // Open the OS file picker
loadFiles(event)               // Handle files from the picker
saveCurrentTab()               // Download the active tab as .md
saveAllTabs()                  // Download all dirty tabs as .md
showExport()                   // Open the export format dialog
```

### Storage

```js
scheduleAutoSave()             // Start the 30-second auto-save timer
doAutoSave()                   // Serialise all tabs to localStorage
```

### View

```js
setView(mode)                  // 'write' | 'split' | 'preview'
updateMdPreview()              // Convert editor HTML to MD and display
```

### Markdown

```js
htmlToMarkdown(html)           // Convert HTML string to Markdown string
markdownToHtml(md)             // Convert Markdown string to HTML string
```

---

## 15. Data Structures

### Tab Object (in-memory)

```js
{
  id:        Number,   // Unique auto-incrementing ID
  name:      String,   // File name shown in tab, e.g. "my-doc.md"
  content:   String,   // innerHTML of the contenteditable editor
  dirty:     Boolean,  // true if there are unsaved changes
  createdAt: Date,     // Creation timestamp
  wordCount: Number    // Cached word count
}
```

### Settings Object (in localStorage)

```js
{
  theme:       'light' | 'dark',
  fontSize:    Number,    // px, 11–24
  lineHeight:  Number,    // 1.3–2.4
  editorWidth: String,    // '100%' | '820px' | '680px'
  sidebarWidth:String,    // '200px' | '240px' | '280px' | '320px'
  spellCheck:  Boolean,
  autoSave:    Boolean,
  focusMode:   Boolean,
  liveSync:    Boolean,
  confirmClose:Boolean
}
```

---

## 16. Markdown Conversion

The editor uses a custom bidirectional converter (no external library).

### HTML → Markdown (`htmlToMarkdown`)

| HTML element | Markdown output |
|---|---|
| `<h1>`–`<h6>` | `#` through `######` |
| `<p>` (`.drop-cap`) | Plain paragraph (drop cap class is not preserved in MD) |
| `<strong>`, `<b>` | `**text**` |
| `<em>`, `<i>` | `*text*` |
| `<u>` | `<u>text</u>` (no standard MD syntax) |
| `<s>`, `<del>` | `~~text~~` |
| `<code>` | `` `text` `` |
| `<pre>` | ```` ```code``` ```` |
| `<blockquote>` | `> text` |
| `<a>` | `[text](url)` |
| `<img>` | `![alt](src)` |
| `<ul>` / `<ol>` | `- item` / `1. item` |
| `<input type="checkbox">` | `- [ ] item` / `- [x] item` |
| `<table>` | Pipe table format |
| `<hr>` | `---` |
| `<br>` | Newline |

### Markdown → HTML (`markdownToHtml`)

Supports all standard Markdown inline and block elements. Used when opening `.md` files to convert them to editable rich HTML.

---

## 17. License

MIT License

Copyright © Saman Wijesinghe

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
