Repository navigation
feat: support pandoc fancy_lists (I. / A. / a. / i. / (1)) behind an opt-in preference - #5754
kingdomseed wants to merge 24 commits into
Conversation
Add utils/listMarker.ts, which reads and writes pandoc fancy_lists markers (decimal, alpha and roman styles with ., ) and () delimiters) and gives the spacing pandoc requires after each marker. Ordered list state gains an optional style and a typed delimiter. The fancyLists option is off by default and re-parses the document when changed.
With fancyLists on, a block tokenizer reads ordered lists that open with an alpha or roman marker, or with a (1) style marker, following pandoc: two spaces after a capital letter or initial-like numeral with a period, later items read in the first item's style, a new list on any change of style or delimiter, nested lists starting at one, and no interruption of a paragraph. Decimal and bullet items also end at a fancy marker. Ordered list state keeps the style, delimiter and start.
Ordered list items are written in their list's style and delimiter, with two spaces after markers such as I. and A. that pandoc would otherwise read as initials. The wider marker moves continuation and nested lines to the new content column. Adjacent lists are told apart by style as well as delimiter, and two ordered lists in a row with the same markers are separated by an HTML comment so they read back as two lists. The tests check each fixture against pandoc when it is installed.
The markdown serializer takes a fancyLists option, passed from the editor options. With it off, two adjacent ordered lists with the same markers are written as before.
Ordered lists carry their style and delimiter as data attributes, and the stylesheet maps them to counter styles, so a. IV) and (1) lists show their own markers instead of decimal ones. A Chromium e2e test reads the marker text from the accessibility tree.
Tab makes a sublist that numbers from one. Under an upper-roman list it takes the outline marker for its depth (I., A., 1., a., i., (1), (a)); other lists keep the parent marker. Outdent and split compare the list style as well as the delimiter, so items of a different style are not merged into the same list. Turning an ordered task list into an ordered list from the front menu keeps its style.
With fancyLists on, a paragraph whose first line starts with a marker such as I. A. a. i. (1) (a) or c) becomes an ordered list in that style. Capital letters and initial-like numerals with a period need two spaces, so B. Russell stays text, and a list inside a list item has to start at one. Converting an item to a task item keeps the list style.
With fancyLists off, Tab copies the parent list's start number into the new sublist as before.
With fancyLists on, HTML export, static rendering and clipboard HTML read pandoc fancy lists and write each ordered list as <ol type> plus a class naming its style and delimiter. Export CSS draws the ) and (1) markers with @counter-style and keeps nested typed lists from being forced to decimal.
The markdown reader used for backslash math switched off every extension the gfm listing does not name. gfm reads fenced code, intraword underscores, backslash line breaks, shortcut reference links and start numbers without listing them, so those exports turned code blocks into inline code and lost list start numbers.
Preferences > Markdown gets a switch for pandoc's fancy_lists extension, off by default. Toggling it re-parses the open document so lettered and Roman numeral lists appear or turn back into text.
With fancyLists on, Convert with Pandoc reads the document with pandoc's markdown reader, shaped like gfm, plus fancy_lists. pandoc's gfm reader takes +fancy_lists but folds an indented A. item into its parent's text, so an outline only nests when markdown reads it.
With fancyLists on, the / quick-insert menu and Paragraph > Outline (Cmd+Option+K on macOS, Ctrl+Alt+K on Linux) insert an ordered list in upper-roman style, turn the list at the cursor into one, or wrap a multi-block selection into one. Windows gets no default shortcut because Ctrl+Alt types characters there. The entry is hidden while the option is off.
Copied markdown now ends a list with <!-- --> before another list in the same style, as saving does, so pasting it reads back two lists.
The block menu builds its Turn Into list from the quick-insert entries through canTurnInto, so a paragraph already offers Outline with its icon while fancyLists is on. Pin that, and that choosing it writes I. text.
Launch the app with fancyLists on and check that an outline renders as nested typed lists, that Tab and Shift+Tab move an item along the outline ladder, that Enter continues roman numbering, and that the markers stay paragraph text with the preference off.
Add the fancyLists preference to the preferences reference, and a Fancy lists section to the syntax guide covering the markers, the two-space rule, the outline levels Tab moves through, and the <!-- --> list separator.
3956d85 to
8d7979b
Compare
|
@kingdomseed I haven't reviewed the code thoroughly yet, but I've tested the new feature on macOS.
|
A fancy list is an ordered list with another marker style, so it needs no list type of its own. Remove the / quick-insert entry, Turn Into > Outline, Paragraph > Outline, its keyboard shortcuts, locale strings, icons and tests. Typing I. and two spaces still starts an outline, and Tab still steps through the outline levels.
With fancyLists on, #., #) and (#) open an ordered list in pandoc's default style. The editor and HTML export number it in digits, and a save keeps the # markers, also after an edit. Typing #. and a space starts one. As in pandoc, a # item continues a list of any style, a # list continues with digits, and adjacent lists that would read back as one are ended with <!-- -->.
|
Thanks for testing! Both are addressed in the latest commits:
One question: right now there's no way to change an existing ordered list's style in the editor. Would you be OK with a "List style" choice on ordered lists, shown only when fancy lists are on? It would sit in the ¶ menu next to Turn Into, offer 1. / a. / A. / i. / I. / (1) / #., and restyle the whole list in place. It's not a new list type, just a style on the existing ordered list. |
86eaef6 to
aab6136
Compare
|
Sorry for the delay in reviewing this PR. I've been busy with some refactoring recently, including the Selection refactor and support for editing transactions. Could you please rebase onto the latest I'll review it as soon as I can. Thanks again for your contribution! |
Closes #4379
Summary
Adds pandoc's
fancy_liststo the editor, behind a new preference that is off by default (Preferences → Markdown → Letter and Roman numeral lists). As discussed in #4379, this replaces the custom outline block this PR first proposed. There is no new syntax: ordered lists read, edit, and save pandoc's markers.1.1)(1)#.#)(#)a.A.a)(a)i.I.i)(i)With the preference off, the editor behaves exactly as it does on
develop:With it on, the same markers become real nested lists:
The file stays plain pandoc markdown. Pandoc 3.12.1 reads this source as the same seven nested lists:
Outlines
A list that starts with
I.is an outline. Tab gives the new sublist the next style, I → A → 1 → a → i → (1) → (a), and Shift+Tab moves back. Every marker after the change renumbers. Lists that start with1.keep today's Tab behavior.Typing
I.,A.,a.,i.,(1),#., or1)at the start of a paragraph starts a list. Pandoc's two-space rule keeps prose such asB. Russellas text. Fancy lists are ordinary ordered lists, so there are no new menu entries or shortcuts.Markers follow the theme:
What else changes
1)and(1)lists show their real delimiters. Today1)renders as1..<ol type="I">and similar, so other apps and screen readers see real lists.markdown. Pandoc'sgfmandcommonmarkreaders do not nest these lists, even with+fancy_lists.markdownreader that backslash math already uses turned off syntax that gfm reads natively: fenced code, intraword_, backslash line breaks, and shortcut links. Fancy-list exports use that reader, so I fixed it in038ac51f. The fix also corrects exports for people who use backslash math.Code
The parser, model, and serializer live in
packages/muya. One table of marker styles inutils/listMarker.tsdrives parsing, formatting, spacing, and the outline ladder.Decimal lists still go through marked's own tokenizer, so documents without fancy markers parse the same with the preference on or off.
Type of change
Test plan
New tests added
test/e2e/fancy-lists.spec.tscovers rendering, Tab and Shift+Tab, Enter, and the off switch.Ran locally on macOS:
test(2845),test:spec(1347),lint:types,build, andcheck-circulartest(1117)validate-licensespandoc-discovery.spec.tsfails locally only because pandoc is installed on that machine. The same 2 cases fail ondevelop.Manually tested on: macOS
Notes for reviewers [optional]
z, letters wrap toa, as pandoc writes them.A.and after single-letter Roman numerals such asI.andV..<!-- -->between them, pandoc's way to end a list.developbyte for byte. Tests assert both.endListItemsAtFancyMarkersswaps marked's internalnextBulletRegex, so check it on marked upgrades.parathen(a) x, no blank line) as a list, while the editor keeps it as text, as pandoc's ownmarkdowndoes. The export reader enableslists_without_preceding_blanklinesoparathen1. xexports as a list, matching how the editor treats decimal lists.start.By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.