新增1.0和2.0两种协议车型车型

This commit is contained in:
ykkokluo
2026-07-17 13:36:01 +08:00
parent a0dc1e6cd0
commit a28bc68e23
62 changed files with 12638 additions and 203 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+209
View File
@@ -0,0 +1,209 @@
# Export MagFass2Car guide Markdown to PDF (requires Chrome or Edge)
param(
[string]$InputMd = "$PSScriptRoot\MagFass2Car使用指南.md",
[string]$OutputPdf = "$PSScriptRoot\MagFass2Car使用指南.pdf"
)
$ErrorActionPreference = 'Stop'
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
function Escape-Html([string]$text) {
return [System.Net.WebUtility]::HtmlEncode($text)
}
function Convert-MarkdownToHtml([string]$markdown) {
$lines = $markdown -split "`r?`n"
$sb = New-Object System.Text.StringBuilder
$inCode = $false
$inTable = $false
$tableRows = New-Object System.Collections.Generic.List[string[]]
$inList = $false
$listOrdered = $false
function Flush-Table {
param($builder, [ref]$inTableRef, $rows)
if (-not $inTableRef.Value) { return }
[void]$builder.AppendLine('<table>')
for ($i = 0; $i -lt $rows.Count; $i++) {
$cells = $rows[$i]
$tag = if ($i -eq 0) { 'th' } else { 'td' }
if ($i -eq 0) { [void]$builder.AppendLine('<thead><tr>') } elseif ($i -eq 1) { [void]$builder.AppendLine('<tbody><tr>') } else { [void]$builder.AppendLine('<tr>') }
foreach ($cell in $cells) {
$cellHtml = Escape-Html($cell.Trim())
$cellHtml = $cellHtml -replace '`([^`]+)`', '<code>$1</code>'
[void]$builder.AppendLine("<$tag>$cellHtml</$tag>")
}
[void]$builder.AppendLine('</tr>')
if ($i -eq 0) { [void]$builder.AppendLine('</thead>') }
}
if ($rows.Count -gt 1) { [void]$builder.AppendLine('</tbody>') }
[void]$builder.AppendLine('</table>')
$rows.Clear()
$inTableRef.Value = $false
}
function Close-List {
param($builder, [ref]$inListRef, [ref]$orderedRef)
if (-not $inListRef.Value) { return }
if ($orderedRef.Value) { [void]$builder.AppendLine('</ol>') } else { [void]$builder.AppendLine('</ul>') }
$inListRef.Value = $false
$orderedRef.Value = $false
}
foreach ($line in $lines) {
if ($line -match '^\s*```') {
if ($inCode) {
[void]$sb.AppendLine('</code></pre>')
$inCode = $false
} else {
Flush-Table $sb ([ref]$inTable) $tableRows
Close-List $sb ([ref]$inList) ([ref]$listOrdered)
[void]$sb.AppendLine('<pre><code>')
$inCode = $true
}
continue
}
if ($inCode) {
[void]$sb.AppendLine((Escape-Html $line))
continue
}
if ($line -match '^\s*\|(.+)\|\s*$') {
Close-List $sb ([ref]$inList) ([ref]$listOrdered)
if ($line -match '^\s*\|[-:\s|]+\|\s*$') { continue }
$cells = ($line.Trim('|') -split '\|') | ForEach-Object { $_.Trim() }
$tableRows.Add($cells)
$inTable = $true
continue
} else {
Flush-Table $sb ([ref]$inTable) $tableRows
}
if ($line -match '^(#{1,6})\s+(.+)$') {
Close-List $sb ([ref]$inList) ([ref]$listOrdered)
$level = $Matches[1].Length
$text = $Matches[2]
[void]$sb.AppendLine("<h$level>$(Escape-Html $text)</h$level>")
continue
}
if ($line -match '^>\s*(.+)$') {
Close-List $sb ([ref]$inList) ([ref]$listOrdered)
$text = $Matches[1]
[void]$sb.AppendLine("<blockquote><p>$(Escape-Html $text)</p></blockquote>")
continue
}
if ($line -match '^---\s*$') {
Close-List $sb ([ref]$inList) ([ref]$listOrdered)
[void]$sb.AppendLine('<hr/>')
continue
}
if ($line -match '^\d+\.\s+(.+)$') {
if (-not $inList) { [void]$sb.AppendLine('<ol>'); $inList = $true; $listOrdered = $true }
$text = Escape-Html $Matches[1]
$text = $text -replace '`([^`]+)`', '<code>$1</code>'
[void]$sb.AppendLine("<li>$text</li>")
continue
}
if ($line -match '^-\s+(.+)$') {
if (-not $inList) { [void]$sb.AppendLine('<ul>'); $inList = $true; $listOrdered = $false }
$text = Escape-Html $Matches[1]
$text = $text -replace '`([^`]+)`', '<code>$1</code>'
[void]$sb.AppendLine("<li>$text</li>")
continue
}
if ([string]::IsNullOrWhiteSpace($line)) {
Close-List $sb ([ref]$inList) ([ref]$listOrdered)
continue
}
Close-List $sb ([ref]$inList) ([ref]$listOrdered)
$p = Escape-Html $line
$p = $p -replace '`([^`]+)`', '<code>$1</code>'
[void]$sb.AppendLine("<p>$p</p>")
}
Flush-Table $sb ([ref]$inTable) $tableRows
Close-List $sb ([ref]$inList) ([ref]$listOrdered)
if ($inCode) { [void]$sb.AppendLine('</code></pre>') }
return $sb.ToString()
}
if (-not (Test-Path $InputMd)) {
throw "Markdown file not found: $InputMd"
}
$md = Get-Content -Path $InputMd -Raw -Encoding UTF8
$body = Convert-MarkdownToHtml $md
$htmlPath = [System.IO.Path]::ChangeExtension($OutputPdf, '.html')
$html = @"
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>MagFass2Car Guide</title>
<style>
@page { size: A4; margin: 18mm 16mm; }
body { font-family: "Microsoft YaHei", "Segoe UI", sans-serif; color: #222; line-height: 1.55; font-size: 11pt; }
h1 { font-size: 22pt; border-bottom: 2px solid #2563eb; padding-bottom: 8px; margin-top: 0; }
h2 { font-size: 16pt; color: #1e40af; margin-top: 22px; page-break-after: avoid; }
h3 { font-size: 13pt; color: #1d4ed8; margin-top: 16px; page-break-after: avoid; }
h4, h5 { font-size: 11.5pt; margin-top: 12px; page-break-after: avoid; }
p, li { orphans: 3; widows: 3; }
code, pre { font-family: Consolas, "Courier New", monospace; }
code { background: #f3f4f6; padding: 1px 4px; border-radius: 3px; font-size: 10pt; }
pre { background: #f8fafc; border: 1px solid #e5e7eb; padding: 10px; overflow-x: auto; font-size: 9.5pt; }
pre code { background: transparent; padding: 0; }
table { border-collapse: collapse; width: 100%; margin: 10px 0 14px; font-size: 10pt; page-break-inside: avoid; }
th, td { border: 1px solid #d1d5db; padding: 6px 8px; vertical-align: top; }
th { background: #eff6ff; text-align: left; }
tr:nth-child(even) td { background: #fafafa; }
blockquote { border-left: 4px solid #93c5fd; margin: 10px 0; padding: 6px 12px; color: #374151; background: #f8fafc; }
hr { border: none; border-top: 1px solid #e5e7eb; margin: 18px 0; }
ul, ol { margin: 6px 0 10px 20px; }
</style>
</head>
<body>
$body
</body>
</html>
"@
[System.IO.File]::WriteAllText($htmlPath, $html, [System.Text.UTF8Encoding]::new($false))
$browserCandidates = @(
"$env:ProgramFiles\Google\Chrome\Application\chrome.exe",
"${env:ProgramFiles(x86)}\Google\Chrome\Application\chrome.exe",
"${env:ProgramFiles(x86)}\Microsoft\Edge\Application\msedge.exe",
"$env:ProgramFiles\Microsoft\Edge\Application\msedge.exe"
)
$browser = $browserCandidates | Where-Object { Test-Path $_ } | Select-Object -First 1
if (-not $browser) {
throw "Chrome/Edge not found. HTML generated at: $htmlPath"
}
if (Test-Path $OutputPdf) { Remove-Item $OutputPdf -Force }
$resolvedHtml = (Resolve-Path -LiteralPath $htmlPath).Path
$fileUri = [System.Uri]::new($resolvedHtml).AbsoluteUri
$args = @(
"--headless=new",
"--disable-gpu",
"--no-pdf-header-footer",
"--print-to-pdf=$OutputPdf",
$fileUri
)
$proc = Start-Process -FilePath $browser -ArgumentList $args -Wait -PassThru
if ($proc.ExitCode -ne 0 -or -not (Test-Path $OutputPdf)) {
throw "PDF export failed with exit code $($proc.ExitCode). HTML: $htmlPath"
}
Write-Output "PDF: $OutputPdf"
Write-Output "HTML: $htmlPath"