1 Commits

Author SHA1 Message Date
schihei c798b8b39e Add fullwidth and circled Unicode formatting commands 2026-05-05 16:05:10 +02:00
4 changed files with 36 additions and 6 deletions
+8 -2
View File
@@ -1,12 +1,14 @@
# Unicode Text Formatter # Unicode Text Formatter
An [Obsidian](https://obsidian.md) plugin that transforms selected text into Unicode Mathematical Alphanumeric Symbols — Sans-Serif Bold, Italic, and Bold-Italic — for use in LinkedIn and Facebook posts. An [Obsidian](https://obsidian.md) plugin that transforms selected text into Unicode Mathematical Alphanumeric Symbols — Sans-Serif Bold, Italic, and Bold-Italic — plus Circled and Fullwidth characters — for use in social media posts.
## Features ## Features
- **Unicode Bold** — converts letters and digits to sans-serif bold (𝗔𝗕𝗖 / 𝗮𝗯𝗰 / 𝟬𝟭𝟮) - **Unicode Bold** — converts letters and digits to sans-serif bold (𝗔𝗕𝗖 / 𝗮𝗯𝗰 / 𝟬𝟭𝟮)
- **Unicode Italic** — converts letters to sans-serif italic (𝘈𝘉𝘊 / 𝘢𝘣𝘤) - **Unicode Italic** — converts letters to sans-serif italic (𝘈𝘉𝘊 / 𝘢𝘣𝘤)
- **Unicode Bold Italic** — converts letters to sans-serif bold italic (𝘼𝘽𝘾 / 𝙖𝙗𝙘) - **Unicode Bold Italic** — converts letters to sans-serif bold italic (𝘼𝘽𝘾 / 𝙖𝙗𝙘)
- **Unicode Fullwidth** — converts letters and digits to fullwidth forms (ABC / abc / 012)
- **Unicode Circled** — converts letters and digits to circled forms (ⒶⒷⒸ / ⓐⓑⓒ / ①②③)
- **Remove Unicode Formatting** — converts any formatted Unicode characters back to plain ASCII - **Remove Unicode Formatting** — converts any formatted Unicode characters back to plain ASCII
- **Convert List Bullets to Arrow** — prefixes every selected line with `→ `, stripping any leading `* ` marker first - **Convert List Bullets to Arrow** — prefixes every selected line with `→ `, stripping any leading `* ` marker first
- **Convert List Bullets to Em Dash** — prefixes every selected line with `— `, stripping any leading `* ` marker first - **Convert List Bullets to Em Dash** — prefixes every selected line with `— `, stripping any leading `* ` marker first
@@ -23,6 +25,8 @@ An [Obsidian](https://obsidian.md) plugin that transforms selected text into Uni
- **Format as Unicode Bold** - **Format as Unicode Bold**
- **Format as Unicode Italic** - **Format as Unicode Italic**
- **Format as Unicode Bold Italic** - **Format as Unicode Bold Italic**
- **Format as Fullwidth**
- **Format as Circled Letters/Numbers**
- **Remove Unicode Formatting** — reverses any of the above back to plain ASCII - **Remove Unicode Formatting** — reverses any of the above back to plain ASCII
- **Convert List Bullets to Arrow** — prefixes every line with `→ ` (strips `* ` if present) - **Convert List Bullets to Arrow** — prefixes every line with `→ ` (strips `* ` if present)
- **Convert List Bullets to Em Dash** — prefixes every line with `— ` (strips `* ` if present) - **Convert List Bullets to Em Dash** — prefixes every line with `— ` (strips `* ` if present)
@@ -60,7 +64,7 @@ npm run lint # ESLint check
|------|---------| |------|---------|
| `src/unicode-maps.ts` | Builds character lookup maps from Unicode code point ranges | | `src/unicode-maps.ts` | Builds character lookup maps from Unicode code point ranges |
| `src/formatter.ts` | `transformText`, `cleanText`, `bulletToEmdash`, `bulletToArrow`, `numberedListSlash`, `numberedListParens`, `markdownToLinkedIn` — text transformation functions | | `src/formatter.ts` | `transformText`, `cleanText`, `bulletToEmdash`, `bulletToArrow`, `numberedListSlash`, `numberedListParens`, `markdownToLinkedIn` — text transformation functions |
| `src/commands.ts` | Registers the nine editor commands with the Obsidian plugin API | | `src/commands.ts` | Registers the eleven editor commands with the Obsidian plugin API |
| `src/main.ts` | Plugin entry point — calls `registerCommands` on load | | `src/main.ts` | Plugin entry point — calls `registerCommands` on load |
### Unicode blocks used ### Unicode blocks used
@@ -70,6 +74,8 @@ npm run lint # ESLint check
| Sans-Serif Bold | U+1D5D4U+1D5ED | U+1D5EEU+1D607 | U+1D7ECU+1D7F5 | | Sans-Serif Bold | U+1D5D4U+1D5ED | U+1D5EEU+1D607 | U+1D7ECU+1D7F5 |
| Sans-Serif Italic | U+1D608U+1D621 | U+1D622U+1D63B | — | | Sans-Serif Italic | U+1D608U+1D621 | U+1D622U+1D63B | — |
| Sans-Serif Bold-Italic | U+1D63CU+1D655 | U+1D656U+1D66F | — | | Sans-Serif Bold-Italic | U+1D63CU+1D655 | U+1D656U+1D66F | — |
| Fullwidth | U+FF21U+FF3A | U+FF41U+FF5A | U+FF10U+FF19 |
| Circled | U+24B6U+24CF | U+24D0U+24E9 | U+2460U+2468, U+24EA |
## Releasing ## Releasing
+2
View File
@@ -20,6 +20,8 @@ export function registerCommands(plugin: UnicodeFormatterPlugin): void {
addFormatCommand(plugin, "bold", "Format as unicode bold"); addFormatCommand(plugin, "bold", "Format as unicode bold");
addFormatCommand(plugin, "italic", "Format as unicode italic"); addFormatCommand(plugin, "italic", "Format as unicode italic");
addFormatCommand(plugin, "bold-italic", "Format as unicode bold italic"); addFormatCommand(plugin, "bold-italic", "Format as unicode bold italic");
addFormatCommand(plugin, "fullwidth", "Format as fullwidth");
addFormatCommand(plugin, "circled", "Format as circled letters/numbers");
plugin.addCommand({ plugin.addCommand({
id: "unicode-formatter:clean", id: "unicode-formatter:clean",
name: "Remove unicode formatting", name: "Remove unicode formatting",
+4 -2
View File
@@ -1,11 +1,13 @@
import { BOLD_MAP, ITALIC_MAP, BOLD_ITALIC_MAP, UNICODE_TO_ASCII_MAP, UNICODE_TO_STYLE } from "./unicode-maps"; import { BOLD_MAP, ITALIC_MAP, BOLD_ITALIC_MAP, FULLWIDTH_MAP, CIRCLED_MAP, UNICODE_TO_ASCII_MAP, UNICODE_TO_STYLE } from "./unicode-maps";
export type FormatStyle = "bold" | "italic" | "bold-italic"; export type FormatStyle = "bold" | "italic" | "bold-italic" | "fullwidth" | "circled";
const STYLE_MAPS: Record<FormatStyle, Record<string, string>> = { const STYLE_MAPS: Record<FormatStyle, Record<string, string>> = {
"bold": BOLD_MAP, "bold": BOLD_MAP,
"italic": ITALIC_MAP, "italic": ITALIC_MAP,
"bold-italic": BOLD_ITALIC_MAP, "bold-italic": BOLD_ITALIC_MAP,
"fullwidth": FULLWIDTH_MAP,
"circled": CIRCLED_MAP,
}; };
export function transformText(text: string, style: FormatStyle): string { export function transformText(text: string, style: FormatStyle): string {
+22 -2
View File
@@ -25,18 +25,38 @@ export const ITALIC_MAP: Record<string, string> = buildMap(0x1D608, 0x1D622);
// Sans-Serif Bold-Italic: U+1D63CU+1D655 (upper), U+1D656U+1D66F (lower) // Sans-Serif Bold-Italic: U+1D63CU+1D655 (upper), U+1D656U+1D66F (lower)
export const BOLD_ITALIC_MAP: Record<string, string> = buildMap(0x1D63C, 0x1D656); export const BOLD_ITALIC_MAP: Record<string, string> = buildMap(0x1D63C, 0x1D656);
// Fullwidth: U+FF21U+FF3A (upper), U+FF41U+FF5A (lower), U+FF10U+FF19 (digits)
export const FULLWIDTH_MAP: Record<string, string> = buildMap(0xFF21, 0xFF41, 0xFF10);
// Circled: U+24B6U+24CF (upper), U+24D0U+24E9 (lower), digits 1-9: U+2460U+2468, 0: U+24EA
function buildCircledMap(): Record<string, string> {
const map: Record<string, string> = {};
for (let i = 0; i < 26; i++) {
map[String.fromCharCode(65 + i)] = String.fromCodePoint(0x24B6 + i);
map[String.fromCharCode(97 + i)] = String.fromCodePoint(0x24D0 + i);
}
map["0"] = String.fromCodePoint(0x24EA);
for (let i = 0; i < 9; i++) {
map[String.fromCharCode(49 + i)] = String.fromCodePoint(0x2460 + i);
}
return map;
}
export const CIRCLED_MAP: Record<string, string> = buildCircledMap();
// Reverse map: Unicode symbol → ASCII character // Reverse map: Unicode symbol → ASCII character
export const UNICODE_TO_ASCII_MAP: Map<string, string> = new Map( export const UNICODE_TO_ASCII_MAP: Map<string, string> = new Map(
[BOLD_MAP, ITALIC_MAP, BOLD_ITALIC_MAP].flatMap(m => [BOLD_MAP, ITALIC_MAP, BOLD_ITALIC_MAP, FULLWIDTH_MAP, CIRCLED_MAP].flatMap(m =>
Object.entries(m).map(([ascii, unicode]) => [unicode, ascii] as [string, string]) Object.entries(m).map(([ascii, unicode]) => [unicode, ascii] as [string, string])
) )
); );
export type FontStyle = "bold" | "italic" | "bold-italic"; export type FontStyle = "bold" | "italic" | "bold-italic" | "fullwidth" | "circled";
// Reverse map: Unicode symbol → font style // Reverse map: Unicode symbol → font style
export const UNICODE_TO_STYLE: Map<string, FontStyle> = new Map([ export const UNICODE_TO_STYLE: Map<string, FontStyle> = new Map([
...Object.values(BOLD_MAP).map(ch => [ch, "bold"] as [string, FontStyle]), ...Object.values(BOLD_MAP).map(ch => [ch, "bold"] as [string, FontStyle]),
...Object.values(ITALIC_MAP).map(ch => [ch, "italic"] as [string, FontStyle]), ...Object.values(ITALIC_MAP).map(ch => [ch, "italic"] as [string, FontStyle]),
...Object.values(BOLD_ITALIC_MAP).map(ch => [ch, "bold-italic"] as [string, FontStyle]), ...Object.values(BOLD_ITALIC_MAP).map(ch => [ch, "bold-italic"] as [string, FontStyle]),
...Object.values(FULLWIDTH_MAP).map(ch => [ch, "fullwidth"] as [string, FontStyle]),
...Object.values(CIRCLED_MAP).map(ch => [ch, "circled"] as [string, FontStyle]),
]); ]);