From e29eda5f044a732cc3be75f2c84910570a925a99 Mon Sep 17 00:00:00 2001 From: wass Date: Sat, 18 May 2024 15:35:56 +0200 Subject: [PATCH] sync with astro-big-doc added astro home control screenshot --- astro.config.mjs | 7 +- config.js | 9 ++- content/home/readme.md | 2 +- content/web/astro-home-control.png | Bin 0 -> 35536 bytes content/web/astro-home.md | 10 +++ integrations/create_menu.js | 66 ++++-------------- package.json | 6 +- src/components/markdown/Link.astro | 18 +++-- src/components/markdown/code/Code.astro | 18 ++--- .../markdown/code/DiagramCode.astro | 6 +- .../markdown/code/Highlighter.astro | 3 +- src/components/markdown/code/LinkCode.astro | 29 ++++++++ src/components/markdown/code/Mermaid.astro | 23 ------ src/components/markdown/code/MermaidCli.astro | 30 -------- src/components/markdown/code/Plantuml.astro | 24 ------- src/components/markdown/code/kroki.yaml | 20 ++++++ src/components/panzoom/panzoom.js | 50 ++++++++++--- src/libs/assets.js | 22 +++++- src/libs/client_utils.js | 2 +- src/pages/[...url].astro | 2 +- src/pages/assets/[...path].js | 5 +- src/pages/codes/[...path].js | 23 ++++-- src/pages/index.astro | 8 ++- 23 files changed, 203 insertions(+), 180 deletions(-) create mode 100644 content/web/astro-home-control.png create mode 100644 src/components/markdown/code/LinkCode.astro delete mode 100644 src/components/markdown/code/Mermaid.astro delete mode 100644 src/components/markdown/code/MermaidCli.astro delete mode 100644 src/components/markdown/code/Plantuml.astro create mode 100644 src/components/markdown/code/kroki.yaml diff --git a/astro.config.mjs b/astro.config.mjs index cecb33e..b7d332a 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,12 +1,15 @@ import { defineConfig } from 'astro/config'; import {config} from './config.js' import {collect_content} from './integrations/integration-content-structure.js' - +import yaml from '@rollup/plugin-yaml'; export default defineConfig({ integrations: [collect_content(config.collect_content)], output: "static", outDir: config.outDir, base: config.base, - trailingSlash: 'ignore' + trailingSlash: 'ignore', + vite: { + plugins: [yaml()] + } }); diff --git a/config.js b/config.js index 4b768b2..0952c3b 100644 --- a/config.js +++ b/config.js @@ -7,8 +7,8 @@ const rootdir = process.cwd() const outdir = (process.env.OUT_DIR==null)?"dist":process.env.OUT_DIR const base = (process.env.PUBLIC_BASE==null)?"":process.env.PUBLIC_BASE -const contentdir = join(rootdir,"content") -const structuredir = join(rootdir,".structure") +const structuredir = (process.env.STRUCTURE==null)?join(rootdir,".structure"):process.env.STRUCTURE +const contentdir = (process.env.CONTENT==null)?join(rootdir,"content"):process.env.CONTENT const config = { rootdir: rootdir, @@ -16,7 +16,6 @@ const config = { base: base, content_path: contentdir, code_path: `${rootdir}/${outdir}/codes`, - plantuml_server: "https://www.plantuml.com/plantuml/svg", kroki_server: "https://kroki.io", client_menu:true, highlighter:{ @@ -32,8 +31,8 @@ config.collect_content = { rootdir:config.rootdir, contentdir:contentdir, content_ext:["md"], - assets_ext:["svg","webp","png","jpeg","jpg","xlsx","glb","hdr","ico"], - outdir:structuredir, + assets_ext:["svg","webp","png","jpeg","jpg","xlsx","glb","hdr","ico","puml"], + outdir:structuredir,//dist does not persist before build out_menu:"public/menu.json",//used by src\layout\client_nav_menu.js debug:false } diff --git a/content/home/readme.md b/content/home/readme.md index 2d5dd46..e0aaacb 100644 --- a/content/home/readme.md +++ b/content/home/readme.md @@ -1,5 +1,5 @@ --- -title : Smart Home Hardware Software Development +title: Home description: Home Automation Frameworks, Microcontrollers, Wireless Networks, Applications, with tutorials and references to the documentation of protocol standards and hardware manufacturers date: 2020-10-06T08:48:23+00:00 lastmod: 2021-02-14T08:00:00+00:00 diff --git a/content/web/astro-home-control.png b/content/web/astro-home-control.png new file mode 100644 index 0000000000000000000000000000000000000000..039a47701d75ec25b5648684c4e5cee69d7e3299 GIT binary patch literal 35536 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
Rz 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 WEeE+0=>_cO7r46q%@Wl+PyP#Jqb}+I literal 0 HcmV?d00001 diff --git a/content/web/astro-home.md b/content/web/astro-home.md index e69de29..d886e24 100644 --- a/content/web/astro-home.md +++ b/content/web/astro-home.md @@ -0,0 +1,10 @@ +# Astro Home Control + +* Home Automation MQTT Client running on Astro as SSR +* Client page update with Server Sent Events +* Custom switches with feedback and custom sliders with animated SVG + +:button[]{label="Github repo" link="https://github.com/MicroWebStacks/astro-home-control" icon="github"} + +![screenshot](./astro-home-control.png) + diff --git a/integrations/create_menu.js b/integrations/create_menu.js index 3622c48..ce1f5a2 100644 --- a/integrations/create_menu.js +++ b/integrations/create_menu.js @@ -1,29 +1,11 @@ -import {dirname, join} from 'path' -import { exists, load_yaml, load_yaml_abs,save_json } from '../src/libs/utils.js'; +import {join} from 'path' +import { exists, load_json_abs, load_yaml_abs,save_json } from '../src/libs/utils.js'; import { section_from_pathname,add_base } from '../src/libs/assets.js'; import {pages_list_to_tree} from './process_menu.js' import {getDocuments} from 'content-structure' import {createHash} from 'crypto' import { config } from '../config.js'; -import { readdir, stat } from 'fs/promises'; -import path from 'path'; - -function content_entry_to_level(entry){ - const base_level = 1 - let level = 0 - const directory = dirname(entry.path) - if(directory != ""){ - //console.log(directory.split('/')) - const path_level = directory.split('/').length - if(entry.url_type == "file"){ - level = base_level + path_level + 1 - }else{ - level = base_level + path_level - } - } - //console.log(`level:(${level}) path:${entry.path}`) - return level -} +import {dirname} from 'path'; async function get_section_menu(section,raw_menu){ let result_items = [] @@ -41,8 +23,8 @@ async function get_section_menu(section,raw_menu){ path: entry.path, url: entry.url, url_type: entry.url_type, + level: entry.level, link:(dir != ".")?`${config.base}/${entry.url}`:`${config.base}/${section}/${entry.url}`, - level:content_entry_to_level(entry), format: entry.format, order: Object.hasOwn(entry,"order")?entry.order:100 } @@ -64,42 +46,23 @@ async function get_section_menu(section,raw_menu){ return result_items } -async function create_raw_menu(content_path){ - const items = await readdir(content_path, { withFileTypes: true }); - const directories = items.filter(dirent => dirent.isDirectory()); - // Map the directories to your desired structure - const structure = directories.map(dir => ({ - label: dir.name.charAt(0).toUpperCase() + dir.name.slice(1), - link: `/${dir.name}`, +async function create_raw_menu(content_path,document_list){ + const top_items = document_list.filter((item)=> item.level === 2).sort((a,b)=> a.order-b.order) + const sorted_items = top_items.map(entry => ({ + label: entry.title, + link: `/${entry.url}`, autogenerate: { - directory: dir.name + directory: dirname(entry.path) } })); - let homeIndex = -1; - const homeStructure = structure.map((entry, index) => { - if (entry.link === "/home") { - homeIndex = index; // Capture the index of the modified entry - return { - label: entry.label, - link: "/" - }; - } - return entry; - }); - - // If "/home" was modified, move it to the beginning of the array - if (homeIndex !== -1) { - const [homeEntry] = homeStructure.splice(homeIndex, 1); // Remove the entry - homeStructure.unshift(homeEntry); // Unshift to the beginning - } - + const home_items = sorted_items.map(item => item.link === '/home' ? { ...item, link: '/' } : item); const icons_file = join(content_path,"icons.yaml") if(await exists(icons_file)){ const icons_list = await load_yaml_abs(icons_file) - homeStructure.push(...icons_list) + home_items.push(...icons_list) } - return homeStructure; + return home_items; } async function create_menu(collect_config){ @@ -108,7 +71,8 @@ async function create_menu(collect_config){ if(await exists(menu_file)){ raw_menu = await load_yaml_abs(menu_file) }else{ - raw_menu = await create_raw_menu(join(collect_config.contentdir)) + const document_list = await load_json_abs(join(collect_config.outdir,"document_list.json")) + raw_menu = await create_raw_menu(collect_config.contentdir,document_list) } const base_menu = JSON.parse(JSON.stringify(raw_menu)) for(let menu_entry of base_menu){ diff --git a/package.json b/package.json index 42ffafd..6c826ec 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "@google/model-viewer": "^3.4.0", "@svgdotjs/svg.js": "^3.1.2", "astro": "^4.5.10", - "content-structure": "^1.1.1", + "content-structure": "^1.1.8", "cookie-parser": "^1.4.6", "cors": "^2.8.5", "datatables.net-dt": "^1.13.7", @@ -31,7 +31,6 @@ "passport": "^0.6.0", "passport-github": "^1.1.0", "photoswipe": "^5.4.3", - "plantuml-encoder": "^1.4.0", "remark": "^15.0.1", "sharp": "^0.33.0", "shikiji": "^0.6.10", @@ -42,5 +41,8 @@ }, "engines": { "pnpm": ">=8.0.0" + }, + "devDependencies": { + "@rollup/plugin-yaml": "^4.1.2" } } diff --git a/src/components/markdown/Link.astro b/src/components/markdown/Link.astro index 84c59d3..0adf576 100644 --- a/src/components/markdown/Link.astro +++ b/src/components/markdown/Link.astro @@ -1,9 +1,11 @@ --- -import {relAssetToUrl} from '@/libs/assets.js' +import {relAssetToUrl, file_ext} from '@/libs/assets.js' import {toHast} from 'mdast-util-to-hast' import {toHtml} from 'hast-util-to-html' import ModelViewer from './model/ModelViewer.astro'; import TableXLSX from './table/TableXLSX.astro'; +import LinkCode from './code/LinkCode.astro'; +import kroki from './code/kroki.yaml' export interface Props { node: object; @@ -20,9 +22,13 @@ if(!external){ src = await relAssetToUrl(node.url,dirpath) } } -const is_model3d = node.url.endsWith(".glb") -const is_table = node.url.endsWith(".xlsx") -const is_link = !is_model3d && !is_table + +const ext = file_ext(node.url) + +const is_model3d = (ext === "glb") +const is_table = (ext === "xlsx") +const is_diagram = Object.keys(kroki.formats).includes(ext) +const is_link = !is_model3d && !is_table && !is_diagram let title = "" if((node.children.length>0)&&(node.children[0].type == "text")){ title = node.children[0].value @@ -42,7 +48,9 @@ if((node.children.length>0)&&(node.children[0].type == "text")){ ))} } - +{is_diagram && + +}