"""Copy the website's current code assets verbatim and derive a Monaco palette from its CSS.
The website has highlight.js previews, not a Monaco editor. The adapter is kept
separate from these originals; this command does not modify the website.
"""
import hashlib
import json
from pathlib import Path
import re
import shutil
import subprocess
import sys
ROOT = Path(__file__).resolve().parents[3]
website = Path(sys.argv[1]).resolve()
output = ROOT / 'assets/Browser/WebsiteCode'
output.mkdir(parents=True, exist_ok=True)
files = [
('XFEStudioWebSite/wwwroot/js/docs/highlight.min.js', 'Highlight.js'),
('XFEStudioWebSite/wwwroot/js/docs/csharp.js', 'CSharp.js'),
('XFEStudioWebSite/wwwroot/css/docs/code-style.css', 'CodeStyle.css'),
('XFEStudioWebSite/wwwroot/css/docs/log.css', 'Log.css'),
('XFEStudioWebSite/wwwroot/css/docs/markdown-style.css', 'MarkdownStyle.css'),
('LICENSE.txt', 'WebsiteLicense.txt'),
]
entries = []
for source, name in files:
data = (website / source).read_bytes()
(output / name).write_bytes(data)
entries.append({'WebsitePath': source, 'Path': name, 'Bytes': len(data), 'Sha256': hashlib.sha256(data).hexdigest(), 'Verbatim': True})
# Resolve the actual article cascade. Later Log.css changes number/string;
# MarkdownStyle.css gives plain code its inherited foreground. A last-rule
# search would incorrectly override more-specific .hljs-meta .hljs-string.
computed_path = ROOT / 'build/BrowserProbe/WebsitePalette/ComputedPalette.json'
subprocess.run(['dotnet', 'run', '--project', str(ROOT / 'Tools/BrowserCompatibility/WebsitePalette/WebsitePalette.csproj'),
'-c', 'Release', '--artifacts-path', str(ROOT / 'build/CSharp/WebsitePaletteArtifacts'),
'--', str(ROOT), str(website), str(computed_path)], cwd=ROOT, check=True)
palette = json.loads(computed_path.read_text('utf-8-sig'))
rules = palette['Rules']
palette_data = 'globalThis.xfeWebsiteCodePalette=' + json.dumps(palette, ensure_ascii=False, separators=(',', ':')) + ';\n'
(output / 'CodePalette.js').write_bytes(palette_data.encode('utf-8'))
manifest = {
'Schema': 'XFESystem.WebsiteCodeAssets.V1', 'SourceRepository': str(website),
'SourceCommit': subprocess.check_output(['git', '-C', str(website), 'rev-parse', 'HEAD'], text=True).strip(),
'WebsiteHasMonaco': False, 'WebsiteHighlighter': 'Highlight.js 11.11.1 + custom csharp.js',
'Files': entries, 'CssCascadeSources': palette['CssSources'],
'DerivedPalette': {'Path': 'CodePalette.js', 'Sha256': hashlib.sha256(palette_data.encode()).hexdigest(),
'CascadeCssSha256': palette['CascadeCssSha256'], 'Source': palette['Derivation']},
'Adapter': {'Path': 'WebsiteMonaco.js', 'Sha256': hashlib.sha256((output / 'WebsiteMonaco.js').read_bytes()).hexdigest(),
'Meaning': 'Explicit new adapter; not a website script or a replacement grammar.'},
'Licenses': {'WebsiteChanges': 'Apache-2.0; WebsiteLicense.txt', 'HighlightJs': 'BSD-3-Clause; original script header retained'},
}
(output / 'Manifest.json').write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + '\n', 'utf-8')
print(json.dumps({'Output': str(output), 'VerbatimFiles': len(entries), 'PaletteRules': len(rules)}))
"""Copy the website's current code assets verbatim and derive a Monaco palette from its CSS.
The website has highlight.js previews, not a Monaco editor. The adapter is kept
separate from these originals; this command does not modify the website.
"""
import hashlib
import json
from pathlib import Path
import re
import shutil
import subprocess
import sys
ROOT = Path(__file__).resolve().parents[3]
website = Path(sys.argv[1]).resolve()
output = ROOT / 'assets/Browser/WebsiteCode'
output.mkdir(parents=True, exist_ok=True)
files = [
('XFEStudioWebSite/wwwroot/js/docs/highlight.min.js', 'Highlight.js'),
('XFEStudioWebSite/wwwroot/js/docs/csharp.js', 'CSharp.js'),
('XFEStudioWebSite/wwwroot/css/docs/code-style.css', 'CodeStyle.css'),
('XFEStudioWebSite/wwwroot/css/docs/log.css', 'Log.css'),
('XFEStudioWebSite/wwwroot/css/docs/markdown-style.css', 'MarkdownStyle.css'),
('LICENSE.txt', 'WebsiteLicense.txt'),
]
entries = []
for source, name in files:
data = (website / source).read_bytes()
(output / name).write_bytes(data)
entries.append({'WebsitePath': source, 'Path': name, 'Bytes': len(data), 'Sha256': hashlib.sha256(data).hexdigest(), 'Verbatim': True})
# Resolve the actual article cascade. Later Log.css changes number/string;
# MarkdownStyle.css gives plain code its inherited foreground. A last-rule
# search would incorrectly override more-specific .hljs-meta .hljs-string.
computed_path = ROOT / 'build/BrowserProbe/WebsitePalette/ComputedPalette.json'
subprocess.run(['dotnet', 'run', '--project', str(ROOT / 'Tools/BrowserCompatibility/WebsitePalette/WebsitePalette.csproj'),
'-c', 'Release', '--artifacts-path', str(ROOT / 'build/CSharp/WebsitePaletteArtifacts'),
'--', str(ROOT), str(website), str(computed_path)], cwd=ROOT, check=True)
palette = json.loads(computed_path.read_text('utf-8-sig'))
rules = palette['Rules']
palette_data = 'globalThis.xfeWebsiteCodePalette=' + json.dumps(palette, ensure_ascii=False, separators=(',', ':')) + ';\n'
(output / 'CodePalette.js').write_bytes(palette_data.encode('utf-8'))
manifest = {
'Schema': 'XFESystem.WebsiteCodeAssets.V1', 'SourceRepository': str(website),
'SourceCommit': subprocess.check_output(['git', '-C', str(website), 'rev-parse', 'HEAD'], text=True).strip(),
'WebsiteHasMonaco': False, 'WebsiteHighlighter': 'Highlight.js 11.11.1 + custom csharp.js',
'Files': entries, 'CssCascadeSources': palette['CssSources'],
'DerivedPalette': {'Path': 'CodePalette.js', 'Sha256': hashlib.sha256(palette_data.encode()).hexdigest(),
'CascadeCssSha256': palette['CascadeCssSha256'], 'Source': palette['Derivation']},
'Adapter': {'Path': 'WebsiteMonaco.js', 'Sha256': hashlib.sha256((output / 'WebsiteMonaco.js').read_bytes()).hexdigest(),
'Meaning': 'Explicit new adapter; not a website script or a replacement grammar.'},
'Licenses': {'WebsiteChanges': 'Apache-2.0; WebsiteLicense.txt', 'HighlightJs': 'BSD-3-Clause; original script header retained'},
}
(output / 'Manifest.json').write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + '\n', 'utf-8')
print(json.dumps({'Output': str(output), 'VerbatimFiles': len(entries), 'PaletteRules': len(rules)}))