Files
thoughtsync/frontend/src/components/MarkdownInline.vue
T
bvandeusenandClaude Opus 5 d9e5753dc2
CI & Build / Build now, or wait for Android? (push) Successful in 2s
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 6s
CI & Build / Python tests (push) Successful in 10s
CI & Build / integration (push) Successful in 16s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Tauri desktop (Linux) (push) Failing after 2m37s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 2m53s
Desktop (Tauri) / Update manifest (push) Skipped
Android / Kotlin + Rust (APK) (push) Canceled after 3m25s
board: a tag in the prose is coloured where it sits, not printed twice
A tagged note was showing its tag twice — once where it was typed, once as a
chip — and the duplicate was the loud copy. Now the chip row carries only what
the body cannot say (a tag lifted off its own line, a label from the picker),
and a `#tag` left mid-sentence is tinted in place.

Which characters are a tag is asked of the CORE, the way the card already asks
it which lines are checklist items: `extract_tag_spans` keeps the spans
`extract_tags` throws away, and `body_tags` hands them to Kotlin. Offsets are
UTF-16 code units, because `AnnotatedString` and JS both index that way and a
char index lands mid-token the first time somebody writes an emoji. The web
keeps its own matcher in markdown.ts, mirroring `line_tags` case for case.

The inline ink is its own table, one Tailwind step deeper than the chip's. A
chip brings its own -100 fill and reads against that alone; inline text sits on
whatever the card is, including a gray-tagged card at neutral-200 — where the
chip's -700 measured 3.98 (green), 4.11 (orange) and 4.34 (teal), under the 4.5
body text needs. At -800/-300 every hue lands 5.63-12.01 light and 7.20-10.84
dark across every palette and generated fill.

Chips now carry the `#` on every surface. The via_tag branch that used to
decide it is gone from the card, and Android's row said no hash at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 22:20:17 -04:00

31 lines
1.4 KiB
Vue

<script setup lang="ts">
import type { InlineToken } from "../notes/markdown";
import { tagTextClasses } from "../notes/colors";
// Emphasis, code, and `#tags`. `[[wiki-links]]` were the one token type that needed a
// router, a store and a resolver behind it; they are gone (note 2897), and so is all
// of that.
//
// `tagColors` maps a lowercased tag name to the colour stored on that label. Threaded
// down from the card rather than looked up here, because this component renders text
// and has no idea which note the text belongs to — and a tag the operator recoloured
// must read the same here as it does on a chip.
defineProps<{ tokens: InlineToken[]; tagColors?: Record<string, string> }>();
</script>
<!-- Rendered tightly (no whitespace between tokens) so a token's own leading/trailing
spaces are preserved and no extra spaces are introduced. -->
<template
><template v-for="(t, i) in tokens" :key="i"
><strong v-if="t.type === 'bold'" class="font-semibold">{{ t.value }}</strong
><em v-else-if="t.type === 'italic'">{{ t.value }}</em
><code
v-else-if="t.type === 'code'"
class="rounded bg-black/5 px-1 py-0.5 font-mono text-[0.85em] dark:bg-white/10"
>{{ t.value }}</code
><span v-else-if="t.type === 'tag'" class="font-medium" :class="tagTextClasses(t.value, tagColors)"
>#{{ t.value }}</span
><template v-else>{{ t.value }}</template></template
></template
>