GetNotebookContent.ps1
function Get-NotebookContent { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "", Justification="Test doesn't understand -begin script blocks. ")] <# .SYNOPSIS Get-NotebookContents reads the contents of a Jupyter Notebooks .Example Get-NotebookContent .\samplenotebook\Chapter01code.ipynb NoteBookName Type Source ------------ ---- ------ Chapter01code.ipynb markdown ## Code for chapter 1 PowerShell in Action third edition Chapter01code.ipynb markdown ## Introduction Chapter01code.ipynb code 'Hello world.' Chapter01code.ipynb code Get-ChildItem -Path $env:windir\*.log | Select-String -List error | Format-Table Path,L... Chapter01code.ipynb code ([xml] [System.Net.WebClient]::new().DownloadString('http://blogs.msdn.com/powershell/r... Chapter01code.ipynb markdown ## 1.2 PowerShell example code Chapter01code.ipynb code Get-ChildItem -Path C:\somefile.txt .Example Get-Notebook .\samplenotebook\*sharp*|Get-NotebookContent NoteBookName Type Source ------------ ---- ------ csharp.ipynb code {Console.Write("hello world")} fsharp.ipynb code {printfn "hello world"} #> [cmdletbinding(DefaultParameterSetName="MarkdownAndCode")] param( [Parameter(ValueFromPipelineByPropertyName,Position=0)] [alias('FullName','NoteBookFullName')] $Path, [parameter(ParameterSetName='JustCode')] [alias('NoMarkdown')] [Switch]$JustCode, [parameter(ParameterSetName='JustMarkdown')] [alias('NoCode')] [Switch]$JustMarkdown, [Switch]$PassThru, [Switch]$IncludeOutput ) process { #allow Path to contain more than one item, if any are wild cards call the function recursively. foreach ($p in $Path) { if ([System.Uri]::IsWellFormedUriString($p, [System.UriKind]::Absolute)) { $r = Invoke-RestMethod $p } elseif (Test-Path $p -ErrorAction SilentlyContinue) { if ((Resolve-Path $p).count -gt 1) { [void]$PSBoundParameters.Remove('Path') Get-ChildItem $p | Get-NotebookContent @PSBoundParameters continue } else { $r = Get-Content $p | ConvertFrom-Json } } if ($PassThru) { return $r} elseif ($JustCode) { $cellType = 'code' } elseif ($JustMarkdown) { $cellType = 'markdown' } else { $cellType = '.' } $cellnumber = 0 foreach ($cell in $r.cells) { $cellnumber += 1 if ($null -ne $cellType -and $cell.'cell_type' -notmatch $cellType) { continue } $IsParameterCell = $false if ($cell.metadata.tags) { if ($null -ne ($cell.metadata.tags -eq 'parameters')) { $IsParameterCell = $true } } if ($cell.metadata.dotnet_interactive) { $Language = switch ($cell.metadata.dotnet_interactive.language) { 'sql' { 'SQL' } 'pwsh' { 'PowerShell' } 'fsharp' { 'F#' } 'csharp' { 'C#' } 'html' { 'html'} Default { 'C#' } } $Language += ' (.NET Interactive)' } elseif ($cell.'cell_type' -match 'code') { $Language = $r.metadata.kernelspec.language if ($r.metadata.kernelspec.display_name -match '^\.NET\s*\(') {$Language += ' (.NET Interactive)'} } elseif ($cell.'cell_type' -match 'code') { $Language = 'markdown' } $cellObj = [Ordered]@{ Cell = $cellNumber NoteBookName = Split-Path -Leaf $p Type = $cell.'cell_type' IsParameterCell = $IsParameterCell Language = $Language Source = -join $cell.source } if ($IncludeOutput) { # There may be one or many outputs. For each output # either a single string if has a .text field containing a string or array of strings # or a hash table if it has a .data field containing .mime-type = "Content" $cellObj['Output'] = foreach ($o in $cell.outputs) { if ($o.text -join "") {$o.text -join " `r`n" } elseif ($o.data) { $o.data.psobject.properties | foreach-object -Begin {$hash=@{}} -Process {$hash[$_.name] =$_.value} -end {$hash} } } #merge the text generated by .NET Interactive in VS code - every output will be a hash table with a text/plain entry. Others do the same with Text/HTML if ( $cellObj.Output.where({$_ -is [hashtable]}) -and -not #if some are hashtables and none are not hashtables $cellObj.Output.where({$_ -isnot [hashtable]}) ){ if ($cellObj.Output.where({ $_.containskey('text/html')}) -and -not #if some have text/html and none don't. $cellObj.Output.where({-not $_.containskey('text/html')}) ) { $cellObj['HtmlOutput'] = $cellObj.output.'text/html' -join "<br />`n" #Add an HTML Output field } if ($cellObj.Output.where({ $_.containskey('text/plain')}) -and -not #if some have text/plain and none don't. $cellObj.Output.where({-not $_.containskey('text/plain')}) ) { $cellObj.Output = -join $cellobj.output.'text/plain' #Merge plain text into the output field } } } [PSCustomObject]$cellObj } } } } |