Reading view: tabs are not expanded to tab stops, so ">" + Tab makes a code block and tab-indented list items do not nest

Steps to reproduce

Paste each sample into its own note and open Reading view (→ stands for a Tab character):

>→quoted text
 - foo
   - bar
→ - baz
*→*→*→

Did you follow the troubleshooting guide?

Yes (reproduced in the sandbox vault, no community plugins).

Expected result

CommonMark 0.31.2 expands a tab to the next multiple of 4 columns when it decides block structure:

  1. >+Tab+quoted text is a quote holding the paragraph quoted text (the tab gives only 3 columns after >, and the first is the optional space, so it is not code).
  2. baz is nested under bar (example 9).
  3. *→*→*→ is a horizontal rule (example 11).

Actual result

  1. A quote holding a code block quoted text.
  2. baz is a sibling of bar.
  3. Three nested empty list items.

Spec examples 2, 5, 6 and 7 show the same cause ( →foo is a paragraph instead of code, and code after a tab inside a list item or a quote loses its leading columns).

Environment

SYSTEM INFO:
	Obsidian version: 1.14.5
	Installer version: 1.14.4
	Operating system: Windows 11 Pro 10.0.26300
	Login status: not logged in
	Language: en
	Insider build toggle: off
	Live preview: on
	Base theme: adapt to system
	Community theme: none
	Snippets enabled: 0
	Restricted mode: on

RECOMMENDATIONS:
	none

Sandbox vault, no community plugins, default theme and settings.

Additional information

Related, opposite symptom: Editing modes: code blocks in blockquotes rendered as paragraph instead of code reports >+space+Tab+text, which Reading view shows as code and the editor as a paragraph. Under CommonMark that line is a paragraph, so it is Reading view that is off there too.

More shapes with the same cause, measured on 1.14.5 and on the current Catalyst build. CommonMark’s rule (2.2 Tabs) is that a tab moves to the next multiple of 4 columns. Reading view instead counts a tab as a fixed amount, so a tab after spaces is short and a tab right after a marker is long:

Markdown (⇥ is a tab) Reading view CommonMark
␣␣⇥%% then [^1]: def a paragraph %% 1: def, and the footnote definition is gone a code block %%, then the definition
[ref]: /url then ⇥code a code block a paragraph code
> x then ⇥y a quote, then a code block y one quote, x y (lazy continuation)
- ⇥p a list item holding a code block p a list item with the paragraph p
+⇥␣␣␣x and 1.⇥␣␣␣x a list item with the paragraph x a list item holding a code block
- item, blank, ⇥␣␣␣para a second paragraph in the item a code block in the item
> [!note] then >⇥code a code block inside the callout a paragraph, as in a plain quote

The callout row is why >⇥ behaves differently in a callout and in a plain quote. After a plain quote’s first line the tabbed line is a lazy continuation of that paragraph, where code cannot start. After a callout’s title line it starts a new block, and the tab after > is read as four columns, so it is code. With > and four spaces it is not code, because the first space belongs to the >.

In the first row the user-visible effect is that two spaces before a tab, instead of none, make a footnote definition on the next line stop existing.


Credit: found by @saberzero1 with the remark-obsidian parity harness; I re-checked it on 1.14.5 and the current Catalyst build.