Skip to content

Commit 04764a9

Browse files
azure-sdkswathipil
andauthored
add psscript to convert apiview json files to md (#45589)
Co-authored-by: swathipil <swathip@microsoft.com>
1 parent 50e0165 commit 04764a9

1 file changed

Lines changed: 155 additions & 0 deletions

File tree

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
<#
5+
.SYNOPSIS
6+
Converts an APIView token JSON file into a markdown file.
7+
8+
.DESCRIPTION
9+
Reads an APIView token JSON file (tree-style format) and renders its ReviewLines into
10+
a fenced markdown code block. This script is language-agnostic and works with token
11+
files produced by any APIView parser.
12+
13+
.PARAMETER TokenJsonPath
14+
Required. Path to the input APIView token JSON file.
15+
16+
.PARAMETER OutputPath
17+
Required. Path to write the output markdown file. If a directory is given, the file will be
18+
named api.md inside that directory.
19+
20+
.EXAMPLE
21+
./Export-APIViewMarkdown.ps1 -TokenJsonPath ./azure-core_python.json -OutputPath ./api.md
22+
23+
.EXAMPLE
24+
./Export-APIViewMarkdown.ps1 -TokenJsonPath ./azure-sdk_java.json -OutputPath ./output/
25+
#>
26+
27+
[CmdletBinding()]
28+
param(
29+
[Parameter(Mandatory = $true)]
30+
[string]$TokenJsonPath,
31+
32+
[Parameter(Mandatory = $true)]
33+
[string]$OutputPath
34+
)
35+
36+
Set-StrictMode -Version 3
37+
$ErrorActionPreference = 'Stop'
38+
39+
function Render-Token {
40+
<#
41+
.SYNOPSIS
42+
Renders a single ReviewToken object to a string, applying HasPrefixSpace and HasSuffixSpace.
43+
#>
44+
param([PSCustomObject]$Token)
45+
46+
$prefix = if ($Token.HasPrefixSpace -eq $true) { " " } else { "" }
47+
$suffix = if ($Token.HasSuffixSpace -eq $true) { " " } else { "" }
48+
return "$prefix$($Token.Value)$suffix"
49+
}
50+
51+
function Render-ReviewLines {
52+
<#
53+
.SYNOPSIS
54+
Recursively renders a list of ReviewLine objects into an array of strings.
55+
#>
56+
param(
57+
[object[]]$ReviewLines,
58+
[int]$IndentLevel = 0
59+
)
60+
61+
$result = [System.Collections.Generic.List[string]]::new()
62+
$indent = " " * $IndentLevel
63+
64+
foreach ($line in $ReviewLines) {
65+
$tokens = @($line.Tokens)
66+
67+
if ($tokens.Count -eq 0) {
68+
# Blank line
69+
$result.Add("")
70+
}
71+
else {
72+
$lineText = ($tokens | ForEach-Object { Render-Token $_ }) -join ""
73+
if ($lineText.Trim() -ne "") {
74+
$result.Add("$indent$lineText")
75+
}
76+
else {
77+
$result.Add("")
78+
}
79+
}
80+
81+
# Recursively render children with increased indentation
82+
$childrenProp = $line.PSObject.Properties.Item('Children')
83+
if ($null -ne $childrenProp -and $null -ne $childrenProp.Value -and $childrenProp.Value.Count -gt 0) {
84+
$childLines = Render-ReviewLines -ReviewLines $childrenProp.Value -IndentLevel ($IndentLevel + 1)
85+
foreach ($childLine in $childLines) {
86+
$result.Add($childLine)
87+
}
88+
}
89+
}
90+
91+
return $result
92+
}
93+
94+
# --- Main ---
95+
96+
if (-not (Test-Path $TokenJsonPath)) {
97+
Write-Error "Token JSON file not found: $TokenJsonPath"
98+
exit 1
99+
}
100+
101+
$tokenJson = Get-Content -Path $TokenJsonPath -Raw | ConvertFrom-Json
102+
103+
if (-not $tokenJson.ReviewLines) {
104+
Write-Error "The token JSON file does not contain a 'ReviewLines' property."
105+
exit 1
106+
}
107+
108+
# Resolve output path: if a directory is given, default filename to api.md
109+
if (Test-Path $OutputPath -PathType Container) {
110+
$OutputPath = Join-Path $OutputPath "api.md"
111+
}
112+
elseif (-not [System.IO.Path]::HasExtension($OutputPath)) {
113+
$OutputPath = Join-Path $OutputPath "api.md"
114+
}
115+
116+
# Read language from the token JSON, falling back to empty string
117+
$language = if ($tokenJson.PSObject.Properties.Item('Language') -and $tokenJson.Language) {
118+
$tokenJson.Language.ToLower()
119+
} else {
120+
""
121+
}
122+
123+
# Map full language names to common code fence identifiers
124+
$languageAliases = @{
125+
"python" = "py"
126+
"javascript" = "js"
127+
"typescript" = "ts"
128+
}
129+
if ($languageAliases.ContainsKey($language)) {
130+
$language = $languageAliases[$language]
131+
}
132+
133+
$reviewLines = @($tokenJson.ReviewLines)
134+
$renderedLines = Render-ReviewLines -ReviewLines $reviewLines
135+
136+
$fenceOpen = "``````$language"
137+
$fenceClose = "``````"
138+
139+
$outputLines = [System.Collections.Generic.List[string]]::new()
140+
$outputLines.Add($fenceOpen)
141+
foreach ($line in $renderedLines) {
142+
$outputLines.Add($line)
143+
}
144+
$outputLines.Add($fenceClose)
145+
146+
$outputContent = $outputLines -join "`n"
147+
148+
$outputDir = Split-Path -Parent $OutputPath
149+
if ($outputDir -and -not (Test-Path $outputDir)) {
150+
New-Item -ItemType Directory -Path $outputDir -Force | Out-Null
151+
}
152+
153+
Set-Content -Path $OutputPath -Value $outputContent -NoNewline -Encoding utf8
154+
155+
Write-Host "Generated markdown: $OutputPath"

0 commit comments

Comments
 (0)