mirror of
https://github.com/wez/wezterm.git
synced 2024-12-25 22:33:52 +03:00
498 lines
16 KiB
Python
498 lines
16 KiB
Python
#!/usr/bin/env python3
|
|
import base64
|
|
import glob
|
|
import json
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
class Page(object):
|
|
def __init__(self, title, filename, children=None):
|
|
self.title = title
|
|
self.filename = filename
|
|
self.children = children or []
|
|
|
|
def render(self, output, depth=0, mode="mdbook"):
|
|
indent = " " * depth
|
|
bullet = "- " if depth > 0 else ""
|
|
if mode == "mdbook":
|
|
if self.filename:
|
|
output.write(f"{indent}{bullet}[{self.title}]({self.filename})\n")
|
|
elif mode == "mkdocs":
|
|
if depth > 0:
|
|
if len(self.children) == 0:
|
|
output.write(f'{indent}{bullet}"{self.title}": {self.filename}\n')
|
|
else:
|
|
output.write(f'{indent}{bullet}"{self.title}":\n')
|
|
if self.filename:
|
|
output.write(
|
|
f'{indent} {bullet}"{self.title}": {self.filename}\n'
|
|
)
|
|
for kid in self.children:
|
|
kid.render(output, depth + 1, mode)
|
|
|
|
|
|
# autogenerate an index page from the contents of a directory
|
|
class Gen(object):
|
|
def __init__(self, title, dirname, index=None, extract_title=False):
|
|
self.title = title
|
|
self.dirname = dirname
|
|
self.index = index
|
|
self.extract_title = extract_title
|
|
|
|
def render(self, output, depth=0, mode="mdbook"):
|
|
names = sorted(glob.glob(f"{self.dirname}/*.md"))
|
|
children = []
|
|
for filename in names:
|
|
title = os.path.basename(filename).rsplit(".", 1)[0]
|
|
if title == "index":
|
|
continue
|
|
|
|
if self.extract_title:
|
|
with open(filename, "r") as f:
|
|
title = f.readline().strip("#").strip()
|
|
|
|
children.append(Page(title, filename))
|
|
|
|
index_filename = f"{self.dirname}/index.md"
|
|
index_page = Page(self.title, index_filename, children=children)
|
|
index_page.render(output, depth, mode)
|
|
with open(f"{self.dirname}/index.md", "w") as idx:
|
|
if self.index:
|
|
idx.write(self.index)
|
|
idx.write("\n\n")
|
|
else:
|
|
try:
|
|
with open(f"{self.dirname}/index.markdown", "r") as f:
|
|
idx.write(f.read())
|
|
idx.write("\n\n")
|
|
except FileNotFoundError:
|
|
pass
|
|
for page in children:
|
|
idx.write(f" - [{page.title}]({os.path.basename(page.filename)})\n")
|
|
|
|
|
|
def load_scheme(scheme):
|
|
ident = re.sub(
|
|
"[^a-z0-9_]", "_", scheme["metadata"]["name"].lower().replace("+", "plus")
|
|
)
|
|
|
|
colors = scheme["colors"]["ansi"] + scheme["colors"]["brights"]
|
|
|
|
data = {
|
|
"name": scheme["metadata"]["name"],
|
|
"prefix": scheme["metadata"]["prefix"],
|
|
"ident": ident,
|
|
"fg": scheme["colors"]["foreground"],
|
|
"bg": scheme["colors"]["background"],
|
|
"metadata": scheme["metadata"],
|
|
}
|
|
|
|
# <https://github.com/asciinema/asciinema-player/wiki/Custom-terminal-themes>
|
|
css = f"""
|
|
.asciinema-theme-{ident} .asciinema-terminal {{
|
|
color: {data["fg"]};
|
|
background-color: {data["bg"]};
|
|
border-color: {data["bg"]};
|
|
}}
|
|
|
|
.asciinema-theme-{ident} .fg-bg {{
|
|
color: {data["bg"]};
|
|
}}
|
|
|
|
.asciinema-theme-{ident} .bg-fg {{
|
|
background-color: {data["fg"]};
|
|
}}
|
|
"""
|
|
|
|
if "cursor_border" in scheme["colors"]:
|
|
data["cursor"] = scheme["colors"]["cursor_border"]
|
|
|
|
css += f"""
|
|
.asciinema-theme-{ident} .cursor-b {{
|
|
background-color: {data["cursor"]} !important;
|
|
}}
|
|
"""
|
|
|
|
if "selection_fg" in scheme["colors"] and "selection_bg" in scheme["colors"]:
|
|
selection_bg = scheme["colors"]["selection_bg"]
|
|
selection_fg = scheme["colors"]["selection_fg"]
|
|
|
|
css += f"""
|
|
.asciinema-theme-{ident} .asciinema-terminal ::selection {{
|
|
color: {selection_fg};
|
|
background-color: {selection_bg};
|
|
}}
|
|
"""
|
|
|
|
for idx, color in enumerate(colors):
|
|
css += f"""
|
|
.asciinema-theme-{ident} .fg-{idx} {{
|
|
color: {color};
|
|
}}
|
|
.asciinema-theme-{ident} .bg-{idx} {{
|
|
background-color: {color};
|
|
}}
|
|
"""
|
|
|
|
data["css"] = css
|
|
return data
|
|
|
|
|
|
def screen_shot_table(scheme):
|
|
T = "gYw"
|
|
lines = [
|
|
scheme["name"],
|
|
"",
|
|
" def 40m 41m 42m 43m 44m 45m 46m 47m",
|
|
]
|
|
for fg_space in [
|
|
" m",
|
|
" 1m",
|
|
" 30m",
|
|
"1;30m",
|
|
" 31m",
|
|
"1;31m",
|
|
" 32m",
|
|
"1;32m",
|
|
" 33m",
|
|
"1;33m",
|
|
" 34m",
|
|
"1;34m",
|
|
" 35m",
|
|
"1;35m",
|
|
" 36m",
|
|
"1;36m",
|
|
" 37m",
|
|
"1;37m",
|
|
]:
|
|
fg = fg_space.strip()
|
|
line = f" {fg_space} \033[{fg} {T} "
|
|
|
|
for bg in ["40m", "41m", "42m", "43m", "44m", "45m", "46m", "47m"]:
|
|
line += f" \033[{fg}\033[{bg} {T} \033[0m"
|
|
lines.append(line)
|
|
|
|
lines.append("")
|
|
lines.append("")
|
|
|
|
screen = "\r\n".join(lines)
|
|
|
|
header = {
|
|
"version": 2,
|
|
"width": 80,
|
|
"height": 24,
|
|
"title": scheme["name"],
|
|
}
|
|
header = json.dumps(header, sort_keys=True)
|
|
data = json.dumps([0.0, "o", screen])
|
|
|
|
return base64.b64encode(f"{header}\n{data}\n".encode("UTF-8")).decode("UTF-8")
|
|
|
|
|
|
class GenColorScheme(object):
|
|
def __init__(self, title, dirname, index=None):
|
|
self.title = title
|
|
self.dirname = dirname
|
|
self.index = index
|
|
|
|
def render(self, output, depth=0, mode="mdbook"):
|
|
with open("colorschemes/data.json") as f:
|
|
scheme_data = json.load(f)
|
|
by_prefix = {}
|
|
by_name = {}
|
|
for scheme in scheme_data:
|
|
scheme = load_scheme(scheme)
|
|
prefix = scheme["prefix"]
|
|
if prefix not in by_prefix:
|
|
by_prefix[prefix] = []
|
|
by_prefix[prefix].append(scheme)
|
|
by_name[scheme["name"]] = scheme
|
|
|
|
style_filename = f"{self.dirname}/scheme.css"
|
|
with open(style_filename, "w") as style_file:
|
|
for scheme in by_name.values():
|
|
style_file.write(scheme["css"])
|
|
style_file.write("\n")
|
|
js_filename = f"{self.dirname}/scheme.js"
|
|
with open(js_filename, "w") as js_file:
|
|
data_by_scheme = {}
|
|
for scheme in by_name.values():
|
|
ident = scheme["ident"]
|
|
data = screen_shot_table(scheme)
|
|
data_by_scheme[ident] = data
|
|
|
|
js_file.write(f"SCHEME_DATA = {json.dumps(data_by_scheme)};\n")
|
|
js_file.write(
|
|
f"""
|
|
function load_scheme_player(ident) {{
|
|
var data = SCHEME_DATA[ident];
|
|
AsciinemaPlayer.create(
|
|
'data:text/plain;base64,' + data,
|
|
document.getElementById(ident + '-player'), {{
|
|
theme: ident,
|
|
autoPlay: true,
|
|
}});
|
|
}}
|
|
"""
|
|
)
|
|
|
|
children = []
|
|
for scheme_prefix in sorted(by_prefix.keys()):
|
|
scheme_filename = f"{self.dirname}/{scheme_prefix}/index.md"
|
|
os.makedirs(os.path.dirname(scheme_filename), exist_ok=True)
|
|
children.append(Page(scheme_prefix, scheme_filename))
|
|
|
|
with open(scheme_filename, "w") as idx:
|
|
idents_to_load = []
|
|
|
|
idx.write(
|
|
f"""---
|
|
title: Color Schemes with first letter "{scheme_prefix}"
|
|
---
|
|
|
|
"""
|
|
)
|
|
|
|
for scheme in by_prefix[scheme_prefix]:
|
|
title = scheme["name"]
|
|
idx.write(f"## {title}\n")
|
|
|
|
data = screen_shot_table(scheme)
|
|
ident = scheme["ident"]
|
|
idents_to_load.append(ident)
|
|
|
|
idx.write(
|
|
f"""
|
|
<div id="{ident}-player"></div>
|
|
"""
|
|
)
|
|
|
|
author = scheme["metadata"].get("author", None)
|
|
if author:
|
|
idx.write(f"Author: `{author}`<br/>\n")
|
|
origin_url = scheme["metadata"].get("origin_url", None)
|
|
if origin_url:
|
|
idx.write(f"Source: <{origin_url}><br/>\n")
|
|
version = scheme["metadata"].get("wezterm_version", None)
|
|
if version and version != "Always":
|
|
idx.write(f"{{{{since('{version}')}}}}<br/>\n")
|
|
|
|
aliases = scheme["metadata"]["aliases"]
|
|
if len(aliases) > 0:
|
|
alias_list = []
|
|
for a in aliases:
|
|
alias_list.append(f"`{a}`")
|
|
aliases = ", ".join(alias_list)
|
|
idx.write(f"This scheme is also known as {aliases}.<br/>\n")
|
|
|
|
idx.write("\nTo use this scheme, add this to your config:\n")
|
|
idx.write(
|
|
f"""
|
|
```lua
|
|
config.color_scheme = '{title}'
|
|
```
|
|
|
|
"""
|
|
)
|
|
|
|
idents_to_load = json.dumps(idents_to_load)
|
|
idx.write(
|
|
f"""
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function() {{
|
|
{idents_to_load}.forEach(ident => load_scheme_player(ident));
|
|
}});
|
|
</script>
|
|
"""
|
|
)
|
|
|
|
index_filename = f"{self.dirname}/index.md"
|
|
index_page = Page(self.title, index_filename, children=children)
|
|
index_page.render(output, depth, mode)
|
|
|
|
with open(f"{self.dirname}/index.md", "w") as idx:
|
|
idx.write(f"{len(scheme_data)} Color schemes listed by first letter\n\n")
|
|
for page in children:
|
|
upper = page.title.upper()
|
|
idx.write(f" - [{upper}]({page.title}/index.md)\n")
|
|
|
|
|
|
TOC = [
|
|
Page(
|
|
"WezTerm",
|
|
"index.md",
|
|
children=[
|
|
Page("Features", "features.md"),
|
|
Page("Scrollback", "scrollback.md"),
|
|
Page("Quick Select Mode", "quickselect.md"),
|
|
Page("Copy Mode", "copymode.md"),
|
|
Page("Hyperlinks", "hyperlinks.md"),
|
|
Page("Shell Integration", "shell-integration.md"),
|
|
Page("iTerm Image Protocol", "imgcat.md"),
|
|
Page("SSH", "ssh.md"),
|
|
Page("Serial Ports & Arduino", "serial.md"),
|
|
Page("Multiplexing", "multiplexing.md"),
|
|
],
|
|
),
|
|
Page(
|
|
"Download",
|
|
"installation.md",
|
|
children=[
|
|
Page("Windows", "install/windows.md"),
|
|
Page("macOS", "install/macos.md"),
|
|
Page("Linux", "install/linux.md"),
|
|
Page("FreeBSD", "install/freebsd.md"),
|
|
Page("Build from source", "install/source.md"),
|
|
],
|
|
),
|
|
Page(
|
|
"Configuration",
|
|
"config/files.md",
|
|
children=[
|
|
Page("Colors & Appearance", "config/appearance.md"),
|
|
Page("Launching Programs", "config/launch.md"),
|
|
Page("Fonts", "config/fonts.md"),
|
|
Page("Font Shaping", "config/font-shaping.md"),
|
|
Page("Keyboard Concepts", "config/keyboard-concepts.md"),
|
|
Page("Key Binding", "config/keys.md"),
|
|
Page("Key Tables", "config/key-tables.md"),
|
|
Page("Default Key Assignments", "config/default-keys.md"),
|
|
Page("Keyboard Encoding", "config/key-encoding.md"),
|
|
Page("Mouse Binding", "config/mouse.md"),
|
|
GenColorScheme("Color Schemes", "colorschemes"),
|
|
Gen("Recipes", "recipes", extract_title=True),
|
|
],
|
|
),
|
|
Page(
|
|
"Lua Reference",
|
|
"config/lua/general.md",
|
|
children=[
|
|
Gen(
|
|
"module: wezterm",
|
|
"config/lua/wezterm",
|
|
),
|
|
Gen(
|
|
"module: wezterm.color",
|
|
"config/lua/wezterm.color",
|
|
),
|
|
Gen(
|
|
"module: wezterm.gui",
|
|
"config/lua/wezterm.gui",
|
|
),
|
|
Gen(
|
|
"module: wezterm.mux",
|
|
"config/lua/wezterm.mux",
|
|
),
|
|
Gen(
|
|
"module: wezterm.procinfo",
|
|
"config/lua/wezterm.procinfo",
|
|
),
|
|
Gen(
|
|
"module: wezterm.time",
|
|
"config/lua/wezterm.time",
|
|
),
|
|
Gen(
|
|
"struct: Config",
|
|
"config/lua/config",
|
|
),
|
|
Gen(
|
|
"enum: KeyAssignment",
|
|
"config/lua/keyassignment",
|
|
),
|
|
Gen(
|
|
"enum: CopyModeAssignment",
|
|
"config/lua/keyassignment/CopyMode",
|
|
),
|
|
Gen("object: Color", "config/lua/color"),
|
|
Page("object: ExecDomain", "config/lua/ExecDomain.md"),
|
|
Page("object: LocalProcessInfo", "config/lua/LocalProcessInfo.md"),
|
|
Gen("object: MuxDomain", "config/lua/MuxDomain"),
|
|
Gen("object: MuxWindow", "config/lua/mux-window"),
|
|
Gen("object: MuxTab", "config/lua/MuxTab"),
|
|
Page("object: PaneInformation", "config/lua/PaneInformation.md"),
|
|
Page("object: TabInformation", "config/lua/TabInformation.md"),
|
|
Page("object: SshDomain", "config/lua/SshDomain.md"),
|
|
Page("object: SpawnCommand", "config/lua/SpawnCommand.md"),
|
|
Gen("object: Time", "config/lua/wezterm.time/Time"),
|
|
Page("object: TlsDomainClient", "config/lua/TlsDomainClient.md"),
|
|
Page("object: TlsDomainServer", "config/lua/TlsDomainServer.md"),
|
|
Gen(
|
|
"object: Pane",
|
|
"config/lua/pane",
|
|
),
|
|
Gen(
|
|
"object: Window",
|
|
"config/lua/window",
|
|
),
|
|
Page("object: WslDomain", "config/lua/WslDomain.md"),
|
|
Gen(
|
|
"events: Gui",
|
|
"config/lua/gui-events",
|
|
),
|
|
Gen(
|
|
"events: Multiplexer",
|
|
"config/lua/mux-events",
|
|
),
|
|
Gen(
|
|
"events: Window",
|
|
"config/lua/window-events",
|
|
),
|
|
],
|
|
),
|
|
Page(
|
|
"CLI Reference",
|
|
"cli/general.md",
|
|
children=[
|
|
Gen("wezterm cli", "cli/cli"),
|
|
Page("wezterm connect", "cli/connect.md"),
|
|
Page("wezterm imgcat", "cli/imgcat.md"),
|
|
Page("wezterm ls-fonts", "cli/ls-fonts.md"),
|
|
Page("wezterm record", "cli/record.md"),
|
|
Page("wezterm replay", "cli/replay.md"),
|
|
Page("wezterm serial", "cli/serial.md"),
|
|
Page("wezterm set-working-directory", "cli/set-working-directory.md"),
|
|
Page("wezterm show-keys", "cli/show-keys.md"),
|
|
Page("wezterm ssh", "cli/ssh.md"),
|
|
Page("wezterm start", "cli/start.md"),
|
|
],
|
|
),
|
|
Page(
|
|
"Reference",
|
|
None,
|
|
children=[
|
|
Page("Escape Sequences", "escape-sequences.md"),
|
|
Page("What is a Terminal?", "what-is-a-terminal.md"),
|
|
],
|
|
),
|
|
Page(
|
|
"Get Help",
|
|
None,
|
|
children=[
|
|
Page("Troubleshooting", "troubleshooting.md"),
|
|
Page("F.A.Q.", "faq.md"),
|
|
Page("Getting Help", "help.md"),
|
|
Page("Contributing", "contributing.md"),
|
|
],
|
|
),
|
|
Page("Change Log", "changelog.md"),
|
|
Page("Sponsor", "sponsor.md"),
|
|
]
|
|
|
|
os.chdir("docs")
|
|
|
|
with open("../mkdocs.yml", "w") as f:
|
|
f.write("# this is auto-generated by docs/generate-toc.py, do not edit\n")
|
|
f.write("INHERIT: docs/mkdocs-base.yml\n")
|
|
f.write("nav:\n")
|
|
for page in TOC:
|
|
page.render(f, depth=1, mode="mkdocs")
|
|
|
|
|
|
with open("SUMMARY.md", "w") as f:
|
|
f.write("[root](index.md)\n")
|
|
for page in TOC:
|
|
page.render(f, depth=1, mode="mdbook")
|