filenames

This commit is contained in:
2026-05-27 22:42:19 +08:00
parent 92de00b52e
commit 3f86aeaf0c
2 changed files with 59 additions and 7 deletions

View File

@@ -9,6 +9,7 @@ const store: { panel: vscode.WebviewPanel | null } = { panel: null };
interface ConvertOptions {
sourcePath: string;
outputDir: string;
baseName?: string;
networks: string[];
}
@@ -38,7 +39,7 @@ export function openPlayworksConverter(_context: vscode.ExtensionContext) {
if (!picked?.[0]) return;
const srcPath = picked[0].fsPath;
const dir = path.dirname(srcPath);
panel.webview.postMessage({ type: 'sourcePicked', path: srcPath, dir });
panel.webview.postMessage({ type: 'sourcePicked', path: srcPath, dir, baseName: sourceBaseName(srcPath) });
break;
}
case 'pickOutput': {
@@ -111,10 +112,17 @@ function sourceBaseName(sourcePath: string): string {
.replace(/_(?:un|al|is|fb|gg|mo|vu|mtg|tt)$/, '');
}
function outputBaseName(opts: ConvertOptions): string {
const rawBaseName = opts.baseName?.trim() || sourceBaseName(opts.sourcePath);
const withoutExtension = rawBaseName.replace(/\.html?$/i, '');
const safeBaseName = path.basename(withoutExtension).replace(/[<>:"/\\|?*]/g, '_').trim();
return safeBaseName || sourceBaseName(opts.sourcePath);
}
async function convertNetwork(html: string, opts: ConvertOptions, network: string): Promise<string> {
const transformed = transformHtml(html, network);
const needsZip = ZIPPED_NETWORKS.has(network);
const baseName = sourceBaseName(opts.sourcePath);
const baseName = outputBaseName(opts);
const htmlFileName = `${baseName}_${network}.html`;
const outputDir = path.join(opts.outputDir, NETWORK_OUTPUT_FOLDERS[network] ?? network);
fs.mkdirSync(outputDir, { recursive: true });
@@ -384,6 +392,13 @@ function getHtml(): string {
</div>
</div>
<div class="section">
<div class="section-label">Base Filename</div>
<div class="row">
<input id="baseName" type="text" placeholder="Base filename..." />
</div>
</div>
<div class="section">
<div class="section-label">Output Folder</div>
<div class="row">
@@ -417,6 +432,7 @@ function getHtml(): string {
const srcEl = document.getElementById('src');
const outEl = document.getElementById('outDir');
const baseNameEl = document.getElementById('baseName');
const convertBtn = document.getElementById('convert');
const openOutBtn = document.getElementById('openOut');
const statusEl = document.getElementById('status');
@@ -424,7 +440,7 @@ function getHtml(): string {
function updateConvertBtn() {
const hasNet = [...document.querySelectorAll('.net-cb')].some(c => c.checked);
convertBtn.disabled = !srcEl.value || !outEl.value || !hasNet;
convertBtn.disabled = !srcEl.value || !outEl.value || !baseNameEl.value.trim() || !hasNet;
}
document.getElementById('pickSrc').addEventListener('click', () => vscode.postMessage({ type: 'pickSource' }));
@@ -439,6 +455,7 @@ function getHtml(): string {
});
document.querySelectorAll('.net-cb').forEach(c => c.addEventListener('change', updateConvertBtn));
outEl.addEventListener('input', updateConvertBtn);
baseNameEl.addEventListener('input', updateConvertBtn);
openOutBtn.addEventListener('click', () => {
if (outputDir) vscode.postMessage({ type: 'openOutput', dir: outputDir });
@@ -461,6 +478,7 @@ function getHtml(): string {
opts: {
sourcePath: srcEl.value,
outputDir: outEl.value,
baseName: baseNameEl.value,
networks,
},
});
@@ -470,6 +488,7 @@ function getHtml(): string {
const msg = event.data;
if (msg.type === 'sourcePicked') {
srcEl.value = msg.path;
baseNameEl.value = msg.baseName || '';
if (!outEl.value && msg.dir) {
outEl.value = msg.dir;
outputDir = msg.dir;

View File

@@ -14,6 +14,7 @@ import (
type playworksConvertOptions struct {
SourcePath string `json:"sourcePath"`
OutputDir string `json:"outputDir"`
BaseName string `json:"baseName"`
Networks []string `json:"networks"`
}
@@ -60,6 +61,13 @@ func PlayworksPage(w http.ResponseWriter, r *http.Request) {
</div>
</div>
<div class="section">
<div class="section-label">Base Filename</div>
<div class="row">
<input id="baseName" type="text" placeholder="Base filename..." style="flex:1;" />
</div>
</div>
<div class="section">
<div class="section-label">Output Folder</div>
<div class="row">
@@ -101,6 +109,7 @@ func PlayworksPage(w http.ResponseWriter, r *http.Request) {
let outputDir = '';
const srcEl = document.getElementById('src');
const outEl = document.getElementById('outDir');
const baseNameEl = document.getElementById('baseName');
const convertBtn = document.getElementById('convert');
const openOutBtn = document.getElementById('openOut');
const statusEl = document.getElementById('status');
@@ -108,7 +117,7 @@ const resultsEl = document.getElementById('results');
function updateConvertBtn() {
const hasNet = [...document.querySelectorAll('.net-cb')].some(c => c.checked);
convertBtn.disabled = !srcEl.value || !outEl.value || !hasNet;
convertBtn.disabled = !srcEl.value || !outEl.value || !baseNameEl.value.trim() || !hasNet;
}
document.getElementById('pickSrc').addEventListener('click', async () => {
@@ -116,6 +125,7 @@ document.getElementById('pickSrc').addEventListener('click', async () => {
const j = await r.json();
if (j.path) {
srcEl.value = j.path;
baseNameEl.value = j.baseName || '';
if (!outEl.value && j.dir) { outEl.value = j.dir; outputDir = j.dir; }
updateConvertBtn();
}
@@ -135,6 +145,7 @@ document.getElementById('selectNone').addEventListener('click', () => {
});
document.querySelectorAll('.net-cb').forEach(c => c.addEventListener('change', updateConvertBtn));
outEl.addEventListener('input', updateConvertBtn);
baseNameEl.addEventListener('input', updateConvertBtn);
openOutBtn.addEventListener('click', () => {
if (outputDir) fetch('/api/open', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({ url: outputDir }) });
});
@@ -153,7 +164,7 @@ document.getElementById('convert').addEventListener('click', async () => {
const res = await fetch('/api/playworks/convert', {
method:'POST',
headers:{'Content-Type':'application/json'},
body: JSON.stringify({ sourcePath: srcEl.value, outputDir: outEl.value, networks })
body: JSON.stringify({ sourcePath: srcEl.value, outputDir: outEl.value, baseName: baseNameEl.value, networks })
});
const msg = await res.json();
convertBtn.disabled = false;
@@ -197,7 +208,7 @@ func PlayworksPickSource(w http.ResponseWriter, r *http.Request) {
writeJSON(w, map[string]any{})
return
}
writeJSON(w, map[string]any{"path": picked[0], "dir": filepath.Dir(picked[0])})
writeJSON(w, map[string]any{"path": picked[0], "dir": filepath.Dir(picked[0]), "baseName": playworksSourceBaseName(picked[0])})
}
func PlayworksPickOutput(w http.ResponseWriter, r *http.Request) {
@@ -243,9 +254,31 @@ func playworksSourceBaseName(sourcePath string) string {
return playworksSuffixRx.ReplaceAllString(base, "")
}
func playworksOutputBaseName(opts playworksConvertOptions) string {
baseName := strings.TrimSpace(opts.BaseName)
if baseName == "" {
baseName = playworksSourceBaseName(opts.SourcePath)
}
baseName = strings.TrimSuffix(baseName, filepath.Ext(baseName))
baseName = filepath.Base(baseName)
baseName = strings.Map(func(r rune) rune {
switch r {
case '<', '>', ':', '"', '/', '\\', '|', '?', '*':
return '_'
default:
return r
}
}, baseName)
baseName = strings.TrimSpace(baseName)
if baseName == "" {
return playworksSourceBaseName(opts.SourcePath)
}
return baseName
}
func convertPlayworksNetwork(htmlSrc string, opts playworksConvertOptions, network string) (string, error) {
transformed := transformPlayworksHTML(htmlSrc, network)
baseName := playworksSourceBaseName(opts.SourcePath)
baseName := playworksOutputBaseName(opts)
htmlFileName := fmt.Sprintf("%s_%s.html", baseName, network)
outputDir := filepath.Join(opts.OutputDir, playworksNetworkOutputFolder(network))
if err := os.MkdirAll(outputDir, 0755); err != nil {