Public/Get-XKCDExplanation.ps1
|
function Get-XKCDExplanation { <# .SYNOPSIS Gets the explanation of a comic from the explain xkcd wiki: https://www.explainxkcd.com/. .DESCRIPTION The Get-XKCDExplanation cmdlet uses the explain xkcd wiki's MediaWiki API to retrieve a comic's "Explanation" section, and optionally its "Transcript" section and reader "Discussion" (from its explain xkcd talk page), returning them as plain text, with the wiki markup used by the site stripped out for readability. By default, only the Explanation is retrieved. Use -Transcript and/or -Discussion to also retrieve those sections on the returned object, or -Full to always retrieve all three. Sections that aren't requested are never fetched from the API (saving a request each) and are omitted from the returned object entirely, rather than being included empty. With -Show (or on Show-XKCDExplanation), -Explanation, -Transcript, and -Discussion each display just that one section -- e.g. -Show -Transcript on its own displays just the transcript, not the explanation. Combine them to display more than one, or use -Full to always display all three. Each displayed section is given its own heading. These same switches determine what's fetched as well as what's displayed, so -Show never retrieves a section it isn't about to show. With -Show, -Explanation, -Transcript, and -Discussion (without -Full) display text sections only, without fetching or showing the comic image -- the title and a link to the explanation are still shown. Use -Full with -Show to always display the comic image alongside every section. By default, Get-XKCDExplanation returns the explanation of the latest available comic. Use -Random to get a random comic instead (optionally within a -Min/-Max range), or -Newest to get the specified number of most recent comics. Use the -Num parameter to specify one or more specific comics to return. .EXAMPLE Get-XKCDExplanation This command gets the explanation of the latest XKCD comic. .EXAMPLE Get-XKCDExplanation 2000 This command returns the explanation of the 2000th XKCD comic. .EXAMPLE Get-XKCD -Random | Get-XKCDExplanation This command gets a random comic and then returns its explanation. .EXAMPLE Get-XKCDExplanation -Random -Min 100 -Max 150 This command returns the explanation of a random comic numbered between 100 and 150. .EXAMPLE Get-XKCDExplanation -Newest 5 This command returns the explanation of the latest 5 comics. .EXAMPLE (Get-XKCDExplanation 2000 -Transcript).Transcript This command returns just the transcript of comic number 2000. -Transcript is required to retrieve it -- by default only the Explanation is fetched and returned. .EXAMPLE Get-XKCDExplanation -Num 1 -Full -Show This command displays the title, image, explanation, transcript, and discussion of comic number 1 directly in the console, each under its own heading (image display requires your terminal to support the Sixel, Kitty, or iTerm2 inline image protocol). Unlike other parameter combinations, -Show does not return the explanation object. .EXAMPLE Get-XKCDExplanation -Num 1 -Explanation -Show This command displays just the explanation of comic number 1 as text, along with its title and a link, without fetching or displaying the comic image. .EXAMPLE Get-XKCDExplanation -Open This command returns the explanation of the latest comic and opens it in your default web browser. .LINK https://www.explainxkcd.com/wiki/index.php/Main_Page #> [cmdletbinding(DefaultParameterSetName = 'Specific')] Param( # Gets the explanation of a random comic. [Parameter(ParameterSetName = 'Random')] [switch] $Random, # Use with -Random to define a lower bound range within which to return a comic. [Parameter(ParameterSetName = 'Random')] [int] $Min = 1, # Use with -Random to define an upper bound range within which to return a comic. -Max is the latest comic number by default. [Parameter(ParameterSetName = 'Random')] [int] $Max, # Gets the explanation of the specified number of the most recent comics. [Parameter(ParameterSetName = 'Newest')] [int] $Newest, # Opens the comic/s in your default web browser. [switch] $Open, # Retrieves, and with -Show displays, the comic's "Explanation" section. The Explanation is always # retrieved regardless of this switch -- it only affects what -Show displays, where combining it with # -Transcript and/or -Discussion displays more than one section. Defaults to the value saved with # Set-XKCDDefault -Explanation, if any. [switch] $Explanation = (Get-XKCDDefaultValue -Name 'Explanation' -Value $false), # Retrieves, and with -Show displays, the comic's "Transcript" section. Without this switch (or -Full), # the Transcript is not fetched and its property is omitted from the returned object entirely. Combine # with -Explanation and/or -Discussion to display more than one section with -Show. Defaults to the # value saved with Set-XKCDDefault -Transcript, if any. [switch] $Transcript = (Get-XKCDDefaultValue -Name 'Transcript' -Value $false), # Retrieves, and with -Show displays, the comic's reader "Discussion", from its explain xkcd talk page. # Without this switch (or -Full), the Discussion is not fetched and its property is omitted from the # returned object entirely. Combine with -Explanation and/or -Transcript to display more than one # section with -Show. Defaults to the value saved with Set-XKCDDefault -Discussion, if any. [switch] $Discussion = (Get-XKCDDefaultValue -Name 'Discussion' -Value $false), # Retrieves, and with -Show displays, all of the explanation, transcript, and discussion sections. # Defaults to the value saved with Set-XKCDDefault -Full, if any. [switch] $Full = (Get-XKCDDefaultValue -Name 'Full' -Value $false), # Displays the comic's title, image, and retrieved sections in the console instead of returning the # explanation object. Image display requires your terminal to support the Sixel, Kitty, or iTerm2 # inline image graphics protocol. [switch] $Show, # Use with -Show to display the higher resolution (_2x) version of the image, where available. Comics # that do not have a higher resolution version are displayed at the standard quality instead. Defaults # to the value saved with Set-XKCDDefault -HighQuality, if any. [switch] $HighQuality = (Get-XKCDDefaultValue -Name 'HighQuality' -Value $false), # The base URL of the explain xkcd wiki's MediaWiki API. [string] $ApiUrl = 'https://www.explainxkcd.com/wiki/api.php', # Gets the explanation of the specified comics. Accepts array input. By default the latest comic is used. [Parameter(ParameterSetName = 'Specific', ValueFromPipeline, ValueFromPipelineByPropertyName, Position = 0)] [int[]] $Num = $Max, # Bypass the confirmation check if you try to open more than 9 comics in your browser. [switch] $Force ) Begin { if (-not $Max) { $Max = (Invoke-RestMethod 'https://xkcd.com/info.0.json').num } if ($Random) { $Num = Get-Random -min $Min -max $Max } if ($Newest) { $Num = (($Max - $Newest) + 1)..$Max } if (-not $Num) { $Num = $Max } } Process { $Num | ForEach-Object { $ID = $_ if ($Show) { Show-XKCDExplanation -Num $ID -Explanation:$Explanation -Transcript:$Transcript -Discussion:$Discussion -Full:$Full -HighQuality:$HighQuality } else { $Sections = (Invoke-RestMethod "${ApiUrl}?action=parse&page=$ID&redirects=1&prop=sections&format=json").parse if (-not $Sections) { Write-Warning "No explanation was found for comic #$ID at $ApiUrl" } else { $ExplanationSection = $Sections.sections | Where-Object { $_.line -eq 'Explanation' } | Select-Object -First 1 $SectionIndex = if ($ExplanationSection) { $ExplanationSection.index } else { 0 } $Wikitext = (Invoke-RestMethod "${ApiUrl}?action=parse&page=$ID&redirects=1&prop=wikitext§ion=$SectionIndex&format=json").parse.wikitext.'*' $ExplanationProperties = [ordered]@{ Num = $ID Title = $Sections.title -replace '^\d+:\s*', '' Url = "https://www.explainxkcd.com/wiki/index.php/$ID" Explanation = ConvertTo-XKCDPlainText -WikiText $Wikitext } # Transcript and Discussion each cost an extra API call, so they're only fetched -- and only # added to the returned object -- when actually requested via -Transcript/-Discussion/-Full. if ($Transcript -or $Full) { $TranscriptSection = $Sections.sections | Where-Object { $_.line -eq 'Transcript' } | Select-Object -First 1 $ExplanationProperties.Transcript = if ($TranscriptSection) { $TranscriptWikitext = (Invoke-RestMethod "${ApiUrl}?action=parse&page=$ID&redirects=1&prop=wikitext§ion=$($TranscriptSection.index)&format=json").parse.wikitext.'*' ConvertTo-XKCDPlainText -WikiText $TranscriptWikitext } else { '' } } if ($Discussion -or $Full) { $TalkTitle = [uri]::EscapeDataString("Talk:$($Sections.title)") $TalkParse = (Invoke-RestMethod "${ApiUrl}?action=parse&page=$TalkTitle&prop=wikitext&format=json").parse $ExplanationProperties.Discussion = if ($TalkParse) { ConvertTo-XKCDPlainText -WikiText $TalkParse.wikitext.'*' } else { '' } } [pscustomobject]$ExplanationProperties } } if ($Open) { if ($Num.count -ge 10 -and -not $Force) { if (-not $confirmation) { $confirmation = Read-Host "This will open $($Num.count) comics in your default browser. Are you sure you want to proceed? [y|n]" } } if ($confirmation -eq 'y' -or $Num.count -lt 10 -or $Force) { Start-Process "https://xkcd.com/$ID" } } } } } |