Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/.vscode/settings.json
107 changes: 107 additions & 0 deletions Admonition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Admonition Widget
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about "Advanced Adminitions"?

Since this is not really a widget.


This widget allows you to create admonition boxes with different types and colors.

- Specify the type of admonition box with the `admonition` attribute.
- Customize the color of the admonition box with the `color` attribute.

The following types are available:

- `abstract`
- `caution`
- `danger`
- `error`
- `hint`
- `important`
- `note`
- `tip`
- `warning`
- `success`


```space-style

.sb-admonition-type::before {
width: var(--admonition-width) !important;
}
.sb-admonition[admonition="abstract"] {
--admonition-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-text" viewBox="0 0 16 16"><path d="M5 4a.5.5 0 0 0 0 1h6a.5.5 0 0 0 0-1zm-.5 2.5A.5.5 0 0 1 5 6h6a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5M5 8a.5.5 0 0 0 0 1h6a.5.5 0 0 0 0-1zm0 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1z"/><path d="M2 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2zm10-1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1"/></svg>');
--admonition-color: dodgerblue;
}

.sb-admonition[admonition="info"] {
--admonition-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"><path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/><path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0"/></svg>');
--admonition-color: turquoise;
}

.sb-admonition[admonition="tip"] {
--admonition-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-fire" viewBox="0 0 16 16"><path d="M8 16c3.314 0 6-2 6-5.5 0-1.5-.5-4-2.5-6 .25 1.5-1.25 2-1.25 2C11 4 9 .5 6 0c.357 2 .5 4-2 6-1.25 1-2 2.729-2 4.5C2 14 4.686 16 8 16m0-1c-1.657 0-3-1-3-2.75 0-.75.25-2 1.25-3C6.125 10 7 10.5 7 10.5c-.375-1.25.5-3.25 2-3.5-.179 1-.25 2 1 3 .625.5 1 1.364 1 2.25C11 14 9.657 15 8 15"/></svg>');
--admonition-color: #00bfa5;
}

.sb-admonition[admonition="success"] {
--admonition-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-lg" viewBox="0 0 16 16"><path d="M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z"/></svg>');
--admonition-color: #00c853;
}

.sb-admonition[admonition="question"] {
--admonition-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-question-circle" viewBox="0 0 16 16"><path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/><path d="M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286m1.557 5.763c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94"/></svg>');
--admonition-color: #64dd17;
}

.sb-admonition[admonition="failure"] {
--admonition-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x-circle" viewBox="0 0 16 16"><path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/><path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708"/></svg>');
--admonition-color: #ff5252;
}

.sb-admonition[admonition="danger"] {
--admonition-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-lightning-fill" viewBox="0 0 16 16"><path d="M5.52.359A.5.5 0 0 1 6 0h4a.5.5 0 0 1 .474.658L8.694 6H12.5a.5.5 0 0 1 .395.807l-7 9a.5.5 0 0 1-.873-.454L6.823 9.5H3.5a.5.5 0 0 1-.48-.641z"/></svg>');
--admonition-color: #ff1744;
}

.sb-admonition[admonition="bug"] {
--admonition-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bug" viewBox="0 0 16 16"><path d="M4.355.522a.5.5 0 0 1 .623.333l.291.956A5 5 0 0 1 8 1c1.007 0 1.946.298 2.731.811l.29-.956a.5.5 0 1 1 .957.29l-.41 1.352A5 5 0 0 1 13 6h.5a.5.5 0 0 0 .5-.5V5a.5.5 0 0 1 1 0v.5A1.5 1.5 0 0 1 13.5 7H13v1h1.5a.5.5 0 0 1 0 1H13v1h.5a1.5 1.5 0 0 1 1.5 1.5v.5a.5.5 0 1 1-1 0v-.5a.5.5 0 0 0-.5-.5H13a5 5 0 0 1-10 0h-.5a.5.5 0 0 0-.5.5v.5a.5.5 0 1 1-1 0v-.5A1.5 1.5 0 0 1 2.5 10H3V9H1.5a.5.5 0 0 1 0-1H3V7h-.5A1.5 1.5 0 0 1 1 5.5V5a.5.5 0 0 1 1 0v.5a.5.5 0 0 0 .5.5H3c0-1.364.547-2.601 1.432-3.503l-.41-1.352a.5.5 0 0 1 .333-.623M4 7v4a4 4 0 0 0 3.5 3.97V7zm4.5 0v7.97A4 4 0 0 0 12 11V7zM12 6a4 4 0 0 0-1.334-2.982A3.98 3.98 0 0 0 8 2a3.98 3.98 0 0 0-2.667 1.018A4 4 0 0 0 4 6z"/></svg>');
--admonition-color: #f50057;
}

.sb-admonition[admonition="example"] {
--admonition-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-vector-pen" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M10.646.646a.5.5 0 0 1 .708 0l4 4a.5.5 0 0 1 0 .708l-1.902 1.902-.829 3.313a1.5 1.5 0 0 1-1.024 1.073L1.254 14.746 4.358 4.4A1.5 1.5 0 0 1 5.43 3.377l3.313-.828zm-1.8 2.908-3.173.793a.5.5 0 0 0-.358.342l-2.57 8.565 8.567-2.57a.5.5 0 0 0 .34-.357l.794-3.174-3.6-3.6z"/><path fill-rule="evenodd" d="M2.832 13.228 8 9a1 1 0 1 0-1-1l-4.228 5.168-.026.086z"/></svg>');
--admonition-color: #7c4dff;
}

.sb-admonition[admonition="quote"] {
--admonition-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-quote" viewBox="0 0 16 16"><path d="M12 12a1 1 0 0 0 1-1V8.558a1 1 0 0 0-1-1h-1.388q0-.527.062-1.054.093-.558.31-.992t.559-.683q.34-.279.868-.279V3q-.868 0-1.52.372a3.3 3.3 0 0 0-1.085.992 4.9 4.9 0 0 0-.62 1.458A7.7 7.7 0 0 0 9 7.558V11a1 1 0 0 0 1 1zm-6 0a1 1 0 0 0 1-1V8.558a1 1 0 0 0-1-1H4.612q0-.527.062-1.054.094-.558.31-.992.217-.434.559-.683.34-.279.868-.279V3q-.868 0-1.52.372a3.3 3.3 0 0 0-1.085.992 4.9 4.9 0 0 0-.62 1.458A7.7 7.7 0 0 0 3 7.558V11a1 1 0 0 0 1 1z"/></svg>');
--admonition-color: #9e9e9e;
}
```

