Refine slash menu and Markdown tags

This commit is contained in:
rucki
2026-08-27 10:32:19 +02:00
parent 78290ee5dc
commit fd2a3de4ac
11 changed files with 142 additions and 41 deletions
+15 -10
View File
@@ -21,7 +21,8 @@ from django.views.decorators.http import require_http_methods, require_POST
from .forms import ApiKeyForm, EditItemForm, InviteRegistrationForm, KanbanForm, QuickItemForm, TeamForm, TeamInviteForm, UserInviteForm, UserPreferenceForm, UserSettingsForm
from .models import ApiKey, Attachment, Item, Kanban, Tag, Team, TeamInvite, TeamMembership, UserInvite, UserPreference
COMMAND_RE = re.compile(r'/(todo|note|link|journal|public|private)\b', re.I)
TYPE_COMMAND_RE = re.compile(r'^/(todo|note|link|journal)\b', re.I)
VISIBILITY_COMMAND_RE = re.compile(r'/(public|private)\b', re.I)
URL_RE = re.compile(r'https?://\S+')
ONLY_URL_RE = re.compile(r'^https?://\S+$')
TITLE_RE = re.compile(r'<title[^>]*>(.*?)</title>', re.I | re.S)
@@ -44,20 +45,24 @@ def fetch_page_title(url):
def parse_quick_content(raw, default_kind=Item.Kind.NOTE):
content = raw.strip()
commands = {c.lower() for c in COMMAND_RE.findall(content)}
content = COMMAND_RE.sub('', content).strip()
type_match = TYPE_COMMAND_RE.match(content)
type_command = type_match.group(1).lower() if type_match else None
visibility_commands = {command.lower() for command in VISIBILITY_COMMAND_RE.findall(content)}
if type_match:
content = content[type_match.end():].strip()
content = VISIBILITY_COMMAND_RE.sub('', content).strip()
only_url = bool(ONLY_URL_RE.match(content))
if 'todo' in commands:
if type_command == 'todo':
kind = Item.Kind.TODO
elif 'journal' in commands:
elif type_command == 'journal':
kind = Item.Kind.JOURNAL
elif 'link' in commands or only_url:
elif type_command == 'link' or only_url:
kind = Item.Kind.LINK
elif 'note' in commands:
elif type_command == 'note':
kind = Item.Kind.NOTE
else:
kind = default_kind if default_kind in Item.Kind.values else Item.Kind.NOTE
visibility = Item.Visibility.PUBLIC if 'public' in commands else Item.Visibility.PRIVATE
visibility = Item.Visibility.PUBLIC if 'public' in visibility_commands else Item.Visibility.PRIVATE
url_match = URL_RE.search(content)
url = url_match.group(0) if kind == Item.Kind.LINK and url_match else ''
if only_url:
@@ -287,7 +292,7 @@ def new_item(request):
form = QuickItemForm(request.POST, request.FILES)
if form.is_valid():
raw = form.cleaned_data['content']
if requested_kind in {'todo', 'link', 'journal'} and not re.search(r'/(todo|note|link|journal)\b', raw, re.I):
if requested_kind in {'todo', 'link', 'journal'} and not TYPE_COMMAND_RE.match(raw.strip()):
raw = f'/{requested_kind} {raw}'
raw, due_at, _ = parse_due_command(raw)
kind, visibility, content, url = parse_quick_content(raw, prefs.default_item_kind)
@@ -307,7 +312,7 @@ def journal(request):
form = QuickItemForm(request.POST, request.FILES)
if form.is_valid():
raw = form.cleaned_data['content']
if not re.search(r'/(todo|note|link)\b', raw, re.I):
if not TYPE_COMMAND_RE.match(raw.strip()):
raw = f'/journal {raw}'
raw, due_at, _ = parse_due_command(raw)
kind, visibility, content, url = parse_quick_content(raw)