Update doc preview infrastructure (#2444)

* Update doc preview infrastructure

Align the used NodeJS and Ruby versions and scripts with the website build.
Also upgrade caniuse-lite DB.

Signed-off-by: Florian Hotze <florianh_dev@icloud.com>

* Add NodeJS/Ruby install instructions

Signed-off-by: Florian Hotze <florianh_dev@icloud.com>

* switch sentence with local preview sentence

Signed-off-by: Stefan Höhn <mail@stefanhoehn.com>

---------

Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
Signed-off-by: Stefan Höhn <mail@stefanhoehn.com>
Co-authored-by: Stefan Höhn <mail@stefanhoehn.com>
pull/2445/head
Florian Hotze 2025-01-06 12:16:05 +01:00 committed by GitHub
parent a27d468310
commit 82a24a4826
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 504 additions and 532 deletions

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
16.20.1

1
.ruby-version Normal file
View File

@ -0,0 +1 @@
3.3.2

View File

@ -1,7 +1,7 @@
# This function will add placeholders for pages that are out of scope of the docs preview
def add_placeholder_pages()
puts ">>> Adding placeholder pages for preview"
puts "➡️ Adding placeholder pages for preview"
[
"addons/integrations/homekit",
"addons/integrations/openhabcloud",
@ -19,7 +19,7 @@ def add_placeholder_pages()
"docs/ecosystem/mycroft",
"docs/installation/openhabian.md"
].each { |path|
puts " -> #{path}"
puts " ➡️ #{path}"
page = path
if (!(path =~ /\.md/)) then
FileUtils.mkdir_p(path)

View File

@ -1,207 +1,169 @@
# This function converts a "source" file to something looking good in VuePress,
# adding, replacing and stuff
# frozen_string_literal: true
require "fileutils"
require "net/http"
require "uri"
require "rexml/document"
# This function converts a "source" file to something looking good in VuePress
def process_file(indir, file, outdir, source)
in_frontmatter = false
frontmatter_processed = false
has_source = false
has_logo = false
obsolete_binding = false
og_title = 'openHAB'
og_description = 'a vendor and technology agnostic open source automation software for your home'
in_frontmatter = false
frontmatter_processed = false
has_source = false
has_logo = false
since_1x = false
obsolete_binding = false
og_title = "openHAB"
og_description = "a vendor and technology agnostic open source automation software for your home"
if !File.exists?("#{indir}/#{file}") then
puts "process_file: IGNORING (NON-EXISTING): #{indir}/#{file}"
return
unless File.exist?("#{indir}/#{file}")
verbose "process_file: IGNORING (NON-EXISTING): #{indir}/#{file}"
return
end
FileUtils.mkdir_p(outdir)
File.open("#{outdir}/#{file}", "w+") do |out|
File.open("#{indir}/#{file}").each do |line|
next if line =~ /^layout: documentation/
next if line =~ /^layout: tutorial/
next if line =~ /^layout: developers/
next if line =~ /^layout: intro/
next if line =~ /^{% include base.html %}/
next if line =~ /\{: #/
next if line =~ /\{::options/
next if line =~ /TOC/
next if line =~ /no_toc/
has_source = true if in_frontmatter && line =~ /^source:/
has_logo = true if in_frontmatter && line =~ /^logo:/
since_1x = true if in_frontmatter && line =~ /^since: 1x/
og_title = line.gsub("title: ", "").gsub("\n", "") if in_frontmatter && line =~ /^title:/
if in_frontmatter && line =~ /^description:/
og_description = line.gsub("description: ", "").gsub("\n", "").gsub("[", "").gsub("]", "").gsub(
%r{\(http[:/\-0-9A-Za-z\.]+\)}, ""
)
end
if line =~ /^---$/
if !in_frontmatter
in_frontmatter = true
elsif !frontmatter_processed
if !has_source && source
# Prefer already present source
out.puts "source: #{source}"
elsif !has_source
# Try to determine the source
outdir_parts = outdir.split("/")
outdir_parts[1] = "binding" if outdir_parts[1] == "bindings"
outdir_parts[1] = "transform" if outdir_parts[1] == "transformations"
outdir_parts[1] = "io" if outdir_parts[1] == "integrations"
if outdir_parts[0] == "addons"
addon_type = outdir_parts[1]
addon = file.split("/")[0]
source = ""
if addon_type == "ui"
puts " (add-on type is ui)"
source = "https://github.com/openhab/openhab-webui/blob/#{$addons_repo_branch}/bundles/org.openhab.ui.#{addon}/README.md"
elsif addon == "zigbee"
puts " (add-on is zigbee)"
source = "https://github.com/openhab/org.openhab.binding.zigbee/blob/#{$addons_repo_branch}/org.openhab.binding.zigbee/README.md"
elsif addon == "zwave" && file !~ /things/
puts " (add-on is zwave)"
source = "https://github.com/openhab/org.openhab.binding.zwave/blob/#{$addons_repo_branch}/README.md"
elsif file !~ /things/
source = "https://github.com/openhab/openhab-addons/blob/#{$addons_repo_branch}/bundles/org.openhab.#{addon_type}.#{addon}/README.md"
end
out.puts "source: #{source}" if source != ""
# For sub-bundles, set the "prev" link to the main add-on
out.puts "prev: ../#{addon.split(".")[0]}/" if addon.include?(".")
# Prev link to the main binding doc for zwave/doc/things.md
out.puts "prev: ../" if file == "zwave/doc/things.md"
end
end
# Add OpenGraph tags
out.puts "meta:"
out.puts " - property: og:title"
out.puts " content: \"#{og_title.gsub('"', '\"')}\""
out.puts " - property: og:description"
out.puts " content: #{og_description}"
in_frontmatter = false
frontmatter_processed = true
end
end
# Remove collapsibles in Linux install document and replace them by regular headings
next if line =~ /include collapsible/ && file =~ /linux/
line = "##### #{line}" if line =~ /^Apt Based Systems/ && file =~ /linux/
line = "##### #{line}" if line =~ /^Yum or Dnf Based Systems/ && file =~ /linux/
line = "##### #{line}" if line =~ /^Systems based on/ && file =~ /linux/
# Expand <!--list-subs--> comments with a list of links
# (https://github.com/eclipse/smarthome/issues/5571)
if line =~ /<!--\s*list-subs\s*-->/
sub_addons = get_subs_links(file.split("/")[0], indir)
out.puts
sub_addons.each do |sub|
out.puts "- [#{sub[1]}](../#{sub[0]}/)"
end
out.puts
end
# Replace links to generated docs in ZWave's things.md by links to the internal viewer
line = line.gsub(%r{]\((.*)/(.*)\)}, '](../thing.html?manufacturer=\1&file=\2)') if file == "zwave/doc/things.md"
# Misc replaces (relative links, remove placeholder interpreted as custom tags)
line = line.gsub("http://docs.openhab.org/addons/uis/habpanel/readme.html", "/docs/configuration/habpanel.html")
line = line.gsub("http://docs.openhab.org/addons/uis/basic/readme.html", "/addons/ui/basic/")
line = line.gsub(%r{http://docs\.openhab\.org/addons/(.*)/(.*)/readme\.html}, '/addons/\1/\2/')
line = line.gsub("http://docs.openhab.org/", "/docs/")
line = line.gsub("/addons/io/", "/addons/integrations/")
line = line.gsub("{{base}}/", "./docs/")
line = line.gsub("(images/", "(./images/")
line = line.gsub("src=\"images/", "src=\"./images/")
line = line.gsub("]:images/", "]:./images/")
line = line.gsub("](doc/", "](./doc/")
line = line.gsub("(diagrams/", "(./diagrams/")
line = line.gsub("./docs/tutorials/beginner/", "/docs/tutorial/")
line = line.gsub("./docs/", "/docs/")
line = line.gsub("<activeState>", '\<activeState\>')
line = line.gsub("<passiveState>", '\<passiveState\>')
line = line.gsub("(?<!`)<dimension>(?!`)", '\<dimension\>')
line = line.gsub("<TransformProgram>", '\<TransformProgram\>')
line = line.gsub("<FlahshbriefingDeviceID>", "`<FlahshbriefingDeviceID>`") if file =~ /amazonechocontrol/
line = line.gsub("<SerialNumber>", "&lt;SerialNumber&gt;") if file =~ /airvisualnode/
line = line.gsub("<version>", "&lt;version&gt;") if file =~ /caldav/
line = line.gsub("by <step>", "by `<step>`") if file =~ /ipx8001/
line = line.gsub("<BR>", "<BR/>")
line = line.gsub("'<package name>:<widget ID>'", "`<package name>:<widget ID>`") if file =~ /lametrictime/
line = line.gsub("<mac address of bridge>", "`<mac address of bridge>`") if file =~ /milight/
line = line.gsub("<mac>", "`<mac>`") if file =~ /milight/
line = line.gsub("<type of bulb>", "`<type of bulb>`") if file =~ /milight/
line = line.gsub("<IP-Address of bridge>", "`<IP-Address of bridge>`") if file =~ /milight/
line = line.gsub("<bulb>", "`<bulb>`") if file =~ /milight/
line = line.gsub("<zone>", "`<zone>`") if file =~ /milight/
line = line.gsub("[](", "[here](") if file =~ /powermax1/
line = line.gsub("<n>", "&lt;n&gt;") if file =~ /rfxcom/
line = line.gsub(" <value> ", " &lt;value&gt; ") if file =~ /zibase/
line = line.gsub("<username>", "&lt;username&gt;") if file =~ /zoneminder/
line = line.gsub("<password>", "&lt;password&gt;") if file =~ /zoneminder/
line = line.gsub("<yourzmip>", "&lt;yourzmip&gt;") if file =~ /zoneminder/
line = line.gsub(" <chatId> ", " &lt;chatId&gt; ") if file =~ /telegram/
line = line.gsub(" <token> ", " &lt;token&gt; ") if file =~ /telegram/
line = line.gsub("<regular expression>", '\<regular expression\>')
line = line.gsub('src="images/', 'src="./images/') if outdir =~ /apps/
line = line.gsub("](/images/", "](./images/") if outdir =~ /google-assistant/
line = line.gsub(/\{:(style|target).*\}/, "") # Jekyll inline attributes syntax not supported
out.puts line
end
FileUtils.mkdir_p(outdir)
File.open("#{outdir}/#{file}", "w+") { |out|
File.open("#{indir}/#{file}").each { |line|
next if line =~ /^layout: documentation/
next if line =~ /^layout: tutorial/
next if line =~ /^layout: developers/
next if line =~ /^layout: intro/
next if line =~ /^{% include base.html %}/
next if line =~ /\{: #/
next if line =~ /\{::options/
next if line =~ /TOC/
next if line =~ /no_toc/
has_source = true if in_frontmatter && line =~ /^source:/
has_logo = true if in_frontmatter && line =~ /^logo:/
if in_frontmatter && line =~ /^title:/ then
og_title = line.gsub('title: ', '').gsub("\n", "")
end
if in_frontmatter && line =~ /^description:/ then
og_description = line.gsub('description: ', '').gsub("\n", "").gsub('[', '').gsub(']', '').gsub(/\(http[:\/\-0-9A-Za-z\.]+\)/, '')
end
if line =~ /^---$/ then
if !in_frontmatter then
in_frontmatter = true
elsif !frontmatter_processed
if !has_source && source then
# Prefer already present source
out.puts "source: #{source}"
elsif !has_source
# Try to determine the source
outdir_parts = outdir.split('/')
outdir_parts[1] = "binding" if outdir_parts[1] == "bindings"
outdir_parts[1] = "transform" if outdir_parts[1] == "transformations"
outdir_parts[1] = "io" if outdir_parts[1] == "integrations"
if (outdir_parts[0] == "addons") then
addon_type = outdir_parts[1]
addon = file.split('/')[0]
source = ""
if addon == "habpanel" then
puts " (add-on is habpanel)"
source = "https://github.com/openhab/openhab-webui/blob/main/bundles/org.openhab.ui.habpanel/README.md"
elsif addon == "zigbee" then
puts " (add-on is zigbee)"
source = "https://github.com/openhab/org.openhab.binding.zigbee/blob/main/org.openhab.binding.zigbee/README.md"
elsif addon == "zwave" && !(file =~ /things/) then
puts " (add-on is zwave)"
source = "https://github.com/openhab/org.openhab.binding.zwave/blob/main/README.md"
elsif !(file =~ /things/) then
puts " (add-on is from openhab-addons)"
source = "https://github.com/openhab/openhab-addons/blob/main/addons/#{addon_type}/org.openhab.#{addon_type}.#{addon}/README.md"
end
out.puts "source: #{source}" if source != ""
# For sub-bundles, set the "prev" link to the main add-on
out.puts "prev: ../#{addon.split('.')[0]}/" if addon.include?('.')
# Prev link to the main binding doc for zwave/doc/things.md
out.puts "prev: ../" if file == 'zwave/doc/things.md'
end
end
# Add OpenGraph tags
out.puts "meta:"
out.puts " - property: og:title"
out.puts " content: \"#{og_title.gsub('"', '\"')}\""
out.puts " - property: og:description"
out.puts " content: #{og_description}"
in_frontmatter = false
frontmatter_processed = true
end
end
# Replace the Jekyll "contribution wanted" include file by custom VuePress markup
line = "[[toc]]" if line =~ /\{:toc/
if line =~ /\{% include contribution-wanted.html %\}/
out.puts "::: tip Contribution Wanted"
out.puts "Please help us improve the documentation! "
out.puts "If you'd like to leave corrections, additions or comments for this article or any other part of this website, please drop a word at:"
out.puts "[Documentation Issue Tracker](#{$docs_repo}/issues)"
out.puts ":::"
next
end
# Remove collapsibles in Linux install document and replace them by regular headings
next if line =~ /include collapsible/ && file =~ /linux/
line = "##### " + line if line =~ /^Apt Based Systems/ && file =~ /linux/
line = "##### " + line if line =~ /^Yum or Dnf Based Systems/ && file =~ /linux/
line = "##### " + line if line =~ /^Systems based on/ && file =~ /linux/
# Fix headers for some pages
line = line.gsub(/^##/, "#") if (outdir == "docs/configuration/ui" && (file =~ /basic/ || file =~ /classic/)) || file == 'astro1/readme.md'
# Fix broken links in the package selection article
if outdir == 'docs/configuration' && file =~ /packages/ then
line = line.gsub('(../addons/uis/paper/readme.html)', '(paperui.html)')
line = line.gsub('(../addons/uis/basic/readme.html)', '(ui/basic/)')
line = line.gsub('(../addons/uis/classic/readme.html)', '(ui/classic/)')
line = line.gsub('(../addons/uis/habmin/readme.html)', '(ui/habmin/)')
line = line.gsub('(../addons/uis/habpanel/readme.html)', '(habpanel.html)')
end
# Handle obsolete bindings
if in_frontmatter && (line =~ /label: / || line =~ /title: /) && outdir == 'addons/bindings' && file =~ /1\// then
addon = file.split('/')[0]
if !$ignore_bindings.include?(addon.gsub('1', '')) && Dir.exists?("#{indir}/#{addon.gsub('1', '')}") then
line = line.gsub("\n", "") + ' (1.x)' if !(line =~ /1\.x/)
if !obsolete_binding then
obsolete_binding = true
out.puts "obsolete: true"
puts " obsolete!"
end
end
end
# Expand <!--list-subs--> comments with a list of links
# (https://github.com/eclipse/smarthome/issues/5571)
if line =~ /<!--\s*list-subs\s*-->/ then
sub_addons = get_subs_links(file.split('/')[0], indir)
out.puts
sub_addons.each { |sub|
out.puts "- [#{sub[1]}](../#{sub[0]}/)"
}
out.puts
end
# Replace links to generated docs in ZWave's things.md by links to the internal viewer
line = line.gsub(/]\((.*)\/(.*)\)/, '](../thing.html?manufacturer=\1&file=\2)') if file == 'zwave/doc/things.md'
# Misc replaces (relative links, remove placeholder interpreted as custom tags)
line = line.gsub('http://docs.openhab.org/addons/uis/paper/readme.html', '/docs/configuration/paperui.html')
line = line.gsub('http://docs.openhab.org/addons/uis/habpanel/readme.html', '/docs/configuration/habpanel.html')
line = line.gsub('http://docs.openhab.org/addons/uis/habmin/readme.html', '/docs/configuration/habmin.html')
line = line.gsub('http://docs.openhab.org/addons/uis/basic/readme.html', '/docs/configuration/ui/basic/')
line = line.gsub(/http:\/\/docs\.openhab\.org\/addons\/(.*)\/(.*)\/readme\.html/, '/addons/\1/\2/')
line = line.gsub('http://docs.openhab.org/', '/docs/')
line = line.gsub('/addons/io/', '/addons/integrations/')
line = line.gsub("{{base}}/", "./docs/")
line = line.gsub("{{docu}}/", "./docs/")
line = line.gsub("(images/", "(./images/")
line = line.gsub("src=\"images/", "src=\"./images/")
line = line.gsub("]:images/", "]:./images/")
line = line.gsub("](doc/", "](./doc/")
line = line.gsub("(diagrams/", "(./diagrams/")
line = line.gsub("./docs/tutorials/beginner/", "/docs/tutorial/")
line = line.gsub("./docs/", "/docs/")
line = line.gsub("<activeState>", '\<activeState\>')
line = line.gsub("<passiveState>", '\<passiveState\>')
line = line.gsub("(?<!`)<dimension>(?!`)", '\<dimension\>')
line = line.gsub("<TransformProgram>", '\<TransformProgram\>')
line = line.gsub("<FlahshbriefingDeviceID>", '`<FlahshbriefingDeviceID>`') if file =~ /amazonechocontrol/
line = line.gsub("<SerialNumber>", '&lt;SerialNumber&gt;') if file =~ /airvisualnode/
line = line.gsub("<version>", '&lt;version&gt;') if file =~ /caldav/
line = line.gsub("by <step>", 'by `<step>`') if file =~ /ipx8001/
line = line.gsub("<BR>", '<BR/>')
line = line.gsub("'<package name>:<widget ID>'", '`<package name>:<widget ID>`') if file =~ /lametrictime/
line = line.gsub("<mac address of bridge>", '`<mac address of bridge>`') if file =~ /milight/
line = line.gsub("<mac>", '`<mac>`') if file =~ /milight/
line = line.gsub("<type of bulb>", '`<type of bulb>`') if file =~ /milight/
line = line.gsub("<IP-Address of bridge>", '`<IP-Address of bridge>`') if file =~ /milight/
line = line.gsub("<bulb>", '`<bulb>`') if file =~ /milight/
line = line.gsub("<zone>", '`<zone>`') if file =~ /milight/
line = line.gsub("[](", '[here](') if file =~ /powermax1/
line = line.gsub("<n>", '&lt;n&gt;') if file =~ /rfxcom/
line = line.gsub(" <value> ", ' &lt;value&gt; ') if file =~ /zibase/
line = line.gsub("<username>", '&lt;username&gt;') if file =~ /zoneminder/
line = line.gsub("<password>", '&lt;password&gt;') if file =~ /zoneminder/
line = line.gsub("<yourzmip>", '&lt;yourzmip&gt;') if file =~ /zoneminder/
line = line.gsub(" <chatId> ", ' &lt;chatId&gt; ') if file =~ /telegram/
line = line.gsub(" <token> ", ' &lt;token&gt; ') if file =~ /telegram/
line = line.gsub("<regular expression>", '\<regular expression\>')
line = line.gsub('src="images/', 'src="./images/') if outdir =~ /apps/
line = line.gsub('](/images/', '](./images/') if outdir =~ /google-assistant/
line = line.gsub(/\{:(style|target).*\}/, '') # Jekyll inline attributes syntax not supported
out.puts line
}
# Add the components for the versions dropdown and the edit link
out.puts
out.puts '<EditPageLink/>'
}
# Add the component for the edit link
out.puts
out.puts "<EditPageLink/>"
end
end

View File

@ -1,157 +0,0 @@
require_relative "./process_file.rb"
def process_main_docs(docs_source_dir)
puts ">>> Migrating the introduction article"
process_file(".", "introduction.md", "docs", "https://github.com/openhab/openhab-docs/blob/main/introduction.md")
FileUtils.mv("docs/introduction.md", "docs/readme.md")
puts ">>> Migrating common images"
FileUtils.mkdir_p("docs/images")
FileUtils.cp_r("#{docs_source_dir}/images/distro.png", "docs/images")
FileUtils.cp_r("#{docs_source_dir}/images/dashboard.png", "docs/images")
puts ">>> Migrating logos"
FileUtils.cp_r("#{docs_source_dir}/images/addons", ".vuepress/public/logos")
puts ">>> Migrating the Concepts section"
if Dir.exists?("#{docs_source_dir}/concepts") then
Dir.glob("#{docs_source_dir}/concepts/*.md").each { |path|
file = File.basename(path)
puts " -> #{file}"
process_file("#{docs_source_dir}/concepts", file, "docs/concepts", "#{$esh_repo_root}/concepts/#{file}")
}
puts " -> images and diagrams"
FileUtils.cp_r("#{docs_source_dir}/concepts/images", "docs/concepts")
FileUtils.cp_r("#{docs_source_dir}/concepts/diagrams", "docs/concepts")
else
puts " Skipping non-existing section!"
end
puts ">>> Migrating the Installation section"
Dir.glob("#{docs_source_dir}/installation/*.md") { |path|
file = File.basename(path)
next if file == "designer.md"
puts " -> #{file}"
process_file("#{docs_source_dir}/installation", file, "docs/installation", "#{$docs_repo_root}/installation/#{file}")
}
puts " -> images"
FileUtils.cp_r("#{docs_source_dir}/installation/images", "docs/installation")
puts ">>> Migrating the Tutorial section"
Dir.glob("#{docs_source_dir}/tutorials/getting_started/*.md") { |path|
file = File.basename(path)
puts " -> #{file}"
process_file("#{docs_source_dir}/tutorials/getting_started", file, "docs/tutorial", "#{$docs_repo_root}/tutorials/getting_started/#{file}")
}
puts " -> images"
FileUtils.cp_r("#{docs_source_dir}/tutorials/getting_started/images", "docs/tutorial")
# FileUtils.cp_r("#{docs_source_dir}/tutorials/images/*", "docs/tutorial/images")
puts ">>> Migrating the Configuration section"
Dir.glob("#{docs_source_dir}/configuration/*.md") { |path|
file = File.basename(path)
next if file == "transform.md" # Useless, copy the one from addons
puts " -> #{file}"
process_file("#{docs_source_dir}/configuration", file, "docs/configuration", "#{$docs_repo_root}/configuration/#{file}")
}
puts " -> images"
FileUtils.cp_r("#{docs_source_dir}/configuration/images", "docs/configuration")
#process_file("#{docs_source_dir}/tutorials", "migration.md", "docs/configuration/migration", "#{$docs_repo_root}/tutorials/migration.md")
#FileUtils.mv("docs/configuration/migration/migration.md", "docs/configuration/migration/index.md")
#FileUtils.cp_r("#{docs_source_dir}/tutorials/images", "docs/configuration/migration")
puts ">>> Migrating the Main UI section"
Dir.glob("#{docs_source_dir}/mainui/*.md") { |path|
file = File.basename(path)
puts " -> #{file}"
process_file("#{docs_source_dir}/mainui", file, "docs/mainui", "#{$docs_repo_root}/mainui/#{file}")
}
["developer", "settings"].each { |subsection|
Dir.glob("#{docs_source_dir}/mainui/#{subsection}/*.md") { |path|
file = File.basename(path)
puts " -> #{subsection}/#{file}"
process_file("#{docs_source_dir}/mainui/#{subsection}", file, "docs/mainui/#{subsection}", "#{$docs_repo_root}/mainui/#{subsection}/#{file}")
}
}
puts " -> images"
FileUtils.cp_r("#{docs_source_dir}/mainui/images", "docs/mainui")
puts ">>> Migrating the Migration Tutorial section"
Dir.glob("#{docs_source_dir}/configuration/migration/*.md") { |path|
file = File.basename(path)
puts " -> #{file}"
process_file("#{docs_source_dir}/configuration/migration", file, "docs/configuration/migration", "#{$docs_repo_root}/configuration/migration/#{file}")
}
puts " -> images"
#FileUtils.cp_r("#{docs_source_dir}/configuration/images", "docs/configuration") // no images placed yet
puts ">>> Migrating the Blockly Tutorial section"
Dir.glob("#{docs_source_dir}/configuration/blockly/*.md") { |path|
file = File.basename(path)
puts " -> #{file}"
process_file("#{docs_source_dir}/configuration/blockly", file, "docs/configuration/blockly", "#{$docs_repo_root}/configuration/blockly/#{file}")
}
puts " -> images"
#FileUtils.cp_r("#{docs_source_dir}/configuration/images", "docs/configuration") // no images placed yet
puts ">>> Migrating the UI section"
Dir.glob("#{docs_source_dir}/ui/*.md") { |path|
file = File.basename(path)
puts " -> #{file}"
process_file("#{docs_source_dir}/ui", file, "docs/ui", "#{$docs_repo_root}/ui/#{file}")
}
puts " -> images"
FileUtils.cp_r("#{docs_source_dir}/ui/images", "docs/ui")
puts ">>> Migrating the Apps section"
Dir.glob("#{docs_source_dir}/addons/uis/apps/*.md") { |path|
file = File.basename(path)
puts " -> #{file}"
process_file("#{docs_source_dir}/addons/uis/apps", file, "docs/apps", "#{$docs_repo_root}/addons/uis/apps/#{file}")
}
puts " -> images"
FileUtils.cp_r("#{docs_source_dir}/addons/uis/apps/images", "docs/apps")
puts ">>> Migrating the Administration section"
Dir.glob("#{docs_source_dir}/administration/*.md") { |path|
file = File.basename(path)
puts " -> #{file}"
process_file("#{docs_source_dir}/administration", file, "docs/administration", "#{$docs_repo_root}/administration/#{file}")
}
puts " -> images"
FileUtils.cp_r("#{docs_source_dir}/administration/images", "docs/administration")
puts ">>> Migrating the Developer section"
Dir.glob("#{docs_source_dir}/developers/*.md") { |path|
file = File.basename(path)
puts " -> #{file}"
process_file("#{docs_source_dir}/developers", file, "docs/developer", "#{$docs_repo_root}/developer/#{file}")
}
["addons", "audio", "bindings", "ioservices", "legacy", "module-types", "osgi", "persistence", "transformations", "utils", "ide"].each { |subsection|
Dir.glob("#{docs_source_dir}/developers/#{subsection}/*.md") { |path|
file = File.basename(path)
puts " -> #{subsection}/#{file}"
process_file("#{docs_source_dir}/developers/#{subsection}", file, "docs/developer/#{subsection}", "#{$docs_repo_root}/developer/#{subsection}/#{file}")
}
}
puts " -> images"
FileUtils.cp_r("#{docs_source_dir}/developers/bindings/images", "docs/developer/bindings")
FileUtils.cp_r("#{docs_source_dir}/developers/osgi/images", "docs/developer/osgi")
FileUtils.cp_r("#{docs_source_dir}/developers/ide/images", "docs/developer/ide")
end

View File

@ -81,38 +81,44 @@ The new build will include all the latest changes in the code repository and in
### How to build the documentation locally
It is possible to build a preview version of the documentation on your local machine. The following software is required:
It is possible to build a preview version of the documentation on your local machine.
The following software is required:
- [`node =16.20.1`](https://nodejs.org/en)
- [`ruby >=3.0.2`](https://www.ruby-lang.org/en/)
- [`Python >= 3.10.12`](https://www.python.org)
- [`NodeJS = 16.20.1`](https://nodejs.org/en)
- [`Ruby >= 3.3.2`](https://www.ruby-lang.org/en/)
If you work on multiple node projects [Node Version Manager](https://github.com/nvm-sh/nvm) is recommended in case they use a different version of node.
We recommend to use [Node Version Manager](https://github.com/nvm-sh/nvm) as well as [Ruby Version Manager](https://rvm.io/) to easily allow using multiple versions of NodeJS and Ruby for multiple projects.
If you don't do that, you can simply start by only installing the above mentioned versions.
Example:
When using `nvm` and/or `rvm`, setup the NodeJS and/or Ruby version:
```bash
$ nvm install 16
# ...
$ nvm use 16
Now using node v16.20.2 (npm v8.19.4)
$ npm install
# ...
$ npm run serve
# ...
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/)
```shell script
nvm use
rvm use
```
The local preview is available under the following options
If `nvm` and/or `rvm` complain about the required versions not being installed, you can install them as following:
- [http://0.0.0.0:8000/docs](http://0.0.0.0:8000/docs)
- [http://localhost:8000/docs](http://localhost:8000/docs)
- [http://[::]/:8000/docs](http://[::]:8000/docs)
```shell script
nvm install 16.20.1
rvm install ruby-3.3.2
```
Next, you can build & serve the documentation preview:
```shell script
npm run serve-preview
```
The local preview is available under the following URLs:
- <http://0.0.0.0:8080/docs>
- <http://localhost:8080/docs>
This will also allow you to preview how the page renders on different devices using the respective browser tools:
![local preview](images/local-docu-preview.png)
This will also allow you to preview how the page renders on different devices using the respective browser tools.
## Documentation Versioning
Just as openHAB is released in versions, the documentation website provides fixed versions of the documentation articles, e.g., [https://www.openhab.org/v2.2/installation/linux.html](https://www.openhab.org/v2.2/installation/linux.html)

236
package-lock.json generated
View File

@ -2427,9 +2427,9 @@
}
},
"node_modules/@vuepress/core/node_modules/cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
"integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
"dependencies": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
@ -2554,9 +2554,9 @@
}
},
"node_modules/@vuepress/plugin-last-updated/node_modules/cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
"integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
"dependencies": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
@ -3194,9 +3194,9 @@
}
},
"node_modules/asn1.js/node_modules/bn.js": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg=="
},
"node_modules/assert": {
"version": "1.5.1",
@ -4251,9 +4251,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001589",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz",
"integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==",
"version": "1.0.30001690",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz",
"integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==",
"funding": [
{
"type": "opencollective",
@ -5025,9 +5025,9 @@
}
},
"node_modules/create-ecdh/node_modules/bn.js": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg=="
},
"node_modules/create-hash": {
"version": "1.2.0",
@ -5072,9 +5072,9 @@
}
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@ -5495,11 +5495,11 @@
"integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg=="
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"dependencies": {
"ms": "2.1.2"
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@ -5717,9 +5717,9 @@
}
},
"node_modules/diffie-hellman/node_modules/bn.js": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg=="
},
"node_modules/dir-glob": {
"version": "2.2.2",
@ -5919,9 +5919,9 @@
}
},
"node_modules/elliptic/node_modules/bn.js": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg=="
},
"node_modules/emoji-regex": {
"version": "8.0.0",
@ -6523,9 +6523,9 @@
}
},
"node_modules/execa/node_modules/cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
"integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
"dependencies": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
@ -7924,20 +7924,20 @@
}
},
"node_modules/http-proxy-middleware/node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dependencies": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/http-proxy-middleware/node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dependencies": {
"to-regex-range": "^5.0.1"
},
@ -7954,11 +7954,11 @@
}
},
"node_modules/http-proxy-middleware/node_modules/micromatch": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dependencies": {
"braces": "^3.0.2",
"braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
@ -9015,9 +9015,9 @@
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
},
"node_modules/koa-route/node_modules/path-to-regexp": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
"integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz",
"integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==",
"dependencies": {
"isarray": "0.0.1"
}
@ -9555,9 +9555,9 @@
}
},
"node_modules/miller-rabin/node_modules/bn.js": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg=="
},
"node_modules/mime": {
"version": "2.6.0",
@ -9764,9 +9764,9 @@
}
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/multicast-dns": {
"version": "6.2.3",
@ -9792,9 +9792,9 @@
"optional": true
},
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"version": "3.3.8",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"funding": [
{
"type": "github",
@ -10686,9 +10686,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.35",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
"integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
"version": "8.4.49",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
"integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
"funding": [
{
"type": "opencollective",
@ -10705,8 +10705,8 @@
],
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
@ -11776,9 +11776,9 @@
}
},
"node_modules/postcss-selector-parser": {
"version": "6.0.15",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
"integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@ -11856,9 +11856,9 @@
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
},
"node_modules/postcss/node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
},
"node_modules/prepend-http": {
"version": "2.0.0",
@ -11967,14 +11967,14 @@
}
},
"node_modules/public-encrypt/node_modules/bn.js": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg=="
},
"node_modules/pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
"integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@ -12931,11 +12931,6 @@
"node": ">=4"
}
},
"node_modules/send/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/serialize-javascript": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
@ -13359,9 +13354,9 @@
}
},
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"engines": {
"node": ">=0.10.0"
}
@ -14671,9 +14666,9 @@
}
},
"node_modules/update-browserslist-db/node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
},
"node_modules/update-notifier": {
"version": "4.1.3",
@ -14869,11 +14864,11 @@
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
},
"node_modules/url/node_modules/qs": {
"version": "6.11.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
"integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
"version": "6.13.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.1.tgz",
"integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==",
"dependencies": {
"side-channel": "^1.0.4"
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
@ -15312,21 +15307,24 @@
}
},
"node_modules/watchpack/node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"optional": true,
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/watchpack/node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"optional": true,
"dependencies": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@ -15357,9 +15355,9 @@
}
},
"node_modules/watchpack/node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"optional": true,
"dependencies": {
"to-regex-range": "^5.0.1"
@ -15862,11 +15860,11 @@
}
},
"node_modules/webpack-plugin-serve/node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dependencies": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@ -15899,11 +15897,11 @@
}
},
"node_modules/webpack-plugin-serve/node_modules/fast-glob/node_modules/micromatch": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dependencies": {
"braces": "^3.0.2",
"braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
@ -15911,9 +15909,9 @@
}
},
"node_modules/webpack-plugin-serve/node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dependencies": {
"to-regex-range": "^5.0.1"
},
@ -15965,9 +15963,9 @@
}
},
"node_modules/webpack-plugin-serve/node_modules/ignore": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
"integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"engines": {
"node": ">= 4"
}
@ -16036,9 +16034,9 @@
}
},
"node_modules/webpack-plugin-serve/node_modules/ws": {
"version": "7.5.9",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
"integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
"version": "7.5.10",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
"engines": {
"node": ">=8.3.0"
},
@ -16082,9 +16080,9 @@
}
},
"node_modules/webpack-serve/node_modules/import-local": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
"integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
"integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
"dependencies": {
"pkg-dir": "^4.2.0",
"resolve-cwd": "^3.0.0"
@ -16365,9 +16363,9 @@
}
},
"node_modules/ws": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
"integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
"dependencies": {
"async-limiter": "~1.0.0"
}

View File

@ -4,14 +4,12 @@
"description": "openHAB Documentation",
"main": "index.js",
"scripts": {
"build-only": "vuepress build .",
"prebuild-preview-local": "ruby prepare-docs.rb",
"build-preview-local": "cross-env LANG=en_US.UTF-8 LANGUAGE=en_US.UTF-8 LC_ALL=en_US.UTF-8 NODE_OPTIONS=--openssl-legacy-provider && npx vuepress build .",
"build-preview": "npm run build-only",
"postinstall": "npm dedupe && npm prune",
"prebuild-preview": "ruby prepare-docs.rb",
"preserve": "npm run build-preview-local",
"serve": "python3 -m http.server --directory vuepress"
"prepare-docs": "ruby prepare-docs.rb",
"build-only": "vuepress build .",
"build-preview": "npm run prepare-docs && npm run build-only",
"preserve-preview": "npm run build-preview",
"serve-preview": "npx http-server vuepress --silent"
},
"engines": {
"node": ">=16.20.1 <17"
@ -40,4 +38,4 @@
"vue-server-renderer": "=2.6.14",
"vue-template-compiler": "=2.6.14"
}
}
}

View File

@ -1,37 +1,200 @@
# This will clone https://github.com/openhab/openhab-docs
# and migrate content into the website with some changes
# frozen_string_literal: true
require "fileutils"
require "net/http"
require "uri"
require "rexml/document"
# require "nokogiri"
$docs_repo = "https://github.com/openhab/openhab-docs"
$docs_repo_root = $docs_repo + "/blob/main"
$docs_repo_branch = "final"
$esh_repo = "https://github.com/eclipse/smarthome"
$esh_repo_root = $esh_repo + "/blob/master/docs/documentation"
$version = nil
require_relative "./.vuepress/process_file.rb"
require_relative "./.vuepress/process_main_docs.rb"
require_relative "./.vuepress/add_placeholders.rb"
$verbose = false
if (Dir.exists?("docs")) then
puts ">>> Removing processed docs"
def verbose(message)
puts message if $verbose
end
if Dir.exist?("docs") then
puts "➡️ Removing processed docs"
FileUtils.rm_rf("docs")
end
if (Dir.exists?("addons/integrations")) then
puts ">>> Removing processed addons"
if Dir.exist?("addons/integrations") then
puts "➡️ Removing processed addons"
FileUtils.rm_rf("docs")
end
process_main_docs(".")
puts "➡️ Migrating the introduction article"
process_file(".", "introduction.md", "docs", "https://github.com/openhab/openhab-docs/blob/main/introduction.md")
FileUtils.mv("docs/introduction.md", "docs/readme.md")
# puts "➡️ Migrating common images"
# FileUtils.mkdir_p("docs/images")
puts "➡️ Migrating logos"
FileUtils.cp_r("./images/addons", ".vuepress/public/logos")
puts "➡️ Migrating the Concepts section"
Dir.glob("./concepts/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{file}"
process_file("./concepts", file, "docs/concepts", "#{$docs_repo_root}/concepts/#{file}")
end
verbose " ➡️ images and diagrams"
FileUtils.cp_r("./concepts/images", "docs/concepts")
FileUtils.cp_r("./concepts/diagrams", "docs/concepts")
puts "➡️ Migrating the Installation section"
Dir.glob("./installation/*.md") do |path|
file = File.basename(path)
next if file == "designer.md"
verbose " ➡️ #{file}"
process_file("./installation", file, "docs/installation",
"#{$docs_repo_root}/installation/#{file}")
end
verbose " ➡️ images"
FileUtils.cp_r("./installation/images", "docs/installation")
puts "➡️ Migrating the Tutorial section"
Dir.glob("./tutorials/getting_started/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{file}"
process_file("./tutorials/getting_started", file, "docs/tutorial",
"#{$docs_repo_root}/tutorials/getting_started/#{file}")
end
verbose " ➡️ images"
FileUtils.cp_r("./tutorials/getting_started/images", "docs/tutorial")
puts "➡️ Migrating the Configuration section"
Dir.glob("./configuration/*.md") do |path|
file = File.basename(path)
next if file == "transform.md" # Useless, copy the one from addons
verbose " ➡️ #{file}"
process_file("./configuration", file, "docs/configuration",
"#{$docs_repo_root}/configuration/#{file}")
end
verbose " ➡️ images"
FileUtils.cp_r("./configuration/images", "docs/configuration")
puts "➡️ Migrating the Main UI section"
Dir.glob("./mainui/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{file}"
process_file("./mainui", file, "docs/mainui", "#{$docs_repo_root}/mainui/#{file}")
end
%w[developer settings].each do |subsection|
Dir.glob("./mainui/#{subsection}/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{subsection}/#{file}"
process_file("./mainui/#{subsection}", file, "docs/mainui/#{subsection}",
"#{$docs_repo_root}/mainui/#{subsection}/#{file}")
end
end
verbose " ➡️ images"
FileUtils.cp_r("./mainui/images", "docs/mainui")
puts "➡️ Migrating the Migration Tutorial section"
Dir.glob("./configuration/migration/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{file}"
process_file("./configuration/migration", file, "docs/configuration/migration",
"#{$docs_repo_root}/configuration/migration/#{file}")
end
verbose " ➡️ images"
# FileUtils.cp_r("./configuration/migration/images", "docs/configuration/migration/") // no images placed yet
puts "➡️ Migrating the Blockly Tutorial section"
Dir.glob("./configuration/blockly/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{file}"
process_file("./configuration/blockly", file, "docs/configuration/blockly",
"#{$docs_repo_root}/configuration/blockly/#{file}")
end
verbose " ➡️ images"
# FileUtils.cp_r("./configuration/blockly/images", "docs/configuration/blockly/") // no images placed yet
puts "➡️ Migrating the UI section"
Dir.glob("./ui/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{file}"
process_file("./ui", file, "docs/ui", "#{$docs_repo_root}/ui/#{file}")
end
verbose " ➡️ images"
FileUtils.cp_r("./ui/images", "docs/ui")
verbose " ➡️ habpanel"
FileUtils.mkdir_p("docs/ui/habpanel")
process_file("./_addons_uis/habpanel/doc", "habpanel.md", "docs/ui/habpanel", "")
verbose " ➡️ images"
if Dir.exist?("./_addons_uis/habpanel/doc/images")
FileUtils.cp_r("./_addons_uis/habpanel/doc/images",
"docs/ui/habpanel")
end
verbose " ➡️ habot"
FileUtils.mkdir_p("docs/ui/habot")
process_file("./_addons_uis/habot", "readme.md", "docs/ui/habot", "")
verbose " ➡️ images"
verbose " ➡️ components"
FileUtils.mkdir_p("docs/ui/components")
Dir.glob("./_addons_uis/org.openhab.ui/doc/components/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{file}"
process_file("./_addons_uis/org.openhab.ui/doc/components", file, "docs/ui/components", "https://github.com/openhab/openhab-webui/blob/main/bundles/org.openhab.ui/doc/components/#{file}")
end
verbose " ➡️ images"
if Dir.exist?("./_addons_uis/org.openhab.ui/doc/components/images")
FileUtils.cp_r("./_addons_uis/org.openhab.ui/doc/components/images",
"docs/ui/components")
end
puts "➡️ Migrating the Apps section"
Dir.glob("./addons/uis/apps/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{file}"
process_file("./addons/uis/apps", file, "docs/apps",
"#{$docs_repo_root}/addons/uis/apps/#{file}")
end
verbose " ➡️ images"
FileUtils.cp_r("./addons/uis/apps/images", "docs/apps")
puts "➡️ Migrating the Administration section"
Dir.glob("./administration/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{file}"
process_file("./administration", file, "docs/administration",
"#{$docs_repo_root}/administration/#{file}")
end
verbose " ➡️ images"
FileUtils.cp_r("./administration/images", "docs/administration")
puts "➡️ Migrating the Developer section"
Dir.glob("./developers/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{file}"
process_file("./developers", file, "docs/developer", "#{$docs_repo_root}/developer/#{file}")
end
%w[audio bindings ioservices legacy module-types osgi persistence transformations utils
ide].each do |subsection|
Dir.glob("./developers/#{subsection}/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{subsection}/#{file}"
process_file("./developers/#{subsection}", file, "docs/developer/#{subsection}",
"#{$docs_repo_root}/developer/#{subsection}/#{file}")
end
end
verbose " ➡️ images"
FileUtils.cp_r("./developers/bindings/images", "docs/developer/bindings")
FileUtils.cp_r("./developers/osgi/images", "docs/developer/osgi")
FileUtils.cp_r("./developers/ide/images", "docs/developer/ide")
["addons"].each do |subsection|
Dir.glob("./developers/#{subsection}/*.md") do |path|
file = File.basename(path)
verbose " ➡️ #{subsection}/#{file}"
process_file("./developers/#{subsection}", file, "docs/developer/#{subsection}",
"#{$docs_repo_root}/developer/#{subsection}/#{file}")
end
end
add_placeholder_pages()
# Regenerate the classic iconset docs
#puts ">>> Generating iconset"
#system("ruby generate_iconset_doc.rb #{docs_source_dir}/_addons_iconsets classic #{docs_source_dir}/_data docs/configuration/iconsets")