diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3a44ec6..69df8bd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -30,6 +30,7 @@
- Line spacing and paragraph spacing (space before / after)
- Increase / decrease indent (paragraphs and lists)
- Bulleted and ordered lists — nested, with multiple numbering styles (decimal, alpha, roman; `.` or `)` suffix) and whole-list indent; Tab / Shift-Tab to nest / un-nest
+- Customizable bullet symbols per list level (Word-style picker on the bullet-list split button: • ◦ ▪ ❖ ➢ ⇨ ✓ – >); round-trips to ODF `text:bullet-char` and DOCX `w:lvlText`, and the DOCX/ODT import maps Wingdings/Symbol bullets (arrows, diamonds, checkmarks …) to their Unicode equivalents instead of flattening them to plain dots. Symbols Liberation Serif lacks render from a bundled 2 KB DejaVu Sans subset (`EdenSymbols.woff2`), so markers look compact and identical on every platform instead of a stretched OS fallback
- Tab stops (real tab character) and manual line breaks (Shift+Enter)
**Insert**
diff --git a/src/App.svelte b/src/App.svelte
index 0bec8ee..2cb2c86 100644
--- a/src/App.svelte
+++ b/src/App.svelte
@@ -627,11 +627,11 @@
Save / Export
{/if}
diff --git a/src/assets/fonts/EdenSymbols.woff2 b/src/assets/fonts/EdenSymbols.woff2
new file mode 100644
index 0000000..f37f9d3
Binary files /dev/null and b/src/assets/fonts/EdenSymbols.woff2 differ
diff --git a/src/assets/fonts/LICENSE-DejaVu.txt b/src/assets/fonts/LICENSE-DejaVu.txt
new file mode 100644
index 0000000..b3d93a1
--- /dev/null
+++ b/src/assets/fonts/LICENSE-DejaVu.txt
@@ -0,0 +1,78 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: DejaVu fonts
+Upstream-Author: Stepan Roh (original author),
+ see /usr/share/doc/fonts-dejavu-core/AUTHORS for full list
+Source: https://dejavu-fonts.github.io/
+
+Files: *
+Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.
+ Bitstream Vera is a trademark of Bitstream, Inc.
+ DejaVu changes are in public domain.
+License: bitstream-vera
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of the fonts accompanying this license ("Fonts") and associated
+ documentation files (the "Font Software"), to reproduce and distribute the
+ Font Software, including without limitation the rights to use, copy, merge,
+ publish, distribute, and/or sell copies of the Font Software, and to permit
+ persons to whom the Font Software is furnished to do so, subject to the
+ following conditions:
+ .
+ The above copyright and trademark notices and this permission notice shall
+ be included in all copies of one or more of the Font Software typefaces.
+ .
+ The Font Software may be modified, altered, or added to, and in particular
+ the designs of glyphs or characters in the Fonts may be modified and
+ additional glyphs or characters may be added to the Fonts, only if the fonts
+ are renamed to names not containing either the words "Bitstream" or the word
+ "Vera".
+ .
+ This License becomes null and void to the extent applicable to Fonts or Font
+ Software that has been modified and is distributed under the "Bitstream
+ Vera" names.
+ .
+ The Font Software may be sold as part of a larger software package but no
+ copy of one or more of the Font Software typefaces may be sold by itself.
+ .
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
+ TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
+ FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
+ ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
+ FONT SOFTWARE.
+ .
+ Except as contained in this notice, the names of Gnome, the Gnome
+ Foundation, and Bitstream Inc., shall not be used in advertising or
+ otherwise to promote the sale, use or other dealings in this Font Software
+ without prior written authorization from the Gnome Foundation or Bitstream
+ Inc., respectively. For further information, contact: fonts at gnome dot
+ org.
+
+Files: debian/*
+Copyright: (C) 2005-2006 Peter Cernak
+ (C) 2006-2011 Davide Viti
+ (C) 2011-2013 Christian Perrier
+ (C) 2013 Fabian Greffrath
+License: GPL-2+
+ This program is free software; you can redistribute it
+ and/or modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later
+ version.
+ .
+ This program is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more
+ details.
+ .
+ You should have received a copy of the GNU General Public
+ License along with this package; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301 USA
+ .
+ On Debian systems, the full text of the GNU General Public
+ License version 2 can be found in the file
+ /usr/share/common-licenses/GPL-2'.
diff --git a/src/lib/components/Toolbar.svelte b/src/lib/components/Toolbar.svelte
index 66ca714..1c172a8 100644
--- a/src/lib/components/Toolbar.svelte
+++ b/src/lib/components/Toolbar.svelte
@@ -3,6 +3,7 @@
import HistoryButton from './HistoryButton.svelte';
import AlignButton from './AlignButton.svelte';
import { ORDERED_LIST_TYPES, DEFAULT_ORDERED_TYPE, type OrderedListType } from '../utils/orderedListTypes';
+ import { BULLET_TYPES } from '../utils/bulletListTypes';
import { isInHeaderCell } from '../editor/extensions/tableHeaderRow';
let { editor, tick }: { editor: Editor | null; tick: number } = $props();
@@ -33,6 +34,30 @@
});
let olMenuOpen = $state(false);
+ let blMenuOpen = $state(false);
+
+ // Marker char of the innermost bullet list at the cursor (null = default cycle
+ // or not in a bullet list).
+ let currentBulletChar = $derived.by(() => {
+ if (tick < 0 || !editor || !editor.isActive('bulletList')) return null;
+ return (editor.getAttributes('bulletList').bulletChar ?? null) as string | null;
+ });
+
+ // Toggle a plain bullet list — the split button's main half.
+ function toggleBulletList() {
+ blMenuOpen = false;
+ editor?.chain().focus().toggleBulletList().run();
+ }
+
+ // Apply a marker char to the innermost list level (null = default); creates the
+ // list first if the selection isn't in one.
+ function applyBulletChar(char: string | null) {
+ if (!editor) return;
+ blMenuOpen = false;
+ const chain = editor.chain().focus();
+ if (!editor.isActive('bulletList')) chain.toggleBulletList();
+ chain.setBulletChar(char).run();
+ }
// Toggle a plain (decimal) ordered list — the split button's main half.
function toggleOrderedList() {
@@ -49,9 +74,9 @@
chain.updateAttributes('orderedList', { listStyleType: key }).run();
}
- function olMenuClickOutside(node: HTMLElement) {
+ function menuClickOutside(node: HTMLElement, close: () => void) {
function handler(e: MouseEvent) {
- if (!node.contains(e.target as Node)) olMenuOpen = false;
+ if (!node.contains(e.target as Node)) close();
}
window.addEventListener('mousedown', handler);
return { destroy() { window.removeEventListener('mousedown', handler); } };
@@ -132,21 +157,65 @@