88 lines
3.0 KiB
PowerShell
88 lines
3.0 KiB
PowerShell
[CmdletBinding()]
|
||
param()
|
||
|
||
$ErrorActionPreference = 'Stop'
|
||
$outputPath = Join-Path $PSScriptRoot 'index.html'
|
||
$sourceDirectory = Join-Path $PSScriptRoot 'protocan'
|
||
$documents = @(
|
||
'README.md',
|
||
'PROTOCOL.md',
|
||
'BOOTLOADER.md',
|
||
'OAP.md',
|
||
'CHANGELOG.md'
|
||
)
|
||
|
||
function Convert-LocalLinks {
|
||
param(
|
||
[string]$Html,
|
||
[string]$SourcePath
|
||
)
|
||
|
||
$sourceParent = Split-Path -Parent $SourcePath
|
||
$outputParent = Split-Path -Parent $outputPath
|
||
$pattern = '(?<attribute>href|src)="(?<target>(?![a-z]+:|/|#)[^"]+)"'
|
||
|
||
return [regex]::Replace($Html, $pattern, {
|
||
param($match)
|
||
|
||
$target = $match.Groups['target'].Value
|
||
$parts = $target -split '#', 2
|
||
$targetPath = [Uri]::UnescapeDataString($parts[0])
|
||
$absoluteTarget = [System.IO.Path]::GetFullPath((Join-Path $sourceParent $targetPath))
|
||
$relativeTarget = [System.IO.Path]::GetRelativePath($outputParent, $absoluteTarget).Replace('\', '/')
|
||
if ($parts.Count -eq 2) {
|
||
$relativeTarget += '#' + $parts[1]
|
||
}
|
||
|
||
return $match.Groups['attribute'].Value + '="' + $relativeTarget + '"'
|
||
})
|
||
}
|
||
|
||
$sections = foreach ($document in $documents) {
|
||
$path = Join-Path $sourceDirectory $document
|
||
$markdown = Get-Content -Raw -LiteralPath $path -Encoding UTF8
|
||
$html = (ConvertFrom-Markdown -InputObject $markdown).Html
|
||
$html = Convert-LocalLinks -Html $html -SourcePath $path
|
||
"<article class=`"card protocan-document`" data-source=`"$document`">$html</article>"
|
||
}
|
||
|
||
$vectorsPath = Join-Path $sourceDirectory 'examples\test-vectors.json'
|
||
$vectors = [System.Net.WebUtility]::HtmlEncode(
|
||
(Get-Content -Raw -LiteralPath $vectorsPath -Encoding UTF8)
|
||
)
|
||
$sections += @"
|
||
<article class="card protocan-document" data-source="examples/test-vectors.json">
|
||
<h1>Тестовые векторы</h1>
|
||
<p>Машинные эталоны из <code>examples/test-vectors.json</code>.</p>
|
||
<pre><code>$vectors</code></pre>
|
||
</article>
|
||
"@
|
||
|
||
$generatedBlock = @"
|
||
<!-- PROTOCAN:START -->
|
||
<section id="protocan-full" class="section">
|
||
<h2>Полная документация ProtoCAN</h2>
|
||
<p class="lead">Нормативные документы и тестовые векторы собраны в эту страницу из исходников <code>doc/setcan/protocan</code>.</p>
|
||
<div class="grid protocan-grid">
|
||
$($sections -join "`n")
|
||
</div>
|
||
</section>
|
||
<!-- PROTOCAN:END -->
|
||
"@
|
||
|
||
$page = Get-Content -Raw -LiteralPath $outputPath -Encoding UTF8
|
||
$pattern = '(?s)<!-- PROTOCAN:START -->.*?<!-- PROTOCAN:END -->'
|
||
if ($page -notmatch $pattern) {
|
||
throw 'Не найдены маркеры PROTOCAN:START/END в doc/setcan/index.html.'
|
||
}
|
||
|
||
$page = [regex]::Replace($page, $pattern, [System.Text.RegularExpressions.MatchEvaluator]{
|
||
param($match)
|
||
$generatedBlock
|
||
}, 1)
|
||
|
||
$page = $page.TrimEnd("`r", "`n") + [Environment]::NewLine
|
||
$utf8WithoutBom = [System.Text.UTF8Encoding]::new($false)
|
||
[System.IO.File]::WriteAllText($outputPath, $page, $utf8WithoutBom)
|
||
Write-Host "[DONE] Создан единый HTML: $outputPath"
|