diff --git a/lua/zettelkasten/action.lua b/lua/zettelkasten/action.lua index 1c60076..a7a5c22 100644 --- a/lua/zettelkasten/action.lua +++ b/lua/zettelkasten/action.lua @@ -1,14 +1,10 @@ local A = {} local o = require 'zettelkasten.options' +local link = require 'zettelkasten.link' local BIGNUMBER = 10000000 -local parsers = { - markdown = {ref = "%[.-%]%((.-)%)", text = "%[(.-)%]%(.-%)"}, - wiki = {ref = "%[%[(.-)|?.-%]%]", text = "%[%[.-|?(.-)%]%]"} -} - -- Opens the link passed in in the editor's current buffer. -- Requires a link object passed in. function A.open(link) @@ -30,35 +26,11 @@ function A.open_selected(style) end end --- Return all links contained in the input given in an array. --- Returned link tables have the following structure: --- link = { text=, ref=, startpos=27, endpos=65 } -function A.extract_all_links(input) - if not input then return end - local links = {} - local curpos = 1 - for _, parser in pairs(parsers) do - while input:find(parser.ref, curpos) do - local ref = input:match(parser.ref, curpos) - local text = input:match(parser.text, curpos) - local startpos, endpos = input:find(parser.ref, curpos) - table.insert(links, { - ref = ref, - text = text, - startpos = startpos, - endpos = endpos - }) - curpos = endpos - end - end - return links -end - -- Returns the link currently under cursor, roughly the vim equivalent of yiW. -- Works for links containing spaces in their text or reference link. function A.get_link_under_cursor() local curpos = vim.api.nvim_win_get_cursor(0)[2] - local links = A.extract_all_links(vim.api.nvim_get_current_line()) + local links = link.extract_all(vim.api.nvim_get_current_line()) for _, link in pairs(links) do if link.startpos <= curpos + 1 and link.endpos > curpos then return link @@ -67,10 +39,10 @@ function A.get_link_under_cursor() return nil end --- Returns the next link of the line from the cursor onwards. +-- Returns the next link of the current line from the cursor onwards. function A.get_next_link_on_line() local curpos = vim.api.nvim_win_get_cursor(0)[2] - local links = A.extract_all_links(vim.api.nvim_get_current_line()) + local links = link.extract_all(vim.api.nvim_get_current_line()) local nearestpos = BIGNUMBER local nearestlink for k, link in pairs(links) do diff --git a/lua/zettelkasten/link.lua b/lua/zettelkasten/link.lua index 6100310..35e1aed 100644 --- a/lua/zettelkasten/link.lua +++ b/lua/zettelkasten/link.lua @@ -3,6 +3,27 @@ local L = {} local o = require 'zettelkasten.options' local a = require 'zettelkasten.anchor' +local parsers = { + markdown = { + ref = "%[.-%]%((.-)%)", + text = "%[(.-)%]%(.-%)", + style_func = function(link, text, extension) + return "[" .. L.trimmed(text) .. "](" .. link .. extension .. ")" + end + }, + wiki = { + ref = "%[%[(.-)|?.-%]%]", + text = "%[%[.-|?(.-)%]%]", + style_func = function(link, text) + local pipe = "" + text = L.trimmed(text) + + if text and text ~= "" then pipe = "|" .. text end + return "[[" .. link .. pipe .. "]]" + end + } +} + -- Returns the text cleaned up to be more useful in a link. -- Spaces are replaced by dashes and everything is lowercased. function L.urlify(text) @@ -22,7 +43,7 @@ end -- Returns text with surrounding whitespace trimmed. Returns empty string -- if only whitespace. -local function trimmed(text) +function L.trimmed(text) if not text then return end return text:match '^()%s*$' and '' or text:match '^%s*(.*%S)' end @@ -32,7 +53,7 @@ end function L.style_markdown(link, text) must_have(link) - return "[" .. trimmed(text) .. "](" .. link .. ")" + return "[" .. L.trimmed(text) .. "](" .. link .. ")" end -- Returns a wikilink-compatible transformation of the link and text combination @@ -40,7 +61,7 @@ end function L.style_wiki(link, text) must_have(link) local pipe = "" - text = trimmed(text) + text = L.trimmed(text) if text and text ~= "" then pipe = "|" .. text end return "[[" .. link .. pipe .. "]]" @@ -54,11 +75,11 @@ function L.create(anchor, text, style) style = style or o.zettel().link_style if style == "markdown" then - local link = (a.prepend(anchor, L.urlify(text))) - return L.style_markdown(L.append_extension(link), text) + local link = (a.prepend(anchor, L.urlify(L.trimmed(text)))) + return parsers.markdown.style_func(link, text, o.zettel().extension) elseif style == "wiki" then - return L.style_wiki(anchor, text) + return parsers.wiki.style_func(anchor, text) end error("Link creation failed.") end @@ -71,4 +92,36 @@ function L.new(text, style) return L.create(anchor, text, style) end -return L +-- Return all links contained in the input given in an array. +-- Returned link tables have the following structure: +-- link = { text=, ref=, startpos=27, endpos=65 } +function L.extract_all(input) + if not input then return end + local links = {} + local curpos = 1 + for _, parser in pairs(parsers) do + while input:find(parser.ref, curpos) do + local ref = input:match(parser.ref, curpos) + local text = input:match(parser.text, curpos) + local startpos, endpos = input:find(parser.ref, curpos) + table.insert(links, { + ref = ref, + text = text, + startpos = startpos, + endpos = endpos + }) + curpos = endpos + end + end + return links +end + +return { + new = L.new, + create = L.create, + style_wiki = L.style_wiki, + style_markdown = L.style_markdown, + append_extension = L.append_extension, + urlify = L.urlify, + extract_all = L.extract_all +} diff --git a/lua/zettelkasten/link_spec.lua b/lua/zettelkasten/link_spec.lua index be39a44..03a8475 100644 --- a/lua/zettelkasten/link_spec.lua +++ b/lua/zettelkasten/link_spec.lua @@ -27,40 +27,6 @@ describe("append_extension", function() end) end) -describe("style_markdown", function() - it("should correctly apply transformations to link and text", function() - assert.same("[My AWESOME Link](1910291645_my-awesome-link.md)", - link.style_markdown("1910291645_my-awesome-link.md", - "My AWESOME Link")) - end) - it("should trim whitespace for the text area", function() - assert.same("[](1910291645_my-awesome-link.md)", - link.style_markdown("1910291645_my-awesome-link.md", " ")) - assert.same("[hi](1910291645_my-awesome-link.md)", link.style_markdown( - "1910291645_my-awesome-link.md", " hi ")) - end) - it("should error if no link provided", function() - assert.is_error(function() link.style_markdown("", "mytext") end) - assert.is_error(function() link.style_markdown(nil, "mytext") end) - end) -end) - -describe("style_wiki", function() - it("should error if no link provided", function() - assert.is_error(function() link.style_wiki("", "mytext") end) - assert.is_error(function() link.style_wiki(nil, "mytext") end) - end) - it("should correctly apply transformations to link and text", function() - assert.same("[[1910291645|My AWESOME Link]]", - link.style_wiki("1910291645", "My AWESOME Link")) - end) - it("should trim whitespace for the text area", function() - assert.same("[[1910291645]]", link.style_wiki("1910291645", " ")) - assert.same("[[1910291645|hi]]", - link.style_wiki("1910291645", " hi ")) - end) -end) - describe("create", function() before_each(function() vim.g.zettel_extension = ".md" @@ -82,6 +48,46 @@ describe("create", function() vim.g.zettel_link_style = "wiki" assert.same("[[1910291645]]", link.create("1910291645")) end) + describe("wiki link styling", function() + it("should error if no link provided", function() + assert.is_error(function() link.style_wiki("", "mytext") end) + assert.is_error(function() link.style_wiki(nil, "mytext") end) + end) + it("should correctly apply transformations to link and text", function() + assert.same("[[1910291645|My AWESOME Link]]", + link.create("1910291645", "My AWESOME Link", "wiki")) + end) + it("should trim whitespace for the text area", function() + assert.same("[[1910291645]]", + link.create("1910291645", " ", "wiki")) + assert.same("[[1910291645|hi]]", + link.create("1910291645", " hi ", "wiki")) + end) + describe("markdown link styling", function() + it("should correctly apply transformations to link and text", + function() + assert.same("[My AWESOME Link](1910291645_my-awesome-link.md)", + link.create("1910291645", "My AWESOME Link", + "markdown")) + end) + it("should trim whitespace for the text area", function() + assert.same("[](1910291645.md)", + link.create("1910291645", " ", "markdown")) + assert.same("[hi](1910291645_hi.md)", + link.create("1910291645", " hi ", "markdown")) + end) + it("should error if no link provided", function() + assert.is_error(function() + link.style_markdown("", "mytext") + end) + assert.is_error(function() + link.style_markdown(nil, "mytext") + end) + end) + end) + + end) + end) describe("new", function()