A Neovim plugin enabling you to solve LeetCode problems.
fix: `cn` `&lcpad;`
5 files changed, +49 -31
+12-2.neoconf.json
| @@ -3,13 +3,23 @@ | ||
| 3 | 3 | "library": { |
| 4 | 4 | "enabled": true, |
| 5 | 5 | "plugins": [ |
| 6 | - "nvim-treesitter", | |
| 7 | 6 | "telescope.nvim", |
| 8 | 7 | "plenary.nvim", |
| 9 | 8 | "nui.nvim", |
| 10 | 9 | "nvim-web-devicons", |
| 11 | - "image.nvim" | |
| 10 | + "image.nvim", | |
| 11 | + "nvim-treesitter" | |
| 12 | 12 | ] |
| 13 | 13 | } |
| 14 | + }, | |
| 15 | + "neoconf": { | |
| 16 | + "plugins": { | |
| 17 | + "lua_ls": { | |
| 18 | + "enabled": true | |
| 19 | + } | |
| 20 | + } | |
| 21 | + }, | |
| 22 | + "lspconfig": { | |
| 23 | + "sumneko_lua": {} | |
| 14 | 24 | } |
| 15 | 25 | } |
+7-17lua/leetcode-plugins/cn/normalizer.lua
| @@ -11,16 +11,10 @@ function Normalizer:cleanup() | ||
| 11 | 11 | :gsub(" ", " ") |
| 12 | 12 | :gsub("<(/?)b([^>]*)>", "<%1strong%2>") |
| 13 | 13 | :gsub(":", ":") |
| 14 | - -- :gsub("<=", "≤") | |
| 15 | - -- :gsub(">", "≤") | |
| 16 | - -- :gsub("<", "≤") | |
| 17 | - -- :gsub("> =", "≤") | |
| 18 | - | |
| 19 | - -- for e, char in pairs(u.entities) do | |
| 20 | - -- self.text = self.text:gsub(e, char) | |
| 21 | - -- end | |
| 22 | 14 | end |
| 23 | 15 | |
| 16 | +-- :gsub("<strong>(提示:%s*)</strong>", "<followup>%1</followup>") -- Note | |
| 17 | + | |
| 24 | 18 | function Normalizer:tags() -- |
| 25 | 19 | self.text = self |
| 26 | 20 | .text -- |
| @@ -28,25 +22,21 @@ function Normalizer:tags() -- | ||
| 28 | 22 | :gsub("<strong>(输出:?%s*)</strong>", "<output>%1</output>") -- output |
| 29 | 23 | :gsub("<strong>(解释:?%s*)</strong>", "<explanation>%1</explanation>") -- explanation |
| 30 | 24 | :gsub("<strong>(进阶:?%s*)</strong>", "<followup>%1</followup>") -- Note |
| 31 | - -- :gsub("<strong>(提示:%s*)</strong>", "<followup>%1</followup>") -- Note | |
| 32 | - :gsub( | |
| 33 | - "<strong>(注意:%s*)</strong>", | |
| 34 | - "<followup>%1</followup>" | |
| 35 | - ) -- Followup | |
| 25 | + :gsub("<strong>(注意:?%s*)</strong>", "<followup>%1</followup>") -- Followup | |
| 36 | 26 | :gsub( |
| 37 | - "\n*<p><strong[^>]*>(示例%s*%d*:?)%s*</strong></p>\n*", | |
| 27 | + "\n*<p>%s*<strong[^>]*>(示例%s*%d*:?)%s*</strong>%s*</p>\n*", | |
| 38 | 28 | "\n\n<example> %1</example>\n\n" |
| 39 | 29 | ) |
| 40 | 30 | :gsub( |
| 41 | - "\n*<p><strong[^>]*>(提示:?)%s*</strong></p>\n*", | |
| 31 | + "\n*<p>%s*<strong[^>]*>(提示:?%s*)</strong>%s*</p>\n*", | |
| 42 | 32 | "\n\n<constraints> %1</constraints>\n\n" |
| 43 | 33 | ) |
| 44 | 34 | :gsub( |
| 45 | - "\n*<p><strong[^>]*>(限制:?)%s*</strong></p>\n*", | |
| 35 | + "\n*<p>%s*<strong[^>]*>(限制:?%s*)</strong>%s*</p>\n*", | |
| 46 | 36 | "\n\n<constraints> %1</constraints>\n\n" |
| 47 | 37 | ) |
| 48 | 38 | :gsub( |
| 49 | - "\n*<p>%s*<strong[^>]*>(提示:?)%s*</strong>%s*</p>\n*", | |
| 39 | + "\n*<p>%s*<strong[^>]*>(提示:?%s*)</strong>%s*</p>\n*", | |
| 50 | 40 | "\n\n<constraints> %1</constraints>\n\n" |
| 51 | 41 | ) |
| 52 | 42 | end |
+23-2lua/leetcode-ui/group/tag/init.lua
| @@ -1,13 +1,12 @@ | ||
| 1 | 1 | local theme = require("leetcode.theme") |
| 2 | 2 | local u = require("leetcode-ui.utils") |
| 3 | +local ts = vim.treesitter | |
| 3 | 4 | |
| 4 | 5 | local utils = require("leetcode.parser.utils") |
| 5 | 6 | local Group = require("leetcode-ui.group") |
| 6 | 7 | local Indent = require("nui.text") |
| 7 | 8 | local Normalizer = require("leetcode.parser.normalizer") |
| 8 | 9 | |
| 9 | -local ts = vim.treesitter | |
| 10 | - | |
| 11 | 10 | local log = require("leetcode.logger") |
| 12 | 11 | |
| 13 | 12 | ---@class lc.ui.Tag : lc.ui.Group |
| @@ -233,6 +232,7 @@ local LeetTag = Tag | ||
| 233 | 232 | |
| 234 | 233 | ---@param text string |
| 235 | 234 | function Tag.static:parse(text) -- |
| 235 | + ---@type string | |
| 236 | 236 | local normalized = Normalizer:norm(text) |
| 237 | 237 | |
| 238 | 238 | local ok, parser = pcall(ts.get_string_parser, normalized, "html") |
| @@ -243,7 +243,28 @@ function Tag.static:parse(text) -- | ||
| 243 | 243 | end |
| 244 | 244 | |
| 245 | 245 | local root = parser:parse()[1]:root() |
| 246 | + | |
| 247 | + local query = ts.query.parse( | |
| 248 | + "html", | |
| 249 | + [[ | |
| 250 | + (element | |
| 251 | + (start_tag | |
| 252 | + (tag_name) @stag (#any-of? @stag "strong" "b")) | |
| 253 | + (text) @text (#match? @text | |
| 254 | + "(Input|Output|Explanation|Note|Follow-up):?") | |
| 255 | + (end_tag | |
| 256 | + (tag_name) @etag)) @el | |
| 257 | + ]] | |
| 258 | + ) | |
| 259 | + | |
| 260 | + for id, capture, md in query:iter_captures(root, normalized) do | |
| 261 | + log.info(md) | |
| 262 | + end | |
| 263 | + | |
| 246 | 264 | return LeetTag(normalized, { spacing = 3, hl = "leetcode_normal" }, root, {}) |
| 247 | 265 | end |
| 248 | 266 | |
| 267 | +-- parser = ts.get_string_parser(normalized, "html") | |
| 268 | +-- root = parser:parse()[1]:root() | |
| 269 | + | |
| 249 | 270 | return LeetTag |
+2-1lua/leetcode-ui/split/description.lua
| @@ -135,7 +135,8 @@ function Description:populate() | ||
| 135 | 135 | todo = { "", "leetcode_alt" }, |
| 136 | 136 | } |
| 137 | 137 | if user_status[self.question.cache.status] then |
| 138 | - header:append(" "):append(table.unpack(user_status[self.question.cache.status])) | |
| 138 | + local s = user_status[self.question.cache.status] | |
| 139 | + header:append(" "):append(s[1], s[2]) | |
| 139 | 140 | end |
| 140 | 141 | |
| 141 | 142 | header:append(" | ") |
+5-9lua/leetcode/parser/normalizer.lua
| @@ -14,6 +14,7 @@ function Normalizer:cleanup() -- | ||
| 14 | 14 | :gsub("<br%s*/>", "\n") |
| 15 | 15 | :gsub("<meta[^>]*/>", "") |
| 16 | 16 | :gsub(" ", " ") |
| 17 | + :gsub("\u{00A0}", " ") | |
| 17 | 18 | :gsub("<(/?)b([^>]*)>", "<%1strong%2>") |
| 18 | 19 | -- :gsub("&#?%w+;", function(e) -- |
| 19 | 20 | -- return vim.tbl_keys({}) |
| @@ -55,21 +56,16 @@ function Normalizer:tags() -- | ||
| 55 | 56 | end |
| 56 | 57 | |
| 57 | 58 | function Normalizer:entities() |
| 59 | + log.debug(self.text) | |
| 58 | 60 | self.text = self |
| 59 | 61 | .text -- |
| 60 | - :gsub("\n*<p>%s+</p>\n*", "&lcpad;") | |
| 62 | + :gsub("\n*<p>%s*</p>\n*", "&lcpad;") | |
| 63 | + :gsub("\n*<p> *</p>\n*", "&lcpad;") | |
| 61 | 64 | :gsub("<([^>]+)>(%s*)</%1>", "%2") |
| 62 | 65 | :gsub("\n", "&lcnl;") |
| 63 | 66 | :gsub("\t", "&lctab;") |
| 64 | 67 | :gsub("%s", " ") |
| 65 | - -- :gsub( | |
| 66 | - -- "(%s*)(<[^>]+>)(%s*)", | |
| 67 | - -- function(m1, m2, m3) return m1:gsub(".", " ") .. m2 .. m3:gsub(".", " ") end | |
| 68 | - -- ) | |
| 69 | - :gsub( | |
| 70 | - "<[^>]+>", | |
| 71 | - function(match) return match:gsub(" ", " ") end | |
| 72 | - ) | |
| 68 | + :gsub("<[^>]+>", function(match) return match:gsub(" ", " ") end) | |
| 73 | 69 | end |
| 74 | 70 | |
| 75 | 71 | ---@param text string |