Skip to content

Commit

Permalink
feat: add default icons for ordered lists
Browse files Browse the repository at this point in the history
## Details

Request: #250

Previously we supported adding icons for ordered lists in much the same
way as unordered, however by default the value was empty.

To do an auto ordering for the pattern of using `1.` for every value we
now provide a default value. However, because ordered lists can go on
and we want to support arbitrary lengths we now also support setting a
function for both ordered and unordered list icons. The function is
called with both the level of the list and the index of the item and
whatever value is returned is used as the icon.

The default function just concatenates a period after the index value
and ignores the level.
  • Loading branch information
MeanderingProgrammer committed Dec 6, 2024
1 parent 7674543 commit a7097f3
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 36 deletions.
32 changes: 22 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,14 +362,20 @@ require('render-markdown').setup({
-- Turn on / off list bullet rendering
enabled = true,
-- Replaces '-'|'+'|'*' of 'list_item'
-- How deeply nested the list is determines the 'level' which is used to index into the list using a cycle
-- The item number in the list is used to index into the value using a clamp if the value is also a list
-- How deeply nested the list is determines the 'level', how far down at that level determines the 'index'
-- If a function is provided both of these values are passed in using 1 based indexing
-- If a list is provided we index into it using a cycle based on the level
-- If the value at that level is also a list we further index into it using a clamp based on the index
-- If the item is a 'checkbox' a conceal is used to hide the bullet instead
icons = { '', '', '', '' },
-- Replaces 'n.'|'n)' of 'list_item'
-- How deeply nested the list is determines the 'level' which is used to index into the list using a cycle
-- The item number in the list is used to index into the value using a clamp if the value is also a list
ordered_icons = {},
-- How deeply nested the list is determines the 'level', how far down at that level determines the 'index'
-- If a function is provided both of these values are passed in using 1 based indexing
-- If a list is provided we index into it using a cycle based on the level
-- If the value at that level is also a list we further index into it using a clamp based on the index
ordered_icons = function(level, index)
return string.format('%d.', index)
end,
-- Padding to add to the left of bullet point
left_pad = 0,
-- Padding to add to the right of bullet point
Expand Down Expand Up @@ -859,14 +865,20 @@ require('render-markdown').setup({
-- Turn on / off list bullet rendering
enabled = true,
-- Replaces '-'|'+'|'*' of 'list_item'
-- How deeply nested the list is determines the 'level' which is used to index into the list using a cycle
-- The item number in the list is used to index into the value using a clamp if the value is also a list
-- How deeply nested the list is determines the 'level', how far down at that level determines the 'index'
-- If a function is provided both of these values are passed in using 1 based indexing
-- If a list is provided we index into it using a cycle based on the level
-- If the value at that level is also a list we further index into it using a clamp based on the index
-- If the item is a 'checkbox' a conceal is used to hide the bullet instead
icons = { '', '', '', '' },
-- Replaces 'n.'|'n)' of 'list_item'
-- How deeply nested the list is determines the 'level' which is used to index into the list using a cycle
-- The item number in the list is used to index into the value using a clamp if the value is also a list
ordered_icons = {},
-- How deeply nested the list is determines the 'level', how far down at that level determines the 'index'
-- If a function is provided both of these values are passed in using 1 based indexing
-- If a list is provided we index into it using a cycle based on the level
-- If the value at that level is also a list we further index into it using a clamp based on the index
ordered_icons = function(level, index)
return string.format('%d.', index)
end,
-- Padding to add to the left of bullet point
left_pad = 0,
-- Padding to add to the right of bullet point
Expand Down
34 changes: 23 additions & 11 deletions doc/render-markdown.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*render-markdown.txt* For 0.10.0 Last change: 2024 December 04
*render-markdown.txt* For 0.10.0 Last change: 2024 December 05

==============================================================================
Table of Contents *render-markdown-table-of-contents*
Expand Down Expand Up @@ -409,14 +409,20 @@ Default Configuration ~
-- Turn on / off list bullet rendering
enabled = true,
-- Replaces '-'|'+'|'*' of 'list_item'
-- How deeply nested the list is determines the 'level' which is used to index into the list using a cycle
-- The item number in the list is used to index into the value using a clamp if the value is also a list
-- How deeply nested the list is determines the 'level', how far down at that level determines the 'index'
-- If a function is provided both of these values are passed in using 1 based indexing
-- If a list is provided we index into it using a cycle based on the level
-- If the value at that level is also a list we further index into it using a clamp based on the index
-- If the item is a 'checkbox' a conceal is used to hide the bullet instead
icons = { '●', '○', '◆', '◇' },
-- Replaces 'n.'|'n)' of 'list_item'
-- How deeply nested the list is determines the 'level' which is used to index into the list using a cycle
-- The item number in the list is used to index into the value using a clamp if the value is also a list
ordered_icons = {},
-- How deeply nested the list is determines the 'level', how far down at that level determines the 'index'
-- If a function is provided both of these values are passed in using 1 based indexing
-- If a list is provided we index into it using a cycle based on the level
-- If the value at that level is also a list we further index into it using a clamp based on the index
ordered_icons = function(level, index)
return string.format('%d.', index)
end,
-- Padding to add to the left of bullet point
left_pad = 0,
-- Padding to add to the right of bullet point
Expand Down Expand Up @@ -896,14 +902,20 @@ Bullet Point Configuration ~
-- Turn on / off list bullet rendering
enabled = true,
-- Replaces '-'|'+'|'*' of 'list_item'
-- How deeply nested the list is determines the 'level' which is used to index into the list using a cycle
-- The item number in the list is used to index into the value using a clamp if the value is also a list
-- How deeply nested the list is determines the 'level', how far down at that level determines the 'index'
-- If a function is provided both of these values are passed in using 1 based indexing
-- If a list is provided we index into it using a cycle based on the level
-- If the value at that level is also a list we further index into it using a clamp based on the index
-- If the item is a 'checkbox' a conceal is used to hide the bullet instead
icons = { '●', '○', '◆', '◇' },
-- Replaces 'n.'|'n)' of 'list_item'
-- How deeply nested the list is determines the 'level' which is used to index into the list using a cycle
-- The item number in the list is used to index into the value using a clamp if the value is also a list
ordered_icons = {},
-- How deeply nested the list is determines the 'level', how far down at that level determines the 'index'
-- If a function is provided both of these values are passed in using 1 based indexing
-- If a list is provided we index into it using a cycle based on the level
-- If the value at that level is also a list we further index into it using a clamp based on the index
ordered_icons = function(level, index)
return string.format('%d.', index)
end,
-- Padding to add to the left of bullet point
left_pad = 0,
-- Padding to add to the right of bullet point
Expand Down
2 changes: 1 addition & 1 deletion lua/render-markdown/health.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ local state = require('render-markdown.state')
local M = {}

---@private
M.version = '7.6.10'
M.version = '7.6.11'

function M.check()
M.start('version')
Expand Down
22 changes: 15 additions & 7 deletions lua/render-markdown/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,12 @@ local M = {}
---@field public checked? render.md.UserCheckboxComponent
---@field public custom? table<string, render.md.UserCustomCheckbox>

---@alias render.md.bullet.Icons string[]|string[][]|fun(level: integer, index: integer): string?

---@class (exact) render.md.UserBullet
---@field public enabled? boolean
---@field public icons? (string|string[])[]
---@field public ordered_icons? (string|string[])[]
---@field public icons? render.md.bullet.Icons
---@field public ordered_icons? render.md.bullet.Icons
---@field public left_pad? integer
---@field public right_pad? integer
---@field public highlight? string
Expand Down Expand Up @@ -494,14 +496,20 @@ M.default_config = {
-- Turn on / off list bullet rendering
enabled = true,
-- Replaces '-'|'+'|'*' of 'list_item'
-- How deeply nested the list is determines the 'level' which is used to index into the list using a cycle
-- The item number in the list is used to index into the value using a clamp if the value is also a list
-- How deeply nested the list is determines the 'level', how far down at that level determines the 'index'
-- If a function is provided both of these values are passed in using 1 based indexing
-- If a list is provided we index into it using a cycle based on the level
-- If the value at that level is also a list we further index into it using a clamp based on the index
-- If the item is a 'checkbox' a conceal is used to hide the bullet instead
icons = { '', '', '', '' },
-- Replaces 'n.'|'n)' of 'list_item'
-- How deeply nested the list is determines the 'level' which is used to index into the list using a cycle
-- The item number in the list is used to index into the value using a clamp if the value is also a list
ordered_icons = {},
-- How deeply nested the list is determines the 'level', how far down at that level determines the 'index'
-- If a function is provided both of these values are passed in using 1 based indexing
-- If a list is provided we index into it using a cycle based on the level
-- If the value at that level is also a list we further index into it using a clamp based on the index
ordered_icons = function(level, index)
return string.format('%d.', index)
end,
-- Padding to add to the left of bullet point
left_pad = 0,
-- Padding to add to the right of bullet point
Expand Down
12 changes: 9 additions & 3 deletions lua/render-markdown/render/list_item.lua
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,16 @@ end
---@private
---@param level integer
function Render:icon(level)
local index = self.node:sibling_count('list_item')
local icons = self.data.ordered and self.bullet.ordered_icons or self.bullet.icons
local icon = List.cycle(icons, level)
if type(icon) == 'table' then
icon = List.clamp(icon, self.node:sibling_count('list_item'))
local icon = nil
if type(icons) == 'function' then
icon = icons(level, index)
else
icon = List.cycle(icons, level)
if type(icon) == 'table' then
icon = List.clamp(icon, index)
end
end
if icon == nil then
return
Expand Down
2 changes: 1 addition & 1 deletion lua/render-markdown/state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ function M.validate()
:type('enabled', 'boolean')
:type({ 'left_pad', 'right_pad' }, 'number')
:type('highlight', 'string')
:list_or_list_of_list({ 'icons', 'ordered_icons' }, 'string')
:list_or_list_of_list({ 'icons', 'ordered_icons' }, 'string', 'function')
:check()
end)
:nested('checkbox', function(checkbox)
Expand Down
4 changes: 2 additions & 2 deletions lua/render-markdown/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@

---@class (exact) render.md.Bullet
---@field public enabled boolean
---@field public icons (string|string[])[]
---@field public ordered_icons (string|string[])[]
---@field public icons render.md.bullet.Icons
---@field public ordered_icons render.md.bullet.Icons
---@field public left_pad integer
---@field public right_pad integer
---@field public highlight string
Expand Down
7 changes: 6 additions & 1 deletion tests/list_table_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ describe('list_table.md', function()

vim.list_extend(expected, util.heading(row:increment(2), 1))

vim.list_extend(expected, util.heading(row:increment(5), 1))
vim.list_extend(expected, {
util.ordered(row:increment(2), 0, '1.'),
util.ordered(row:increment(1), 0, '2.'),
})

vim.list_extend(expected, util.heading(row:increment(2), 1))

vim.list_extend(expected, {
util.table_border(row:increment(2), true, { 8, 15, 7, 6 }),
Expand Down
14 changes: 14 additions & 0 deletions tests/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,20 @@ function M.bullet(row, col, level, spaces)
}
end

---@param row integer
---@param col integer
---@param text string
---@return render.md.MarkInfo
function M.ordered(row, col, text)
---@type render.md.MarkInfo
return {
row = { row, row },
col = { col, col + 3 },
virt_text = { { text, M.hl('Bullet') } },
virt_text_pos = 'overlay',
}
end

---@param row integer
---@param start_col integer
---@param end_col integer
Expand Down

0 comments on commit a7097f3

Please sign in to comment.