Implement space-style (#796)
* Implement space-style * Add reloading styles to System: Reload --------- Co-authored-by: Zef Hemel <zef@zef.me>pull/770/head^2
parent
2705fff52e
commit
95ae722a50
|
@ -1,9 +1,14 @@
|
|||
import { LRLanguage } from "@codemirror/language";
|
||||
import {
|
||||
cLanguage,
|
||||
cmakeLanguage,
|
||||
cppLanguage,
|
||||
csharpLanguage,
|
||||
cssLanguage,
|
||||
dartLanguage,
|
||||
diffLanguage,
|
||||
dockerfileLanguage,
|
||||
goLanguage,
|
||||
htmlLanguage,
|
||||
javaLanguage,
|
||||
javascriptLanguage,
|
||||
|
@ -12,7 +17,9 @@ import {
|
|||
Language,
|
||||
objectiveCLanguage,
|
||||
objectiveCppLanguage,
|
||||
perlLanguage,
|
||||
postgresqlLanguage,
|
||||
powerShellLanguage,
|
||||
protobufLanguage,
|
||||
pythonLanguage,
|
||||
rustLanguage,
|
||||
|
@ -20,19 +27,13 @@ import {
|
|||
shellLanguage,
|
||||
sqlLanguage,
|
||||
StreamLanguage,
|
||||
tclLanguage,
|
||||
tomlLanguage,
|
||||
typescriptLanguage,
|
||||
xmlLanguage,
|
||||
yamlLanguage,
|
||||
goLanguage,
|
||||
diffLanguage,
|
||||
powerShellLanguage,
|
||||
perlLanguage,
|
||||
tclLanguage,
|
||||
verilogLanguage,
|
||||
vhdlLanguage,
|
||||
dockerfileLanguage,
|
||||
cmakeLanguage,
|
||||
xmlLanguage,
|
||||
yamlLanguage,
|
||||
} from "./deps.ts";
|
||||
import {
|
||||
extendedMarkdownLanguage,
|
||||
|
@ -58,7 +59,8 @@ export const builtinLanguages: Record<string, Language> = {
|
|||
"postgres": StreamLanguage.define(postgresqlLanguage),
|
||||
"rust": StreamLanguage.define(rustLanguage),
|
||||
"rs": StreamLanguage.define(rustLanguage),
|
||||
"css": StreamLanguage.define(sqlLanguage),
|
||||
"css": StreamLanguage.define(cssLanguage),
|
||||
"space-style": StreamLanguage.define(cssLanguage),
|
||||
"html": htmlLanguage,
|
||||
"python": StreamLanguage.define(pythonLanguage),
|
||||
"py": StreamLanguage.define(pythonLanguage),
|
||||
|
|
|
@ -94,6 +94,12 @@ export function systemSyscalls(
|
|||
}
|
||||
}
|
||||
},
|
||||
"system.loadSpaceStyles": async () => {
|
||||
if (!client) {
|
||||
throw new Error("Not supported on server");
|
||||
}
|
||||
await client.loadCustomStyles();
|
||||
},
|
||||
"system.invokeSpaceFunction": (_ctx, name: string, ...args: any[]) => {
|
||||
return commonSystem.invokeSpaceFunction(name, args);
|
||||
},
|
||||
|
|
|
@ -132,6 +132,12 @@ functions:
|
|||
events:
|
||||
- page:index
|
||||
|
||||
# Style
|
||||
indexSpaceStyle:
|
||||
path: style.ts:indexSpaceStyle
|
||||
events:
|
||||
- page:index
|
||||
|
||||
# Hashtags
|
||||
indexTags:
|
||||
path: tags.ts:indexTags
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
import { IndexTreeEvent } from "../../plug-api/types.ts";
|
||||
import { collectNodesOfType, findNodeOfType } from "../../plug-api/lib/tree.ts";
|
||||
import { ObjectValue } from "../../plug-api/types.ts";
|
||||
import { indexObjects } from "./api.ts";
|
||||
import { readSetting } from "$sb/lib/settings_page.ts";
|
||||
import { cleanPageRef } from "$sb/lib/resolve.ts";
|
||||
|
||||
export type StyleObject = ObjectValue<{
|
||||
style: string;
|
||||
origin: string;
|
||||
}>;
|
||||
|
||||
export async function indexSpaceStyle({ name, tree }: IndexTreeEvent) {
|
||||
const allStyles: StyleObject[] = [];
|
||||
|
||||
// Also collect CSS from custom styles in settings
|
||||
let customStylePages = await readSetting("customStyles", []);
|
||||
if (!Array.isArray(customStylePages)) {
|
||||
customStylePages = [customStylePages];
|
||||
}
|
||||
customStylePages = customStylePages.map((page: string) => cleanPageRef(page));
|
||||
|
||||
collectNodesOfType(tree, "FencedCode").map((t) => {
|
||||
const codeInfoNode = findNodeOfType(t, "CodeInfo");
|
||||
if (!codeInfoNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fenceType = codeInfoNode.children![0].text!;
|
||||
if (fenceType !== "space-style") {
|
||||
if (
|
||||
!customStylePages.includes(name) || fenceType !== "css"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const codeTextNode = findNodeOfType(t, "CodeText");
|
||||
if (!codeTextNode) {
|
||||
// Honestly, this shouldn't happen
|
||||
return;
|
||||
}
|
||||
const codeText = codeTextNode.children![0].text!;
|
||||
let codeOrigin = "";
|
||||
if (customStylePages.includes(name)) {
|
||||
codeOrigin = "settings";
|
||||
} else if (name.startsWith("Library/")) {
|
||||
codeOrigin = "library";
|
||||
} else {
|
||||
codeOrigin = "user";
|
||||
}
|
||||
|
||||
allStyles.push({
|
||||
ref: `${name}@${t.from!}`,
|
||||
tag: "space-style",
|
||||
style: codeText,
|
||||
origin: codeOrigin,
|
||||
});
|
||||
});
|
||||
|
||||
await indexObjects<StyleObject>(name, allStyles);
|
||||
}
|
|
@ -25,6 +25,7 @@ import type {
|
|||
CompleteEvent,
|
||||
SlashCompletions,
|
||||
} from "../plug-api/types.ts";
|
||||
import { StyleObject } from "../plugs/index/style.ts";
|
||||
import { throttle } from "$lib/async.ts";
|
||||
import { PlugSpacePrimitives } from "$common/spaces/plug_space_primitives.ts";
|
||||
import { EventedSpacePrimitives } from "$common/spaces/evented_space_primitives.ts";
|
||||
|
@ -1095,36 +1096,32 @@ export class Client {
|
|||
}
|
||||
|
||||
async loadCustomStyles() {
|
||||
if (this.settings.customStyles) {
|
||||
const accumulatedCSS: string[] = [];
|
||||
let customStylePages = this.settings.customStyles;
|
||||
if (!Array.isArray(customStylePages)) {
|
||||
customStylePages = [customStylePages];
|
||||
}
|
||||
for (const customStylesPage of customStylePages) {
|
||||
try {
|
||||
const { text: stylesText } = await this.space.readPage(
|
||||
cleanPageRef(customStylesPage),
|
||||
);
|
||||
// Analogous to yamlSettingsRegex in settings.ts
|
||||
const cssBlockRegex = /^(```+|~~~+)css\r?\n([\S\s]+)\1/m;
|
||||
const match = cssBlockRegex.exec(stylesText);
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
accumulatedCSS.push(match[2]);
|
||||
} catch (e: any) {
|
||||
console.error("Failed to load custom styles", e);
|
||||
}
|
||||
}
|
||||
const customStylesContent = accumulatedCSS.join("\n\n");
|
||||
this.ui.viewDispatch({
|
||||
type: "set-ui-option",
|
||||
key: "customStyles",
|
||||
value: customStylesContent,
|
||||
});
|
||||
document.getElementById("custom-styles")!.innerHTML = customStylesContent;
|
||||
const spaceStyles = await this.clientSystem.queryObjects<StyleObject>(
|
||||
"space-style",
|
||||
{},
|
||||
);
|
||||
if (!spaceStyles) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sort stylesheets (last declared styles take precedence)
|
||||
// Order is 1: Imported styles, 2: Other styles, 3: customStyles from Settings
|
||||
const sortOrder = ["library", "user", "settings"];
|
||||
spaceStyles.sort((a, b) =>
|
||||
sortOrder.indexOf(a.origin) - sortOrder.indexOf(b.origin)
|
||||
);
|
||||
|
||||
const accumulatedCSS: string[] = [];
|
||||
for (const s of spaceStyles) {
|
||||
accumulatedCSS.push(s.style);
|
||||
}
|
||||
const customStylesContent = accumulatedCSS.join("\n\n");
|
||||
this.ui.viewDispatch({
|
||||
type: "set-ui-option",
|
||||
key: "customStyles",
|
||||
value: customStylesContent,
|
||||
});
|
||||
document.getElementById("custom-styles")!.innerHTML = customStylesContent;
|
||||
}
|
||||
|
||||
async runCommandByName(name: string, args?: any[]) {
|
||||
|
|
|
@ -66,6 +66,10 @@ export function editorSyscalls(client: Client): SysCallMapping {
|
|||
"system.loadSpaceScripts",
|
||||
[],
|
||||
);
|
||||
await client.clientSystem.system.localSyscall(
|
||||
"system.loadSpaceStyles",
|
||||
[],
|
||||
);
|
||||
},
|
||||
"editor.openUrl": (_ctx, url: string, existingWindow = false) => {
|
||||
if (!existingWindow) {
|
||||
|
|
|
@ -12,5 +12,7 @@ These are the block types that ship with SilverBullet, but [[Plugs]] can define
|
|||
* `query`: [[Live Queries]]
|
||||
* `toc`: [[Table of Contents]]
|
||||
* `embed`: [[Live Embeds]]
|
||||
* `space-script`: [[Space Script]]
|
||||
* `space-style`: [[Space Style]]
|
||||
|
||||
The fenced code block syntax is also used to get [[Markdown/Syntax Highlighting]] for numerous programming languages.
|
|
@ -6,9 +6,9 @@ Silverbullet supports [admonitions](https://github.com/community/community/discu
|
|||
> **warning** This is a
|
||||
> warning admonition
|
||||
|
||||
Custom admonitions can be added in [[STYLES]] using the following format:
|
||||
Custom admonitions can be added in a [[Space Style]] using the following format:
|
||||
|
||||
```css
|
||||
```space-style
|
||||
// Replace the keyword with a word or phrase of your choice
|
||||
.sb-admonition[admonition="keyword"] {
|
||||
// The icon can be a link or an embedded image like shown here
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
This page contains settings for configuring SilverBullet and its Plugs. Changing any of these will go into effect immediately in most cases except `indexPage` and `customStyles`, which require a reload.
|
||||
This page contains settings for configuring SilverBullet and its Plugs. Changing any of these will go into effect immediately in most cases except `indexPage` which requires a reload.
|
||||
|
||||
```yaml
|
||||
# Initial page to load when launching SB, can contain template variables
|
||||
indexPage: "[[SilverBullet]]"
|
||||
|
||||
# Load custom CSS styles from the following page, can also be an array
|
||||
customStyles: "[[STYLES]]"
|
||||
|
||||
# Hide the sync button
|
||||
hideSyncButton: false
|
||||
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
In [[SETTINGS]] you can define a `customStyles` setting that links to a page like this. SilverBullet will load the specified page, find a CSS code block inside that page and load it upon boot (an example can be found below).
|
||||
|
||||
This can be used to achieve various things, such as overriding the default editor font or setting wider page widths. What CSS styles you can override is not very well documented, you’ll have to reverse-engineer things a bit for now, unfortunately.
|
||||
|
||||
```css
|
||||
#sb-root {
|
||||
/* Uncomment the next line to set the editor font to Courier */
|
||||
/* --editor-font: "Courier" !important; */
|
||||
/* Uncomment the next line to set the editor width to 1400px */
|
||||
/* --editor-width: 1400px !important; */
|
||||
}
|
||||
|
||||
/* Choose another header color */
|
||||
#sb-top {
|
||||
/* background-color: #ffe54a !important; */
|
||||
}
|
||||
|
||||
/* You can even change the appearance of buttons */
|
||||
button {
|
||||
/* align-items: center;
|
||||
background-color: #fff;
|
||||
border-radius: 6px;
|
||||
box-shadow: transparent 0 0 0 3px,rgba(18, 18, 18, .1) 0 6px 20px;
|
||||
box-sizing: border-box;
|
||||
color: #121212;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
flex: 1 1 auto;
|
||||
font-family: Inter,sans-serif;
|
||||
font-size: 0.6rem;
|
||||
justify-content: center;
|
||||
line-height: 1;
|
||||
margin: 0.2rem;
|
||||
outline: none;
|
||||
padding: 0.3rem 0.4rem;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
transition: box-shadow .2s,-webkit-box-shadow .2s;
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
touch-action: manipulation; */
|
||||
}
|
||||
|
||||
button:hover {
|
||||
/* box-shadow: #121212 0 0 0 3px, transparent 0 0 0 0; */
|
||||
}
|
||||
```
|
|
@ -0,0 +1,70 @@
|
|||
Space Style is [[Space Script]]‘s stylish sibling. It enables you to add your own styling to SilverBullet with `space-style` [[Blocks]].
|
||||
|
||||
This can be used to achieve various things, such as overriding the default editor font or setting wider page widths. It is also possible to develop custom themes this way.
|
||||
|
||||
To apply the updated styles, either reload the client or run the {[System: Reload]} command.
|
||||
|
||||
Many styles can be set with [variables](https://github.com/silverbulletmd/silverbullet/blob/main/web/styles/theme.scss) but not everything is covered. You’ll have to reverse-engineer those parts, unfortunately.
|
||||
|
||||
# Examples
|
||||
All the actual CSS in these examples is commented out as to not affect this very website.
|
||||
```space-style
|
||||
html {
|
||||
/* Changes to the default theme */
|
||||
/* Such as the accent color */
|
||||
/*--ui-accent-color: #464cfc;*/
|
||||
}
|
||||
|
||||
html[data-theme="dark"] {
|
||||
/* Changes to the dark theme */
|
||||
/*--ui-accent-color: #464cfc;*/
|
||||
}
|
||||
|
||||
html {
|
||||
/* Uncomment the next line to set the editor font to Courier */
|
||||
/* --editor-font: "Courier" !important; */
|
||||
/* Uncomment the next line to set the editor width to 1400px */
|
||||
/* --editor-width: 1400px !important; */
|
||||
}
|
||||
|
||||
/* Choose another header color */
|
||||
html {
|
||||
/*--top-background-color: #eee;*/
|
||||
}
|
||||
/* Or modify the element directly */
|
||||
#sb-top {
|
||||
/*background-color: #eee !important;*/
|
||||
}
|
||||
|
||||
/* You can even change the appearance of buttons */
|
||||
button {
|
||||
/* align-items: center;
|
||||
background-color: #fff;
|
||||
border-radius: 6px;
|
||||
box-shadow: transparent 0 0 0 3px,rgba(18, 18, 18, .1) 0 6px 20px;
|
||||
box-sizing: border-box;
|
||||
color: #121212;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
flex: 1 1 auto;
|
||||
font-family: Inter,sans-serif;
|
||||
font-size: 0.6rem;
|
||||
justify-content: center;
|
||||
line-height: 1;
|
||||
margin: 0.2rem;
|
||||
outline: none;
|
||||
padding: 0.3rem 0.4rem;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
transition: box-shadow .2s,-webkit-box-shadow .2s;
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
touch-action: manipulation; */
|
||||
}
|
||||
|
||||
button:hover {
|
||||
/* box-shadow: #121212 0 0 0 3px, transparent 0 0 0 0; */
|
||||
}
|
||||
```
|
|
@ -1,6 +1,6 @@
|
|||
Dark theme, originally [shared here](https://discord.com/channels/1028543811191836782/1028543811984568373/1141715540755361833). Make sure you switch SilverBullet to {[Editor: Toggle Dark Mode|dark mode]} to use.
|
||||
|
||||
```css
|
||||
```space-style
|
||||
html[data-theme="dark"], html[data-theme="dark"]{
|
||||
--root-background-color: rgba(30,33,38,255);
|
||||
--root-color: rgba(255,255,255,0.6);
|
||||
|
|
Loading…
Reference in New Issue