```space-lua
admonitionList={
"note",
"abstract",
"info",
"tip",
"success",
"question",
"warning",
"failure",
"danger",
"bug",
"example",
"quote",
"warning",
"note"
}
for i, v in ipairs(admonitionList) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: I think i can be _ here?

slashcommand.define {
name = "ad-"..v,
description= "admonition for "..v,
run = function()
tpl="> **"..v.."** |^|\n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you indent this nicely?

tpl=tpl.."> \n"
editor.insertAtCursor(tpl, false, true)
end
}
end

```
9 changes: 9 additions & 0 deletions AdmonitionWidget.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this file really be called AdminitionWidget?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure this is 0.x legacy, this "widget" shouldn't do anything and it's misnamed.

description: Adds breadcrumbs
tags: template
hooks.top:
where: 'not pageDecoration.disableTOC'
# Show all the way at the top
order: -1
---
${yg.bc()}
66 changes: 66 additions & 0 deletions Breadcrumbs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Breadcrumbs

With breadcrumbs, you can navigate back through the hierarchy of pages in a hierarchical space. The breadcrumbs are displayed at the top of the page and are clickable.

See [source](https://community.silverbullet.md/t/breadcrumbs-for-hierarchical-pages/737)

```space-lua
yg=yg or {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what yg stands for, and I'm not sure it's useful to expose yg.* publicly. Can these not be local functions or do you see a use case to call this from outside?

yg.t_bc = template.new[==[/[[${name}]] ]==]
yg.t_bcsub = template.new[==[-[[${name}]] ]==]

function yg.breadcrumbs(path)
local mypage = path or editor.getCurrentPage()
local parts = string.split(mypage,"/")
local crumbs = {}
for i,part in ipairs(parts) do
local current = ""
for j=1,i do
if current ~= "" then
current=current.."/"
end
current = current..parts[j]
end
table.insert(crumbs, {name = current})
end
return crumbs
end

function yg.bc(path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bc?

return "[[home]]"..(template.each(yg.breadcrumbs(path),yg.t_bc)).." "..(template.each(yg.children(path),yg.t_bcsub))
end

function compareDate(a, b)
print(a.lastModified > b.lastModified )
return a.lastModified > b.lastModified
end


function yg.children(path)
local crumbsChildren = {}
local mypage = path or editor.getCurrentPage()
for page in each(table.sort(space.listPages(), compareDate)) do
--print(mypage,page.name,string.find(page.name,mypage) )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debug code can go

if (string.find(page.name,mypage) and mypage ~= page.name and #crumbsChildren <7)
then
table.insert(crumbsChildren, {name = page.ref})
end
end
return crumbsChildren
end

-- template
function widgets.breadcrumbs()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So at this level I think it indeed does make sense to extend wigets. 👍🏻 but then I think the yg stuff can all be local to the script.

return widget.new {
markdown = yg.bc()
}
end

event.listen {
name = "hooks:renderTopWidgets",
run = function(e)
return widgets.breadcrumbs()
end
}

```
168 changes: 168 additions & 0 deletions ColorPicker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# Color Picker

The color picker is a widget that allows you to easily select colors from a variety of options. You can use it to change the color of text, backgrounds, borders, or any other color-related CSS property.

The color picker provides a range of color options, including preset colors, a color picker, and a color wheel. You can also enter a color value manually by typing a hex code.

To use the color picker:
1. Open the color picker widget by clicking on the color picker icon in the toolbar.
2. Select a color from the options provided or enter a hex code in the input field.
3. Click on the color you want to use.
4. The selected color will be applied to the selected element.

Note: The color picker only works with CSS properties that support color values.


```space-lua
local function getSelectedtext()
local text = space.readPage(editor.getCurrentPage())
local cursorSelectionRange = editor.getSelection()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

editor.getSelection() gives you also back .text directly, so you don't need to do all of this.


local extractedText = string.sub(text, cursorSelectionRange.from + 1, cursorSelectionRange.to)

return extractedText
end


-- Check if a string is a valid 3- or 6-digit hex color (with or without a leading '#')
local function isHex(s)
local txtMatch = (string.match(s, '^#?[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]$') or string.match(s, '^#?[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]$')) ~= nil
return txtMatch
end

local function expandHex36(hex)
-- Duplicate each character to form the 6-digit code
local r = string.sub(hex, 1, 1)
local g = string.sub(hex, 2, 2)
local b = string.sub(hex, 3, 3)

return r .. r .. g .. g .. b .. b
end



local function openSidePanelWContent(htmlContent)
-- js script to update color value on change
local jsScript = [[
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how I feel about including a whole bunch of JS, but I see why you need this. Alright then :)

const CP_ROOT = "colorp"
const CP_ID = "First"

const COLOR_PICKER_ID = `${CP_ROOT}${CP_ID}`
const COLOR_PICKER_LBL_ID = `${CP_ROOT}${CP_ID}Lbl`
const COLOR_PICKER_ADD_BTN_ID = `${CP_ROOT}AddColor`
const COLOR_PICKER_OL_ID = `${CP_ROOT}List`

const colorPicker = document.getElementById(COLOR_PICKER_ID)
const colorPickerLbl = document.getElementById(COLOR_PICKER_LBL_ID)
const colorPickerList = document.getElementById(COLOR_PICKER_OL_ID)
const addColorBtn = document.getElementById(COLOR_PICKER_ADD_BTN_ID)

var currentColorIndex = 0;
var lastSetColor = colorPickerLbl.innerText;

colorPicker.addEventListener("input", watchColorPicker, false);
colorPicker.addEventListener("change", watchColorPicker, false);
addColorBtn.addEventListener("click", addNewColor, false);

function watchColorPicker(event) {
colorPickerLbl.innerText = event.target.value;
lastSetColor = event.target.value
}

function watchColorPickerAll(event) {
const colorLabelID = event.target.id + "Lbl";
document.getElementById(colorLabelID).innerHTML = " " + event.target.value;
lastSetColor = event.target.value;
}



function addNewColor(event) {
const newColorID = `${CP_ROOT}Li${currentColorIndex}`;
// create list item
var li = document.createElement("li");
var odiv = document.createElement("div");
var colorBtn = document.createElement("input");

colorBtn.type = "color";
colorBtn.id = newColorID;
colorBtn.name = newColorID;
colorBtn.value = lastSetColor;
colorBtn.oninput = watchColorPickerAll;

var colorLbl = document.createElement("label");
colorLbl.id = `${newColorID}Lbl`;
colorLbl.for = newColorID;
colorLbl.innerHTML = " " + lastSetColor;

odiv.appendChild(colorBtn);
odiv.appendChild(colorLbl);

// append div to list item object and update list
li.appendChild(odiv)
colorPickerList.appendChild(li);
currentColorIndex++;
}

]]
-- Inject script and show the html content in the panl
editor.showPanel("rhs", 1, htmlContent, jsScript)
end



local function closeSidePanelWContent()
editor.hidePanel("rhs")
end


local function buildHTMLColorPicker(hex)
local html = "<div>" ..
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What may be nicer is to use spacelua.interpolate (this is a Space Lua specific feature also used in template.new, roughly this should work:

local html = spacelua.interpolate([[<div>
  <input type='color' id='colorpFirst' value=#${hex}>
  <label id='colorpFirstLbl' for='colorpFirst'>#${hex}</label>
]], {hex = hex})

You get the idea, note the ${...} there.

"<input type='color' id='colorpFirst' value=#" .. hex .. ">" ..
"<label id='colorpFirstLbl' for='colorpFirst'>#" .. hex .. "</label>" ..
"<div>" ..
"<button id='colorpAddColor'>Add Color</button>" ..
"<hr/>" ..
"<ol id='colorpList'>" ..
"</ol>" ..
"</div>" ..
"</div>"
return html
end



command.define {
name = "ColorPicker - Show",
key = "Alt-p",
run = function()
local txt = getSelectedtext()
if isHex(txt) then
local hexVal = string.gsub(txt, '^#', '')

if string.len(hexVal) == 3 then
hexVal = expandHex36(hexVal)
end

local html = buildHTMLColorPicker(hexVal)
openSidePanelWContent(html)
editor.flashNotification(hexVal)
else
local defaultHex = "000000"
local html = buildHTMLColorPicker(defaultHex)
openSidePanelWContent(html)
editor.flashNotification(defaultHex)
end
end
}


command.define {
name = "ColorPicker - Hide",
key = "Escape",
run = function()
closeSidePanelWContent()
end
}

```
Loading