|
| 1 | +--- |
| 2 | +author: malys |
| 3 | +description: Generate and copy links to specific cursor positions and headers in markdown documents |
| 4 | +name: "Library/Malys/CursorPosition" |
| 5 | +tags: meta/library |
| 6 | +--- |
| 7 | +# Cursor Position Link Generator |
| 8 | + |
| 9 | +This script provides functionality to generate and copy links to specific cursor positions and headers within markdown documents. It's particularly useful for creating precise references within a document or across multiple documents. |
| 10 | + |
| 11 | +## Features |
| 12 | + |
| 13 | +- **External Links**: Generate full URLs pointing to specific cursor positions or headers |
| 14 | +- **Internal Links**: Create markdown-style internal links for use within the same document |
| 15 | + |
| 16 | +## Usage |
| 17 | + |
| 18 | +### External Links (Ctrl+Shift+C) |
| 19 | +Copies a full URL to the current cursor position or header to the clipboard. |
| 20 | +- If the cursor is on a header line: Creates a URL with the header as an anchor (e.g., `https://your-host/Page#Header Name`) |
| 21 | +- If not on a header: Creates a URL with the cursor position (e.g., `https://your-host/Page@123`) |
| 22 | + |
| 23 | +### Internal Links (Ctrl+Shift+L) |
| 24 | +Copies a markdown-style internal link to the current cursor position or header. |
| 25 | +- If on a header: Creates a link like `[Header Name@123]` |
| 26 | +- If not on a header: Creates a link like `[Page Name@123]` |
| 27 | +--- |
| 28 | +## Source |
| 29 | +```space-lua |
| 30 | +-- [[Page#Header]] -> http(s)://host/Page#Header |
| 31 | +-- [[Page@pos]] -> http(s)://host/Page@pos |
| 32 | +
|
| 33 | +local function replace_space_with_percent20(s) |
| 34 | + local parts = {} |
| 35 | + for i = 1, #s do |
| 36 | + local c = s:sub(i, i) |
| 37 | + if c == " " then |
| 38 | + parts[#parts+1] = "%20" |
| 39 | + else |
| 40 | + parts[#parts+1] = c |
| 41 | + end |
| 42 | + end |
| 43 | + return table.concat(parts) |
| 44 | +end |
| 45 | +
|
| 46 | +local function build_page_url(pageName) |
| 47 | + -- get direct url from js |
| 48 | + local BASE_URL = js.window.location.origin |
| 49 | + local path = replace_space_with_percent20(pageName) |
| 50 | + if BASE_URL:sub(-1) == "/" then |
| 51 | + return BASE_URL .. path |
| 52 | + else |
| 53 | + return BASE_URL .. "/" .. path |
| 54 | + end |
| 55 | +end |
| 56 | +
|
| 57 | +command.define { |
| 58 | + name = "Cursor: Copy external link", |
| 59 | + key = "Ctrl-Shift-c", |
| 60 | + run = function() |
| 61 | + local currentLine = editor.getCurrentLine().text |
| 62 | + local pageName = editor.getCurrentPage() |
| 63 | + local pos = editor.getCursor() |
| 64 | + local headerMarks, headerName = string.match(currentLine, "^(#+) +(.+)$") |
| 65 | + |
| 66 | + local pageUrl = build_page_url(pageName) |
| 67 | + local out |
| 68 | + if headerMarks and headerName and headerName:match("%S") then |
| 69 | + headerName = headerName:match("^%s*(.+)") |
| 70 | + headerName = replace_space_with_percent20(headerName) |
| 71 | + out = string.format("%s#%s", pageUrl, headerName) |
| 72 | + -- editor.flashNotification("Copied header external link: " .. out, "info") |
| 73 | + editor.flashNotification("Copied header link: " .. out, "info") |
| 74 | + else |
| 75 | + out = string.format("%s@%d", pageUrl, pos) |
| 76 | + -- editor.flashNotification("Copied cursor external link: " .. out, "info") |
| 77 | + editor.flashNotification("Copied cursor link: " .. out, "info") |
| 78 | + end |
| 79 | + |
| 80 | + editor.copyToClipboard(out) |
| 81 | + end |
| 82 | +} |
| 83 | +
|
| 84 | +
|
| 85 | +command.define { |
| 86 | + name = "Cursor: Copy internal link", |
| 87 | + key = "Ctrl-Shift-l", |
| 88 | + run = function() |
| 89 | + local currentLine = editor.getCurrentLine().text |
| 90 | + local pageName = editor.getCurrentPage() |
| 91 | + local pos = editor.getCursor() |
| 92 | + local headerMarks, headerName = string.match(currentLine, "^(#+) +(.+)$") |
| 93 | + |
| 94 | + local out |
| 95 | + if headerMarks and headerName and headerName:match("%S") then |
| 96 | + headerName = headerName:match("^%s*(.+)") |
| 97 | + out = string.format("[[%s@%s]]", replace_space_with_percent20(headerName), pos) |
| 98 | + editor.flashNotification("Copied header internal link: " .. out, "info") |
| 99 | + else |
| 100 | + out = string.format("[[%s@%d]]", replace_space_with_percent20(pageName), pos) |
| 101 | + editor.flashNotification("Copied cursor internal link: " .. out, "info") |
| 102 | + end |
| 103 | + |
| 104 | + editor.copyToClipboard(out) |
| 105 | + end |
| 106 | +} |
| 107 | +
|
| 108 | +``` |
0 commit comments