From 4147bf68891a685b8c401b4918693e06e092eff0 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 6 Feb 2024 10:02:32 +0000 Subject: [PATCH 1/9] docs: added @pascalwilbrink's guide for plugin development --- .../How-to-write-a-plugin-for-OpenSCD.md | 229 ++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 collections/_guides/How-to-write-a-plugin-for-OpenSCD.md diff --git a/collections/_guides/How-to-write-a-plugin-for-OpenSCD.md b/collections/_guides/How-to-write-a-plugin-for-OpenSCD.md new file mode 100644 index 0000000..ca9933a --- /dev/null +++ b/collections/_guides/How-to-write-a-plugin-for-OpenSCD.md @@ -0,0 +1,229 @@ + + +# How to write a plugin for OpenSCD + +This tutorial will explain on how to write a plugin for OpenSCD. + +## Prerequisites +* Node ( LTS) +* Git +* An IDE + +In this example, we will use the Lit framework ([https://lit.dev](https://lit.dev)) to create a plugin for OpenSCD. On top of the Lit framework, we make use of the standards provided by Open Web Components ([open-wc.org](https://open-wc.org/)). + +# TOC +* Scaffolding a new plugin +* Setting up property injection +* Choosing the plugin type +* Adding functionality to the plugin + + +## Scaffolding a new plugin +We can scaffold a new empty project by using the `@open-wc` init command. + +```bash +npm init @open-wc +``` +--- + +When prompted, choose the following: + +`What would you like to do today?` › Scaffold a new project + +`What would you like to scaffold?` › Web Component + +`What would you like to add?` › Linting (eslint & prettier), Testing (web-test-runner), Demoing (storybook) + +`Would you like to use typescript?` › Yes + +`What is the tag name of your web component?` › oscd-my-new-plugin + +--- + +After scaffolding is complete, the first thing that we need to do is to change the plugin class. + +Open the `OscdMyNewPlugin.ts` file in the `src` folder and change the following line: + +```diff +- export class OscdMyNewPlugin extends LitElement { ++ export default class OscdMyNewPlugin extends LitElement { +``` + +> Note the `default` keyword. + +--- + +Now, the `src/oscd-my-new-plugin.ts` file needs to be changed: + +```diff +- import { OscdMyNewPlugin } from './OscdMyNewPlugin.js'; ++ import OscdMyNewPlugin from './OscdMyNewPlugin.js'; +``` + +> Note the removed brackets + +--- + +The last thing we have to change, is the `src/index.ts` file. + +```diff +- export { OscdMyNewPlugin } from './OscdMyNewPlugin.js'; ++ export * from './OscdMyNewPlugin.js'; +``` + +> Note the asterisk on export + +--- + +This change is making sure that the plugin is default exported, so that OpenSCD can dynamically import it correctly. + +## Setting up property injection +In order to start displaying or editing the SCL file, we first need to add properties that will be injected into the plugin. + +Inside the `OscdMyNewPlugin.ts` file, add the following code: + +```TypeScript +import { html, css, LitElement } from 'lit'; +import { property } from 'lit/decorators.js'; + +export default class OscdMyNewPlugin extends LitElement { + + @property({ type: Object }) + doc!: XMLDocument; + + @property({ type: Number }) + editCount = -1; + + @property({ type: String }) + locale!: string; + + ... +``` + +These properties will be injected into the Plugin from the OpenSCD host. + +## Choosing the Plugin type +OpenSCD currently supports 2 different plugin types. +* Menu type plugins +* Editor type plugins + +### Menu type plugins +--- +Menu type plugins usually run on the background. They are displayed in the sidebar menu and are rendered at all times. +Example of menu type plugins are: +* Validators +* Generators + +### Editor type plugins +--- +Editor type plugins are displayed in the main Editor. An editor type plugin will be rendered when it's being activated by the Tab bar on top of OpenSCD. +Examples of editor type plugins are: +* Communication editor +* Substation editor +* Single Line Diagram + +If you choose to make your plugin a Menu type plugin, you need to implement the `run` method in your plugin. + +```TypeScript +import { html, css, LitElement } from 'lit'; +import { property } from 'lit/decorators.js'; + +export default class OscdMyNewPlugin extends LitElement { + + @property({ type: Object }) + doc!: XMLDocument; + + @property({ type: Number }) + editCount = -1; + + @property({ type: String }) + locale!: string; + + async run(): Promise { + ... Plugin implementation goes here + } +``` + +If you choose to make your plugin an Editor type plugin, you need to implement the `render` function from Lit. + +```TypeScript +import { html, css, LitElement, TemplateResult } from 'lit'; +import { property } from 'lit/decorators.js'; + +export default class OscdMyNewPlugin extends LitElement { + + @property({ type: Object }) + doc!: XMLDocument; + + @property({ type: Number }) + editCount = -1; + + @property({ type: String }) + locale!: string; + + render(): TemplateResult { + return html`
My plugin works!
`; + } +``` + +In this example, we'll choose for an editor type plugin. + +## Adding functionality to the plugin + +The SCL document can be traversed like any other HTMLElement. +Let's say you want to list all the SubStations inside the plugin. +You can do so by using + +```TypeScript +Array.from(doc.querySelectorAll('Substation')).map((substation) => substation.getAttribute('name')); +``` + +```TypeScript +import { html, css, LitElement, TemplateResult } from 'lit'; +import { property } from 'lit/decorators.js'; + +export default class OscdMyNewPlugin extends LitElement { + + @property({ type: Object }) + doc!: XMLDocument; + + @property({ type: Number }) + editCount = -1; + + @property({ type: String }) + locale!: string; + + renderSubstationNames(): TemplateResult { + return html``; + } + + render(): TemplateResult { + return html`
${this.renderSubstationNames()}
`; + } +``` + +You can make the plugin as simple or difficult as you want. + + +## Building the plugin +After implementing your logic in the plugin, it's time to build the plugin. +Thankfully, the Open-WC standard provides us with npm scripts to easily build the plugin. + + +```bash +npm run build +``` +The script above creates the build output which can be hosted on GitHub for example. Just copy over the build directory and you're good to go. + +--- + +And that's it! You just successfully created and built a plugin that can be used with OpenSCD. + +In a different guide, we will cover more advanced things, like editing the SCL file. + +> If you're looking for the full code of this guide, [you can find it here](https://github.com/openscd/oscd-plugin-template). This repository also has templates for other frameworks. From 29271b4a2417d66f09ad12d41fabfdf7e9c2afb7 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 6 Feb 2024 10:09:22 +0000 Subject: [PATCH 2/9] chore: adding front matter and updating markdown file name --- ...How-to-write-a-plugin-for-OpenSCD.md => plugin-guide.md} | 6 ++++++ 1 file changed, 6 insertions(+) rename collections/_guides/{How-to-write-a-plugin-for-OpenSCD.md => plugin-guide.md} (97%) diff --git a/collections/_guides/How-to-write-a-plugin-for-OpenSCD.md b/collections/_guides/plugin-guide.md similarity index 97% rename from collections/_guides/How-to-write-a-plugin-for-OpenSCD.md rename to collections/_guides/plugin-guide.md index ca9933a..c3a4904 100644 --- a/collections/_guides/How-to-write-a-plugin-for-OpenSCD.md +++ b/collections/_guides/plugin-guide.md @@ -1,3 +1,9 @@ +--- +layout: guide +title: "How to write a plugin for OpenSCD" +name: "How to write a plugin for OpenSCD" +summary: "Brief tutorial explaining how to write a plugin for OpenSCD" +--- # How to write a plugin for OpenSCD From a2a1705525ce8a16d92788a38cd07b3c394253d1 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 6 Feb 2024 10:22:59 +0000 Subject: [PATCH 3/9] chore: styling the guides layout --- _layouts/guide.html | 20 +- assets/css/github-markdown.css | 1195 ++++++++++++++++++++++++++++++++ 2 files changed, 1211 insertions(+), 4 deletions(-) create mode 100644 assets/css/github-markdown.css diff --git a/_layouts/guide.html b/_layouts/guide.html index 2a4931b..8709cae 100644 --- a/_layouts/guide.html +++ b/_layouts/guide.html @@ -2,16 +2,28 @@ {% include head.html %} + + {% include header.html %}
-
- {{ page.name }} -
-
+
{{ page.content }}
diff --git a/assets/css/github-markdown.css b/assets/css/github-markdown.css new file mode 100644 index 0000000..d32a314 --- /dev/null +++ b/assets/css/github-markdown.css @@ -0,0 +1,1195 @@ +@media (prefers-color-scheme: dark) { + .markdown-body, + [data-theme="dark"] { + /*dark*/ + color-scheme: dark; + --color-prettylights-syntax-comment: #8b949e; + --color-prettylights-syntax-constant: #79c0ff; + --color-prettylights-syntax-entity: #d2a8ff; + --color-prettylights-syntax-storage-modifier-import: #c9d1d9; + --color-prettylights-syntax-entity-tag: #7ee787; + --color-prettylights-syntax-keyword: #ff7b72; + --color-prettylights-syntax-string: #a5d6ff; + --color-prettylights-syntax-variable: #ffa657; + --color-prettylights-syntax-brackethighlighter-unmatched: #f85149; + --color-prettylights-syntax-invalid-illegal-text: #f0f6fc; + --color-prettylights-syntax-invalid-illegal-bg: #8e1519; + --color-prettylights-syntax-carriage-return-text: #f0f6fc; + --color-prettylights-syntax-carriage-return-bg: #b62324; + --color-prettylights-syntax-string-regexp: #7ee787; + --color-prettylights-syntax-markup-list: #f2cc60; + --color-prettylights-syntax-markup-heading: #1f6feb; + --color-prettylights-syntax-markup-italic: #c9d1d9; + --color-prettylights-syntax-markup-bold: #c9d1d9; + --color-prettylights-syntax-markup-deleted-text: #ffdcd7; + --color-prettylights-syntax-markup-deleted-bg: #67060c; + --color-prettylights-syntax-markup-inserted-text: #aff5b4; + --color-prettylights-syntax-markup-inserted-bg: #033a16; + --color-prettylights-syntax-markup-changed-text: #ffdfb6; + --color-prettylights-syntax-markup-changed-bg: #5a1e02; + --color-prettylights-syntax-markup-ignored-text: #c9d1d9; + --color-prettylights-syntax-markup-ignored-bg: #1158c7; + --color-prettylights-syntax-meta-diff-range: #d2a8ff; + --color-prettylights-syntax-brackethighlighter-angle: #8b949e; + --color-prettylights-syntax-sublimelinter-gutter-mark: #484f58; + --color-prettylights-syntax-constant-other-reference-link: #a5d6ff; + --color-fg-default: #e6edf3; + --color-fg-muted: #848d97; + --color-fg-subtle: #6e7681; + --color-canvas-default: #0d1117; + --color-canvas-subtle: #161b22; + --color-border-default: #30363d; + --color-border-muted: #21262d; + --color-neutral-muted: rgba(110,118,129,0.4); + --color-accent-fg: #2f81f7; + --color-accent-emphasis: #1f6feb; + --color-success-fg: #3fb950; + --color-success-emphasis: #238636; + --color-attention-fg: #d29922; + --color-attention-emphasis: #9e6a03; + --color-attention-subtle: rgba(187,128,9,0.15); + --color-danger-fg: #f85149; + --color-danger-emphasis: #da3633; + --color-done-fg: #a371f7; + --color-done-emphasis: #8957e5; + } +} + +@media (prefers-color-scheme: light) { + .markdown-body, + [data-theme="light"] { + /*light*/ + color-scheme: light; + --color-prettylights-syntax-comment: #57606a; + --color-prettylights-syntax-constant: #0550ae; + --color-prettylights-syntax-entity: #6639ba; + --color-prettylights-syntax-storage-modifier-import: #24292f; + --color-prettylights-syntax-entity-tag: #116329; + --color-prettylights-syntax-keyword: #cf222e; + --color-prettylights-syntax-string: #0a3069; + --color-prettylights-syntax-variable: #953800; + --color-prettylights-syntax-brackethighlighter-unmatched: #82071e; + --color-prettylights-syntax-invalid-illegal-text: #f6f8fa; + --color-prettylights-syntax-invalid-illegal-bg: #82071e; + --color-prettylights-syntax-carriage-return-text: #f6f8fa; + --color-prettylights-syntax-carriage-return-bg: #cf222e; + --color-prettylights-syntax-string-regexp: #116329; + --color-prettylights-syntax-markup-list: #3b2300; + --color-prettylights-syntax-markup-heading: #0550ae; + --color-prettylights-syntax-markup-italic: #24292f; + --color-prettylights-syntax-markup-bold: #24292f; + --color-prettylights-syntax-markup-deleted-text: #82071e; + --color-prettylights-syntax-markup-deleted-bg: #ffebe9; + --color-prettylights-syntax-markup-inserted-text: #116329; + --color-prettylights-syntax-markup-inserted-bg: #dafbe1; + --color-prettylights-syntax-markup-changed-text: #953800; + --color-prettylights-syntax-markup-changed-bg: #ffd8b5; + --color-prettylights-syntax-markup-ignored-text: #eaeef2; + --color-prettylights-syntax-markup-ignored-bg: #0550ae; + --color-prettylights-syntax-meta-diff-range: #8250df; + --color-prettylights-syntax-brackethighlighter-angle: #57606a; + --color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f; + --color-prettylights-syntax-constant-other-reference-link: #0a3069; + --color-fg-default: #1F2328; + --color-fg-muted: #656d76; + --color-fg-subtle: #6e7781; + --color-canvas-default: #ffffff; + --color-canvas-subtle: #f6f8fa; + --color-border-default: #d0d7de; + --color-border-muted: hsla(210,18%,87%,1); + --color-neutral-muted: rgba(175,184,193,0.2); + --color-accent-fg: #0969da; + --color-accent-emphasis: #0969da; + --color-success-fg: #1a7f37; + --color-success-emphasis: #1f883d; + --color-attention-fg: #9a6700; + --color-attention-emphasis: #9a6700; + --color-attention-subtle: #fff8c5; + --color-danger-fg: #d1242f; + --color-danger-emphasis: #cf222e; + --color-done-fg: #8250df; + --color-done-emphasis: #8250df; + } +} + +.markdown-body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + margin: 0; + color: var(--color-fg-default); + background-color: var(--color-canvas-default); + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; + font-size: 16px; + line-height: 1.5; + word-wrap: break-word; +} + +.markdown-body .octicon { + display: inline-block; + fill: currentColor; + vertical-align: text-bottom; +} + +.markdown-body h1:hover .anchor .octicon-link:before, +.markdown-body h2:hover .anchor .octicon-link:before, +.markdown-body h3:hover .anchor .octicon-link:before, +.markdown-body h4:hover .anchor .octicon-link:before, +.markdown-body h5:hover .anchor .octicon-link:before, +.markdown-body h6:hover .anchor .octicon-link:before { + width: 16px; + height: 16px; + content: ' '; + display: inline-block; + background-color: currentColor; + -webkit-mask-image: url("data:image/svg+xml,"); + mask-image: url("data:image/svg+xml,"); +} + +.markdown-body details, +.markdown-body figcaption, +.markdown-body figure { + display: block; +} + +.markdown-body summary { + display: list-item; +} + +.markdown-body [hidden] { + display: none !important; +} + +.markdown-body a { + background-color: transparent; + color: var(--color-accent-fg); + text-decoration: none; +} + +.markdown-body abbr[title] { + border-bottom: none; + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +.markdown-body b, +.markdown-body strong { + font-weight: var(--base-text-weight-semibold, 600); +} + +.markdown-body dfn { + font-style: italic; +} + +.markdown-body h1 { + margin: .67em 0; + font-weight: var(--base-text-weight-semibold, 600); + padding-bottom: .3em; + font-size: 2em; + border-bottom: 1px solid var(--color-border-muted); +} + +.markdown-body mark { + background-color: var(--color-attention-subtle); + color: var(--color-fg-default); +} + +.markdown-body small { + font-size: 90%; +} + +.markdown-body sub, +.markdown-body sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +.markdown-body sub { + bottom: -0.25em; +} + +.markdown-body sup { + top: -0.5em; +} + +.markdown-body img { + border-style: none; + max-width: 100%; + box-sizing: content-box; + background-color: var(--color-canvas-default); +} + +.markdown-body code, +.markdown-body kbd, +.markdown-body pre, +.markdown-body samp { + font-family: monospace; + font-size: 1em; +} + +.markdown-body figure { + margin: 1em 40px; +} + +.markdown-body hr { + box-sizing: content-box; + overflow: hidden; + background: transparent; + border-bottom: 1px solid var(--color-border-muted); + height: .25em; + padding: 0; + margin: 24px 0; + background-color: var(--color-border-default); + border: 0; +} + +.markdown-body input { + font: inherit; + margin: 0; + overflow: visible; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +.markdown-body [type=button], +.markdown-body [type=reset], +.markdown-body [type=submit] { + -webkit-appearance: button; + appearance: button; +} + +.markdown-body [type=checkbox], +.markdown-body [type=radio] { + box-sizing: border-box; + padding: 0; +} + +.markdown-body [type=number]::-webkit-inner-spin-button, +.markdown-body [type=number]::-webkit-outer-spin-button { + height: auto; +} + +.markdown-body [type=search]::-webkit-search-cancel-button, +.markdown-body [type=search]::-webkit-search-decoration { + -webkit-appearance: none; + appearance: none; +} + +.markdown-body ::-webkit-input-placeholder { + color: inherit; + opacity: .54; +} + +.markdown-body ::-webkit-file-upload-button { + -webkit-appearance: button; + appearance: button; + font: inherit; +} + +.markdown-body a:hover { + text-decoration: underline; +} + +.markdown-body ::placeholder { + color: var(--color-fg-subtle); + opacity: 1; +} + +.markdown-body hr::before { + display: table; + content: ""; +} + +.markdown-body hr::after { + display: table; + clear: both; + content: ""; +} + +.markdown-body table { + border-spacing: 0; + border-collapse: collapse; + display: block; + width: max-content; + max-width: 100%; + overflow: auto; +} + +.markdown-body td, +.markdown-body th { + padding: 0; +} + +.markdown-body details summary { + cursor: pointer; +} + +.markdown-body details:not([open])>*:not(summary) { + display: none !important; +} + +.markdown-body a:focus, +.markdown-body [role=button]:focus, +.markdown-body input[type=radio]:focus, +.markdown-body input[type=checkbox]:focus { + outline: 2px solid var(--color-accent-fg); + outline-offset: -2px; + box-shadow: none; +} + +.markdown-body a:focus:not(:focus-visible), +.markdown-body [role=button]:focus:not(:focus-visible), +.markdown-body input[type=radio]:focus:not(:focus-visible), +.markdown-body input[type=checkbox]:focus:not(:focus-visible) { + outline: solid 1px transparent; +} + +.markdown-body a:focus-visible, +.markdown-body [role=button]:focus-visible, +.markdown-body input[type=radio]:focus-visible, +.markdown-body input[type=checkbox]:focus-visible { + outline: 2px solid var(--color-accent-fg); + outline-offset: -2px; + box-shadow: none; +} + +.markdown-body a:not([class]):focus, +.markdown-body a:not([class]):focus-visible, +.markdown-body input[type=radio]:focus, +.markdown-body input[type=radio]:focus-visible, +.markdown-body input[type=checkbox]:focus, +.markdown-body input[type=checkbox]:focus-visible { + outline-offset: 0; +} + +.markdown-body kbd { + display: inline-block; + padding: 3px 5px; + font: 11px ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace; + line-height: 10px; + color: var(--color-fg-default); + vertical-align: middle; + background-color: var(--color-canvas-subtle); + border: solid 1px var(--color-neutral-muted); + border-bottom-color: var(--color-neutral-muted); + border-radius: 6px; + box-shadow: inset 0 -1px 0 var(--color-neutral-muted); +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 24px; + margin-bottom: 16px; + font-weight: var(--base-text-weight-semibold, 600); + line-height: 1.25; +} + +.markdown-body h2 { + font-weight: var(--base-text-weight-semibold, 600); + padding-bottom: .3em; + font-size: 1.5em; + border-bottom: 1px solid var(--color-border-muted); +} + +.markdown-body h3 { + font-weight: var(--base-text-weight-semibold, 600); + font-size: 1.25em; +} + +.markdown-body h4 { + font-weight: var(--base-text-weight-semibold, 600); + font-size: 1em; +} + +.markdown-body h5 { + font-weight: var(--base-text-weight-semibold, 600); + font-size: .875em; +} + +.markdown-body h6 { + font-weight: var(--base-text-weight-semibold, 600); + font-size: .85em; + color: var(--color-fg-muted); +} + +.markdown-body p { + margin-top: 0; + margin-bottom: 10px; +} + +.markdown-body blockquote { + margin: 0; + padding: 0 1em; + color: var(--color-fg-muted); + border-left: .25em solid var(--color-border-default); +} + +.markdown-body ul, +.markdown-body ol { + margin-top: 0; + margin-bottom: 0; + padding-left: 2em; +} + +.markdown-body ol ol, +.markdown-body ul ol { + list-style-type: lower-roman; +} + +.markdown-body ul ul ol, +.markdown-body ul ol ol, +.markdown-body ol ul ol, +.markdown-body ol ol ol { + list-style-type: lower-alpha; +} + +.markdown-body dd { + margin-left: 0; +} + +.markdown-body tt, +.markdown-body code, +.markdown-body samp { + font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace; + font-size: 12px; +} + +.markdown-body pre { + margin-top: 0; + margin-bottom: 0; + font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace; + font-size: 12px; + word-wrap: normal; +} + +.markdown-body .octicon { + display: inline-block; + overflow: visible !important; + vertical-align: text-bottom; + fill: currentColor; +} + +.markdown-body input::-webkit-outer-spin-button, +.markdown-body input::-webkit-inner-spin-button { + margin: 0; + -webkit-appearance: none; + appearance: none; +} + +.markdown-body .mr-2 { + margin-right: var(--base-size-8, 8px) !important; +} + +.markdown-body::before { + display: table; + content: ""; +} + +.markdown-body::after { + display: table; + clear: both; + content: ""; +} + +.markdown-body>*:first-child { + margin-top: 0 !important; +} + +.markdown-body>*:last-child { + margin-bottom: 0 !important; +} + +.markdown-body a:not([href]) { + color: inherit; + text-decoration: none; +} + +.markdown-body .absent { + color: var(--color-danger-fg); +} + +.markdown-body .anchor { + float: left; + padding-right: 4px; + margin-left: -20px; + line-height: 1; +} + +.markdown-body .anchor:focus { + outline: none; +} + +.markdown-body p, +.markdown-body blockquote, +.markdown-body ul, +.markdown-body ol, +.markdown-body dl, +.markdown-body table, +.markdown-body pre, +.markdown-body details { + margin-top: 0; + margin-bottom: 16px; +} + +.markdown-body blockquote>:first-child { + margin-top: 0; +} + +.markdown-body blockquote>:last-child { + margin-bottom: 0; +} + +.markdown-body h1 .octicon-link, +.markdown-body h2 .octicon-link, +.markdown-body h3 .octicon-link, +.markdown-body h4 .octicon-link, +.markdown-body h5 .octicon-link, +.markdown-body h6 .octicon-link { + color: var(--color-fg-default); + vertical-align: middle; + visibility: hidden; +} + +.markdown-body h1:hover .anchor, +.markdown-body h2:hover .anchor, +.markdown-body h3:hover .anchor, +.markdown-body h4:hover .anchor, +.markdown-body h5:hover .anchor, +.markdown-body h6:hover .anchor { + text-decoration: none; +} + +.markdown-body h1:hover .anchor .octicon-link, +.markdown-body h2:hover .anchor .octicon-link, +.markdown-body h3:hover .anchor .octicon-link, +.markdown-body h4:hover .anchor .octicon-link, +.markdown-body h5:hover .anchor .octicon-link, +.markdown-body h6:hover .anchor .octicon-link { + visibility: visible; +} + +.markdown-body h1 tt, +.markdown-body h1 code, +.markdown-body h2 tt, +.markdown-body h2 code, +.markdown-body h3 tt, +.markdown-body h3 code, +.markdown-body h4 tt, +.markdown-body h4 code, +.markdown-body h5 tt, +.markdown-body h5 code, +.markdown-body h6 tt, +.markdown-body h6 code { + padding: 0 .2em; + font-size: inherit; +} + +.markdown-body summary h1, +.markdown-body summary h2, +.markdown-body summary h3, +.markdown-body summary h4, +.markdown-body summary h5, +.markdown-body summary h6 { + display: inline-block; +} + +.markdown-body summary h1 .anchor, +.markdown-body summary h2 .anchor, +.markdown-body summary h3 .anchor, +.markdown-body summary h4 .anchor, +.markdown-body summary h5 .anchor, +.markdown-body summary h6 .anchor { + margin-left: -40px; +} + +.markdown-body summary h1, +.markdown-body summary h2 { + padding-bottom: 0; + border-bottom: 0; +} + +.markdown-body ul.no-list, +.markdown-body ol.no-list { + padding: 0; + list-style-type: none; +} + +.markdown-body ol[type="a s"] { + list-style-type: lower-alpha; +} + +.markdown-body ol[type="A s"] { + list-style-type: upper-alpha; +} + +.markdown-body ol[type="i s"] { + list-style-type: lower-roman; +} + +.markdown-body ol[type="I s"] { + list-style-type: upper-roman; +} + +.markdown-body ol[type="1"] { + list-style-type: decimal; +} + +.markdown-body div>ol:not([type]) { + list-style-type: decimal; +} + +.markdown-body ul ul, +.markdown-body ul ol, +.markdown-body ol ol, +.markdown-body ol ul { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body li>p { + margin-top: 16px; +} + +.markdown-body li+li { + margin-top: .25em; +} + +.markdown-body dl { + padding: 0; +} + +.markdown-body dl dt { + padding: 0; + margin-top: 16px; + font-size: 1em; + font-style: italic; + font-weight: var(--base-text-weight-semibold, 600); +} + +.markdown-body dl dd { + padding: 0 16px; + margin-bottom: 16px; +} + +.markdown-body table th { + font-weight: var(--base-text-weight-semibold, 600); +} + +.markdown-body table th, +.markdown-body table td { + padding: 6px 13px; + border: 1px solid var(--color-border-default); +} + +.markdown-body table td>:last-child { + margin-bottom: 0; +} + +.markdown-body table tr { + background-color: var(--color-canvas-default); + border-top: 1px solid var(--color-border-muted); +} + +.markdown-body table tr:nth-child(2n) { + background-color: var(--color-canvas-subtle); +} + +.markdown-body table img { + background-color: transparent; +} + +.markdown-body img[align=right] { + padding-left: 20px; +} + +.markdown-body img[align=left] { + padding-right: 20px; +} + +.markdown-body .emoji { + max-width: none; + vertical-align: text-top; + background-color: transparent; +} + +.markdown-body span.frame { + display: block; + overflow: hidden; +} + +.markdown-body span.frame>span { + display: block; + float: left; + width: auto; + padding: 7px; + margin: 13px 0 0; + overflow: hidden; + border: 1px solid var(--color-border-default); +} + +.markdown-body span.frame span img { + display: block; + float: left; +} + +.markdown-body span.frame span span { + display: block; + padding: 5px 0 0; + clear: both; + color: var(--color-fg-default); +} + +.markdown-body span.align-center { + display: block; + overflow: hidden; + clear: both; +} + +.markdown-body span.align-center>span { + display: block; + margin: 13px auto 0; + overflow: hidden; + text-align: center; +} + +.markdown-body span.align-center span img { + margin: 0 auto; + text-align: center; +} + +.markdown-body span.align-right { + display: block; + overflow: hidden; + clear: both; +} + +.markdown-body span.align-right>span { + display: block; + margin: 13px 0 0; + overflow: hidden; + text-align: right; +} + +.markdown-body span.align-right span img { + margin: 0; + text-align: right; +} + +.markdown-body span.float-left { + display: block; + float: left; + margin-right: 13px; + overflow: hidden; +} + +.markdown-body span.float-left span { + margin: 13px 0 0; +} + +.markdown-body span.float-right { + display: block; + float: right; + margin-left: 13px; + overflow: hidden; +} + +.markdown-body span.float-right>span { + display: block; + margin: 13px auto 0; + overflow: hidden; + text-align: right; +} + +.markdown-body code, +.markdown-body tt { + padding: .2em .4em; + margin: 0; + font-size: 85%; + white-space: break-spaces; + background-color: var(--color-neutral-muted); + border-radius: 6px; +} + +.markdown-body code br, +.markdown-body tt br { + display: none; +} + +.markdown-body del code { + text-decoration: inherit; +} + +.markdown-body samp { + font-size: 85%; +} + +.markdown-body pre code { + font-size: 100%; +} + +.markdown-body pre>code { + padding: 0; + margin: 0; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; +} + +.markdown-body .highlight { + margin-bottom: 16px; +} + +.markdown-body .highlight pre { + margin-bottom: 0; + word-break: normal; +} + +.markdown-body .highlight pre, +.markdown-body pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + color: var(--color-fg-default); + background-color: var(--color-canvas-subtle); + border-radius: 6px; +} + +.markdown-body pre code, +.markdown-body pre tt { + display: inline; + max-width: auto; + padding: 0; + margin: 0; + overflow: visible; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; +} + +.markdown-body .csv-data td, +.markdown-body .csv-data th { + padding: 5px; + overflow: hidden; + font-size: 12px; + line-height: 1; + text-align: left; + white-space: nowrap; +} + +.markdown-body .csv-data .blob-num { + padding: 10px 8px 9px; + text-align: right; + background: var(--color-canvas-default); + border: 0; +} + +.markdown-body .csv-data tr { + border-top: 0; +} + +.markdown-body .csv-data th { + font-weight: var(--base-text-weight-semibold, 600); + background: var(--color-canvas-subtle); + border-top: 0; +} + +.markdown-body [data-footnote-ref]::before { + content: "["; +} + +.markdown-body [data-footnote-ref]::after { + content: "]"; +} + +.markdown-body .footnotes { + font-size: 12px; + color: var(--color-fg-muted); + border-top: 1px solid var(--color-border-default); +} + +.markdown-body .footnotes ol { + padding-left: 16px; +} + +.markdown-body .footnotes ol ul { + display: inline-block; + padding-left: 16px; + margin-top: 16px; +} + +.markdown-body .footnotes li { + position: relative; +} + +.markdown-body .footnotes li:target::before { + position: absolute; + top: -8px; + right: -8px; + bottom: -8px; + left: -24px; + pointer-events: none; + content: ""; + border: 2px solid var(--color-accent-emphasis); + border-radius: 6px; +} + +.markdown-body .footnotes li:target { + color: var(--color-fg-default); +} + +.markdown-body .footnotes .data-footnote-backref g-emoji { + font-family: monospace; +} + +.markdown-body .pl-c { + color: var(--color-prettylights-syntax-comment); +} + +.markdown-body .pl-c1, +.markdown-body .pl-s .pl-v { + color: var(--color-prettylights-syntax-constant); +} + +.markdown-body .pl-e, +.markdown-body .pl-en { + color: var(--color-prettylights-syntax-entity); +} + +.markdown-body .pl-smi, +.markdown-body .pl-s .pl-s1 { + color: var(--color-prettylights-syntax-storage-modifier-import); +} + +.markdown-body .pl-ent { + color: var(--color-prettylights-syntax-entity-tag); +} + +.markdown-body .pl-k { + color: var(--color-prettylights-syntax-keyword); +} + +.markdown-body .pl-s, +.markdown-body .pl-pds, +.markdown-body .pl-s .pl-pse .pl-s1, +.markdown-body .pl-sr, +.markdown-body .pl-sr .pl-cce, +.markdown-body .pl-sr .pl-sre, +.markdown-body .pl-sr .pl-sra { + color: var(--color-prettylights-syntax-string); +} + +.markdown-body .pl-v, +.markdown-body .pl-smw { + color: var(--color-prettylights-syntax-variable); +} + +.markdown-body .pl-bu { + color: var(--color-prettylights-syntax-brackethighlighter-unmatched); +} + +.markdown-body .pl-ii { + color: var(--color-prettylights-syntax-invalid-illegal-text); + background-color: var(--color-prettylights-syntax-invalid-illegal-bg); +} + +.markdown-body .pl-c2 { + color: var(--color-prettylights-syntax-carriage-return-text); + background-color: var(--color-prettylights-syntax-carriage-return-bg); +} + +.markdown-body .pl-sr .pl-cce { + font-weight: bold; + color: var(--color-prettylights-syntax-string-regexp); +} + +.markdown-body .pl-ml { + color: var(--color-prettylights-syntax-markup-list); +} + +.markdown-body .pl-mh, +.markdown-body .pl-mh .pl-en, +.markdown-body .pl-ms { + font-weight: bold; + color: var(--color-prettylights-syntax-markup-heading); +} + +.markdown-body .pl-mi { + font-style: italic; + color: var(--color-prettylights-syntax-markup-italic); +} + +.markdown-body .pl-mb { + font-weight: bold; + color: var(--color-prettylights-syntax-markup-bold); +} + +.markdown-body .pl-md { + color: var(--color-prettylights-syntax-markup-deleted-text); + background-color: var(--color-prettylights-syntax-markup-deleted-bg); +} + +.markdown-body .pl-mi1 { + color: var(--color-prettylights-syntax-markup-inserted-text); + background-color: var(--color-prettylights-syntax-markup-inserted-bg); +} + +.markdown-body .pl-mc { + color: var(--color-prettylights-syntax-markup-changed-text); + background-color: var(--color-prettylights-syntax-markup-changed-bg); +} + +.markdown-body .pl-mi2 { + color: var(--color-prettylights-syntax-markup-ignored-text); + background-color: var(--color-prettylights-syntax-markup-ignored-bg); +} + +.markdown-body .pl-mdr { + font-weight: bold; + color: var(--color-prettylights-syntax-meta-diff-range); +} + +.markdown-body .pl-ba { + color: var(--color-prettylights-syntax-brackethighlighter-angle); +} + +.markdown-body .pl-sg { + color: var(--color-prettylights-syntax-sublimelinter-gutter-mark); +} + +.markdown-body .pl-corl { + text-decoration: underline; + color: var(--color-prettylights-syntax-constant-other-reference-link); +} + +.markdown-body g-emoji { + display: inline-block; + min-width: 1ch; + font-family: "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; + font-size: 1em; + font-style: normal !important; + font-weight: var(--base-text-weight-normal, 400); + line-height: 1; + vertical-align: -0.075em; +} + +.markdown-body g-emoji img { + width: 1em; + height: 1em; +} + +.markdown-body .task-list-item { + list-style-type: none; +} + +.markdown-body .task-list-item label { + font-weight: var(--base-text-weight-normal, 400); +} + +.markdown-body .task-list-item.enabled label { + cursor: pointer; +} + +.markdown-body .task-list-item+.task-list-item { + margin-top: 4px; +} + +.markdown-body .task-list-item .handle { + display: none; +} + +.markdown-body .task-list-item-checkbox { + margin: 0 .2em .25em -1.4em; + vertical-align: middle; +} + +.markdown-body .contains-task-list:dir(rtl) .task-list-item-checkbox { + margin: 0 -1.6em .25em .2em; +} + +.markdown-body .contains-task-list { + position: relative; +} + +.markdown-body .contains-task-list:hover .task-list-item-convert-container, +.markdown-body .contains-task-list:focus-within .task-list-item-convert-container { + display: block; + width: auto; + height: 24px; + overflow: visible; + clip: auto; +} + +.markdown-body ::-webkit-calendar-picker-indicator { + filter: invert(50%); +} + +.markdown-body .markdown-alert { + padding: var(--base-size-8) var(--base-size-16); + margin-bottom: 16px; + color: inherit; + border-left: .25em solid var(--color-border-default); +} + +.markdown-body .markdown-alert>:first-child { + margin-top: 0; +} + +.markdown-body .markdown-alert>:last-child { + margin-bottom: 0; +} + +.markdown-body .markdown-alert .markdown-alert-title { + display: flex; + font-weight: var(--base-text-weight-medium, 500); + align-items: center; + line-height: 1; +} + +.markdown-body .markdown-alert.markdown-alert-note { + border-left-color: var(--color-accent-emphasis); +} + +.markdown-body .markdown-alert.markdown-alert-note .markdown-alert-title { + color: var(--color-accent-fg); +} + +.markdown-body .markdown-alert.markdown-alert-important { + border-left-color: var(--color-done-emphasis); +} + +.markdown-body .markdown-alert.markdown-alert-important .markdown-alert-title { + color: var(--color-done-fg); +} + +.markdown-body .markdown-alert.markdown-alert-warning { + border-left-color: var(--color-attention-emphasis); +} + +.markdown-body .markdown-alert.markdown-alert-warning .markdown-alert-title { + color: var(--color-attention-fg); +} + +.markdown-body .markdown-alert.markdown-alert-tip { + border-left-color: var(--color-success-emphasis); +} + +.markdown-body .markdown-alert.markdown-alert-tip .markdown-alert-title { + color: var(--color-success-fg); +} + +.markdown-body .markdown-alert.markdown-alert-caution { + border-left-color: var(--color-danger-emphasis); +} + +.markdown-body .markdown-alert.markdown-alert-caution .markdown-alert-title { + color: var(--color-danger-fg); +} From af080c54154c71f5095f443fe77a4d7092624e3d Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 6 Feb 2024 10:52:19 +0000 Subject: [PATCH 4/9] chore: removing bg color and updated margin for content guide --- _layouts/guide.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_layouts/guide.html b/_layouts/guide.html index 8709cae..233f935 100644 --- a/_layouts/guide.html +++ b/_layouts/guide.html @@ -8,7 +8,7 @@ box-sizing: border-box; min-width: 200px; max-width: 980px; - margin: 0 auto; + margin: 45px auto; padding: 45px; } From 757fe414b9308b9bb8c036cbab4780da3f3de0b7 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 6 Feb 2024 12:20:26 +0000 Subject: [PATCH 5/9] chore: adding glossary --- _includes/header.html | 4 ++-- pages/glossary.md | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 pages/glossary.md diff --git a/_includes/header.html b/_includes/header.html index 3c0e30e..92fc84c 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -26,8 +26,8 @@

  • - - Sub Item 3 + > + Glossary
  • diff --git a/pages/glossary.md b/pages/glossary.md new file mode 100644 index 0000000..6ba96f5 --- /dev/null +++ b/pages/glossary.md @@ -0,0 +1,39 @@ +--- +layout: default +title: Glossary +subtitle: OpenSCD Glossary +cover: solar +--- + +# OpenSCD Glossary + +This glossary introduces terms that have been developed and collectively endorsed by the OpenSCD community. Please note that terms specific to the SCL (Substation Configuration Language) fall outside the scope of this glossary, as they are thoroughly covered and explained by the relevant IEC standards; The goal of the glossary is helping to get a common understanding of the terms introduced into the OpenSCD project, with the aim of enhancing communication. + +## Wizard +A wizard is a user-friendly interface that assists individuals in completing complicated tasks by breaking them into simpler, easy-to-follow steps. It typically offers guidance, instructions, and choices, making tasks more manageable and enabling users to accomplish them efficiently. + +## Plug-in +An OpenSCD plug-in allows to extend OpenSCD functionality. E.g. support vendeor/organisational specific needs. It's crafted to seamlessly merge with the main OpenSCD-core API, broadening its capabilities without altering its fundamental structure. OpenSCD-core incorporates a selected set of plug-ins and settings (e.g. color scheme) to enhance its functionality. + +## Distribution +An OpenSCD distirbution is openSCD-core with a set of user/organsition selected plug-ins, styling and other environmental variables. An OpenSCD distribution allows to meet organisation/user needs. E.g. selection of open source and 3rd party plug-ins or the useage of organisation colors. + +## Validator plug-in +The primary role of Validator plug-in is to ensure that the information provided meets certain criteria or requirements. In the context of our tool, this plug-in is essential for validating the IEC 61850 SCL file that's either created or modified by the tool. It acts as a quality checker, ensuring the integrity and compliance of the SCL file according to specified guidelines or standards. + +## Menu plug-in +Menu Plug-in in OpenSCD refers to the functionalities accessible directly from the main menu of the tool. These options perform specific tasks within the tool without necessarily adding a new module or plug-in to the workspace. For instance: + +- **Save Project:** Saves the current project. +- **Open Project:** Opens an existing project. +- **Create Virtual IED:** Adds a new IED (Intelligent Electronic Device). + +These options facilitate essential tasks within OpenSCD without altering the tool's interface or adding new components to the workspace. + + +## Editor plug-in +**Editor Plug-ins** in OpenSCD are accessed through the Extensions section in the Menu. These plug-ins, found in the Editor tab of the Extensions section, are responsible for adding or removing modules within the tool's workspace. For instance: **IED**, **Substation** and **Single Line Diagram** plug-ins. + +Editor Plug-ins extend the functionality of OpenSCD by adding modules or components to the workspace, providing users with additional tools and features for more specialized tasks or configurations. + + From fe796dfe41b652bf6e4e530a8f1889107ad55698 Mon Sep 17 00:00:00 2001 From: Juan Munoz Date: Tue, 6 Feb 2024 12:23:58 +0000 Subject: [PATCH 6/9] chore: fix broken glossary link --- _includes/header.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/header.html b/_includes/header.html index 92fc84c..fe81877 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -26,7 +26,7 @@

  • - > + Glossary
  • From a3e4d29930fe0f906bb4845aa55032beae158159 Mon Sep 17 00:00:00 2001 From: Pascal Wilbrink Date: Mon, 12 Feb 2024 15:32:36 +0100 Subject: [PATCH 7/9] Feat: Update CSS --- _config.yml | 6 +- _includes/head.html | 1 - _layouts/guide.html | 9 +- _plugins/reading_time_filter.rb | 55 ++++++ assets/css/_syntax.scss | 261 +++++++++++++++++++++++++++ assets/css/components.css | 4 +- assets/css/components/card.css | 46 +++++ assets/css/components/toc.css | 34 ++++ assets/css/github-markdown.css | 2 +- assets/css/layout.css | 17 ++ assets/css/main.css | 9 +- assets/css/pages.css | 3 + assets/css/syntax.css | 70 +++++++ assets/sass/_syntax.scss | 261 +++++++++++++++++++++++++++ collections/_guides/create_plugin.md | 232 ++++++++++++++++++++++++ docker-compose.yml | 2 +- index.html | 4 +- pages/glossary.md | 1 + pages/guides.md | 26 +-- 19 files changed, 1017 insertions(+), 26 deletions(-) create mode 100644 _plugins/reading_time_filter.rb create mode 100644 assets/css/_syntax.scss create mode 100644 assets/css/components/card.css create mode 100644 assets/css/components/toc.css create mode 100644 assets/css/syntax.css create mode 100644 assets/sass/_syntax.scss create mode 100644 collections/_guides/create_plugin.md diff --git a/_config.yml b/_config.yml index 78764c5..bc1cd35 100644 --- a/_config.yml +++ b/_config.yml @@ -11,8 +11,8 @@ description: > # this means to ignore newlines until "baseurl:" Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description. -baseurl: "/Documentation" # the subpath of your site, e.g. /blog -url: "https://openscd.github.io" # the base hostname & protocol for your site +#baseurl: "/Documentation" # the subpath of your site, e.g. /blog +#url: "https://openscd.github.io" # the base hostname & protocol for your site collections_dir: collections # Markdown settings @@ -27,7 +27,7 @@ toc: ordered_list: false no_toc_section_class: no_toc_section list_id: toc - list_class: section-nav + list_class: nav--toc sublist_class: '' item_class: toc-entry item_prefix: toc- diff --git a/_includes/head.html b/_includes/head.html index 0b7f0cb..ed5cfc6 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -2,7 +2,6 @@ - {% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %} diff --git a/_layouts/guide.html b/_layouts/guide.html index 233f935..f8393a9 100644 --- a/_layouts/guide.html +++ b/_layouts/guide.html @@ -20,18 +20,21 @@ {% include header.html %} -
    +