From afdf982c5aac8974d2640cdb5e102995c010c633 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Wed, 18 Mar 2026 15:19:03 -0700 Subject: [PATCH 1/5] feat: Simplifying OpenGraph module scaffolding ( Fixes #14 ) --- .github/workflows/OpenGraph-Build.yml | 21 +++++---------------- OpenGraph.ps.psm1 | 26 -------------------------- OpenGraph.psm1 | 23 +---------------------- 3 files changed, 6 insertions(+), 64 deletions(-) delete mode 100644 OpenGraph.ps.psm1 diff --git a/.github/workflows/OpenGraph-Build.yml b/.github/workflows/OpenGraph-Build.yml index dd5dc5d..1f4c001 100644 --- a/.github/workflows/OpenGraph-Build.yml +++ b/.github/workflows/OpenGraph-Build.yml @@ -35,7 +35,7 @@ jobs: Install-Module -Name Pester -Repository PSGallery -Force -Scope CurrentUser -MaximumVersion $PesterMaxVersion -SkipPublisherCheck -AllowClobber Import-Module Pester -Force -PassThru -MaximumVersion $PesterMaxVersion} @Parameters - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@v2 - name: RunPester id: RunPester shell: pwsh @@ -92,6 +92,9 @@ jobs: $result = Invoke-Pester -PassThru -Verbose -OutputFile ".\$moduleName.TestResults.xml" -OutputFormat NUnitXml @codeCoverageParameters + "::set-output name=TotalCount::$($result.TotalCount)", + "::set-output name=PassedCount::$($result.PassedCount)", + "::set-output name=FailedCount::$($result.FailedCount)" | Out-Host if ($result.FailedCount -gt 0) { "::debug:: $($result.FailedCount) tests failed" foreach ($r in $result.TestResult) { @@ -490,21 +493,7 @@ jobs: if: ${{ success() }} steps: - name: Check out repository - uses: actions/checkout@v2 - - name: GitLogger - uses: GitLogging/GitLoggerAction@main - id: GitLogger - - name: Use PSSVG Action - uses: StartAutomating/PSSVG@main - id: PSSVG - - name: Use PipeScript Action - uses: StartAutomating/PipeScript@main - id: PipeScript + uses: actions/checkout@main - name: UseEZOut uses: StartAutomating/EZOut@master - - name: UseHelpOut - uses: StartAutomating/HelpOut@master - - name: Use PSJekyll Action - uses: PowerShellWeb/PSJekyll@main - id: PSJekyll diff --git a/OpenGraph.ps.psm1 b/OpenGraph.ps.psm1 deleted file mode 100644 index 562e155..0000000 --- a/OpenGraph.ps.psm1 +++ /dev/null @@ -1,26 +0,0 @@ -$commandsPath = Join-Path $PSScriptRoot Commands -[include('*-*')]$commandsPath - -$myModule = $MyInvocation.MyCommand.ScriptBlock.Module -$ExecutionContext.SessionState.PSVariable.Set($myModule.Name, $myModule) -$myModule.pstypenames.insert(0, $myModule.Name) - -New-PSDrive -Name $MyModule.Name -PSProvider FileSystem -Scope Global -Root $PSScriptRoot -ErrorAction Ignore - -if ($home) { - $MyModuleProfileDirectory = Join-Path ([Environment]::GetFolderPath("LocalApplicationData")) $MyModule.Name - if (-not (Test-Path $MyModuleProfileDirectory)) { - $null = New-Item -ItemType Directory -Path $MyModuleProfileDirectory -Force - } - New-PSDrive -Name "My$($MyModule.Name)" -PSProvider FileSystem -Scope Global -Root $MyModuleProfileDirectory -ErrorAction Ignore -} - -# Set a script variable of this, set to the module -# (so all scripts in this scope default to the correct `$this`) -$script:this = $myModule - -#region Custom -#endregion Custom - -Export-ModuleMember -Alias * -Function * -Variable $myModule.Name - diff --git a/OpenGraph.psm1 b/OpenGraph.psm1 index 41a1efb..a3604cf 100644 --- a/OpenGraph.psm1 +++ b/OpenGraph.psm1 @@ -10,27 +10,6 @@ $commandsPath = Join-Path $PSScriptRoot Commands . $file.FullName } -$myModule = $MyInvocation.MyCommand.ScriptBlock.Module -$ExecutionContext.SessionState.PSVariable.Set($myModule.Name, $myModule) -$myModule.pstypenames.insert(0, $myModule.Name) - -New-PSDrive -Name $MyModule.Name -PSProvider FileSystem -Scope Global -Root $PSScriptRoot -ErrorAction Ignore - -if ($home) { - $MyModuleProfileDirectory = Join-Path ([Environment]::GetFolderPath("LocalApplicationData")) $MyModule.Name - if (-not (Test-Path $MyModuleProfileDirectory)) { - $null = New-Item -ItemType Directory -Path $MyModuleProfileDirectory -Force - } - New-PSDrive -Name "My$($MyModule.Name)" -PSProvider FileSystem -Scope Global -Root $MyModuleProfileDirectory -ErrorAction Ignore -} - -# Set a script variable of this, set to the module -# (so all scripts in this scope default to the correct `$this`) -$script:this = $myModule - -#region Custom -#endregion Custom - -Export-ModuleMember -Alias * -Function * -Variable $myModule.Name +Export-ModuleMember -Alias * -Function * From 266b8e0aacf9e3828078498b4fd05c761ded45c4 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Wed, 18 Mar 2026 15:19:43 -0700 Subject: [PATCH 2/5] feat: Simplifying OpenGraph module scaffolding ( Fixes #14 ) Updating build definition --- Build/GitHub/Jobs/OpenGraph.psd1 | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/Build/GitHub/Jobs/OpenGraph.psd1 b/Build/GitHub/Jobs/OpenGraph.psd1 index 8c2f390..e39282f 100644 --- a/Build/GitHub/Jobs/OpenGraph.psd1 +++ b/Build/GitHub/Jobs/OpenGraph.psd1 @@ -4,29 +4,8 @@ steps = @( @{ name = 'Check out repository' - uses = 'actions/checkout@v2' - }, - @{ - name = 'GitLogger' - uses = 'GitLogging/GitLoggerAction@main' - id = 'GitLogger' - }, - @{ - name = 'Use PSSVG Action' - uses = 'StartAutomating/PSSVG@main' - id = 'PSSVG' - }, - @{ - name = 'Use PipeScript Action' - uses = 'StartAutomating/PipeScript@main' - id = 'PipeScript' - }, - 'RunEZOut', - 'RunHelpOut', - @{ - name = 'Use PSJekyll Action' - uses = 'PowerShellWeb/PSJekyll@main' - id = 'PSJekyll' - } + uses = 'actions/checkout@main' + } + 'RunEZOut' ) } \ No newline at end of file From 70756e7412c85f3aba61169c6518ea2e9f655e6f Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Wed, 18 Mar 2026 15:22:22 -0700 Subject: [PATCH 3/5] feat: `Get-OpenGraph` improvement ( Fixes #15, Fixes #16, Fixes #17 ) --- Commands/Get-OpenGraph.ps1 | 65 +++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/Commands/Get-OpenGraph.ps1 b/Commands/Get-OpenGraph.ps1 index e21598c..c822c54 100644 --- a/Commands/Get-OpenGraph.ps1 +++ b/Commands/Get-OpenGraph.ps1 @@ -18,15 +18,22 @@ function Get-OpenGraph 'https://msnbc.com/', 'https://fox.com/' | Get-OpenGraph + .LINK + https://ogp.me/ #> [Alias('openGraph','ogp')] [CmdletBinding(PositionalBinding=$false)] param( # The URL that may contain Open Graph metadata - [Parameter(ValueFromPipelineByPropertyName)] + [Parameter(Position=0,ValueFromPipeline,ValueFromPipelineByPropertyName)] [Uri] $Url, + # Any HTML that may contain open graph metadata. + [Parameter(ValueFromPipelineByPropertyName)] + [string] + $Html, + # A dictionary of additional Open Graph metadata to include in the result [Parameter(ValueFromPipelineByPropertyName)] [Collections.IDictionary] @@ -40,36 +47,70 @@ function Get-OpenGraph begin { # Make a regex to match meta tags - $metaRegex = [Regex]::new('','IgnoreCase','00:00:00.1') - if (-not $script:OpenGraphCache) { - $script:OpenGraphCache = [Ordered]@{} - } + # We will match both open and closed tags. + $metaRegex = [Regex]::new('','IgnoreCase','00:00:00.1') + # If we do not have a cache + if (-not $script:Cache) { + # create one. + $script:Cache = [Ordered]@{} + } } process { # Declare an empty object to hold the Open Graph metadata $openGraphMetadata = [Ordered]@{PSTypeName='OpenGraph'} - if ($Url) { - if ($script:OpenGraphCache[$url] -and -not $Force) { - return $script:OpenGraphCache[$url] + if ($Url -and -not $PSBoundParameters['html']) { + # If the url is an absolute url with a scheme or http or https. + if ($url.Scheme -in 'http', 'https') { + # Get the url (if it is not cached). + if (-not $script:Cache[$url] -or $Force) { + $script:Cache[$url] =try { + Invoke-RestMethod -Uri $Url + } catch { $_ } + } + $html = $script:Cache[$url] + } + # Otherwise, see if the path exists + elseif (Test-Path $url) + { + # and get content from that path. + $html = Get-Content "$url" -Raw } - $restResponse = Invoke-RestMethod -Uri $Url - foreach ($match in $metaRegex.Matches("$restResponse")) { + } + + # If we had any html, + if ($html) { + # find all of the `` tags. + foreach ($match in $metaRegex.Matches($html)) { + # Try to make them XML $matchXml = "$match" -as [xml] + # If that fails, + if (-not $matchXml) { + # try once more after explicitly closing the end tag. + $matchXml = $match -replace '>$', '/>' -as [xml] + } + # If the meta tag contained a property and content, if ($matchXml.meta.property -and $matchXml.meta.content) { - $openGraphMetadata[$matchXml.meta.property] = $matchXml.meta.content + # we will add it to our openGraph metadata. + $openGraphMetadata[ + $matchXml.meta.property + ] = $matchXml.meta.content } } - $script:OpenGraphCache[$url] = $openGraphMetadata } + + # If any data was provided if ($Data) { + # copy it into open graph metadata foreach ($key in $Data.Keys) { $openGraphMetadata[$key] = $Data[$key] } } + # If there was no open graph metadata, return nothing. if (-not $openGraphMetadata.Count) { return } + # Otherwise, return our OpenGraph metadata [PSCustomObject]$openGraphMetadata } } \ No newline at end of file From 202aa20f4ce51af0eb635b5febbd75407abbc243 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Wed, 18 Mar 2026 15:25:29 -0700 Subject: [PATCH 4/5] docs: `README.md.ps1` ( Fixes #18 ) --- README.md | 67 ++++++++++- README.md.ps1 | 307 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 371 insertions(+), 3 deletions(-) create mode 100644 README.md.ps1 diff --git a/README.md b/README.md index 5757c6d..f0f5707 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,71 @@ # OpenGraph +[![OpenGraph](https://img.shields.io/powershellgallery/dt/OpenGraph)](https://www.powershellgallery.com/packages/OpenGraph/) +## Get OpenGraph with PowerShell -[OpenGraph](https://ogp.me) is a protocol for embedding information in a page search optimization and social media. +## Installing and Importing -The OpenGraph module lets you see this information for any page that has it. +You can install OpenGraph from the [PowerShell gallery](https://powershellgallery.com/) ~~~PowerShell -Get-OpenGraph https://abc.com/ +Install-Module OpenGraph -Scope CurrentUser -Force ~~~ +Once installed, you can import the module with: + +~~~PowerShell +Import-Module OpenGraph -PassThru +~~~ + + +You can also clone the repo and import the module locally: + +~~~PowerShell +git clone https://github.com/PoshWeb/OpenGraph +cd ./OpenGraph +Import-Module ./ -PassThru +~~~ + +## Functions +OpenGraph has 1 function +### Get-OpenGraph +#### Gets Open Graph metadata for a given URL. +Gets Open Graph metadata for a given URL. + +[Open Graph](https://ogp.me/) is a protocol that enables any web page to become a rich object in a social graph. + +It is used many social networks to display rich content when links are shared. + +This function retrieves the Open Graph metadata from a given URL and returns it as a custom object. +##### Parameters + +|Name|Type|Description| +|-|-|-| +|Url|Uri|The URL that may contain Open Graph metadata| +|Html|String|Any HTML that may contain open graph metadata.| +|Data|IDictionary|A dictionary of additional Open Graph metadata to include in the result| +|Force|SwitchParameter|If set, forces the function to retrieve the Open Graph metadata even if it is already cached.| + +##### Examples +###### Example 1 +~~~PowerShell +Get-OpenGraph -Url https://abc.com/ +~~~ +###### Example 2 +~~~PowerShell +'https://cnn.com/', + 'https://msnbc.com/', + 'https://fox.com/' | + Get-OpenGraph +~~~ +#### Links +* [https://ogp.me/](https://ogp.me/) +## Types +### OpenGraph +#### Members +|Name|MemberType| +|-|-| +|[ToString](Types/OpenGraph/ToString.ps1)|ScriptMethod| +|[get_HTML](Types/OpenGraph/get_HTML.ps1)|ScriptProperty| +> (c) 2025 Start-Automating + +> [LICENSE](https://github.com/PoshWeb/OpenGraph/blob/main/LICENSE) diff --git a/README.md.ps1 b/README.md.ps1 new file mode 100644 index 0000000..22b8205 --- /dev/null +++ b/README.md.ps1 @@ -0,0 +1,307 @@ +<# +.SYNOPSIS + README.md.ps1 +.DESCRIPTION + README.md.ps1 makes README.md + + This is a simple and helpful scripting convention for writing READMEs. + + `./README.md.ps1 > ./README.md` + + Feel free to copy and paste this code. + + Please document your parameters, and add NOTES. +.NOTES + This README.md.ps1 is used to generate help for a module. + + It: + + * Outputs the name and description + * Provides installation instructions + * Lists commands + * Lists parameters + * Lists examples + * Lists Extended Types +.EXAMPLE + ./README.md.ps1 > ./README.md +.EXAMPLE + Get-Help ./README.md.ps1 +#> +param( +# The name of the module +[string]$ModuleName = $($PSScriptRoot | Split-Path -Leaf), + +# The domains that serve git repositories. +# If the project uri links to this domain, +# installation instructions will show how to import the module locally. +[string[]] +$GitDomains = @( + 'github.com', 'tangled.org', 'tangled.sh', 'codeberg.org' +), + +# A list of types the module exposes +[Alias('ModuleTypeNames','ModuleTypes')] +[string[]] +$ModuleTypeName = @( + Get-ChildItem -Path $PSScriptRoot -Filter *.types.ps1xml | + Select-Xml /Types/Type/Name | + Foreach-Object {$_.Node.InnerText } | + Sort-Object +), + +# The name of the root directory containing types. +[string] +$TypeRoot = 'Types', + +# If set, we don't need no badges. +[switch] +$NoBadge, + +# If set, will not display gallery instructions or badges +[switch] +$NotOnGallery +) + +Push-Location $PSScriptRoot + +# Import the module +$module = Import-Module "./$ModuleName.psd1" -PassThru + +# And output a header +"# $module" + +if (-not $NoBadge) { + # If it is on the gallery, show the downloads badge. + if (-not $NotOnGallery) { + @( + "[!" + "[$ModuleName](https://img.shields.io/powershellgallery/dt/$ModuleName)" + "](https://www.powershellgallery.com/packages/$ModuleName/)" + ) -join '' + } +} + +# Show the module description +"## $($module.Description)" + +# Show any intro section defined in the manifest +$module.PrivateData.PSData.PSIntro + +#region Boilerplate installation instructions +if (-not $NotOnGallery) { +@" + +## Installing and Importing + +You can install $ModuleName from the [PowerShell gallery](https://powershellgallery.com/) + +~~~PowerShell +Install-Module $($ModuleName) -Scope CurrentUser -Force +~~~ + +Once installed, you can import the module with: + +~~~PowerShell +Import-Module $ModuleName -PassThru +~~~ + +"@ +} +#endregion Gallery installation instructions + +#region Git installation instructions +$projectUri = $module.PrivateData.PSData.ProjectURI -as [uri] + +if ($projectUri.DnsSafeHost -in $GitDomains) { +@" + +You can also clone the repo and import the module locally: + +~~~PowerShell +git clone $projectUri +cd ./$ModuleName +Import-Module ./ -PassThru +~~~ + +"@ +} +#endregion Git installation instructions + +#region Exported Functions +$exportedFunctions = $module.ExportedFunctions +if ($exportedFunctions) { + + "## Functions" + + "$($ModuleName) has $($exportedFunctions.Count) function$( + if ($exportedFunctions.Count -gt 1) { "s"} + )" + + foreach ($export in $exportedFunctions.Keys | Sort-Object) { + # Get help if it there is help to get + $help = Get-Help $export + # If the help is a string, + if ($help -is [string]) { + # make it preformatted text + "~~~" + "$export" + "~~~" + } else { + # Otherwise, add list the export + "### $($export)" + + # And make it's synopsis a header + "#### $($help.SYNOPSIS)" + + # put the description below that + "$($help.Description.text -join [Environment]::NewLine)" + + # Make a table of parameters + if ($help.parameters.parameter) { + "##### Parameters" + + "" + + "|Name|Type|Description|" + "|-|-|-|" + foreach ($parameter in $help.Parameters.Parameter) { + "|$($parameter.Name)|$($parameter.type.name)|$( + $parameter.description.text -replace '(?>\r\n|\n)', '
' + )|" + } + + "" + } + + # Show our examples + "##### Examples" + + $exampleNumber = 0 + foreach ($example in $help.examples.example) { + $markdownLines = @() + $exampleNumber++ + $nonCommentLine = $false + "###### Example $exampleNumber" + + # Combine the code and remarks + $exampleLines = + @( + $example.Code + foreach ($remark in $example.Remarks.text) { + if (-not $remark) { continue } + $remark + } + ) -join ([Environment]::NewLine) -split '(?>\r\n|\n)' # and split into lines + + # Go thru each line in the example as part of a loop + $codeBlock = @(foreach ($exampleLine in $exampleLines) { + # Any comments until the first uncommentedLine are markdown + if ($exampleLine -match '^\#' -and -not $nonCommentLine) { + $markdownLines += $exampleLine -replace '^\#\s{0,1}' + } else { + $nonCommentLine = $true + $exampleLine + } + }) -join [Environment]::NewLine + + $markdownLines + "~~~PowerShell" + $CodeBlock + "~~~" + } + + $relatedUris = foreach ($link in $help.relatedLinks.navigationLink) { + if ($link.uri) { + $link.uri + } + } + if ($relatedUris) { + "#### Links" + foreach ($related in $relatedUris) { + "* [$related]($related)" + } + } + } + } +} +#endregion Exported Functions + +#region Exported Types +if ($ModuleTypeName) { + $typeData = Get-TypeData -TypeName $ModuleTypeName + + if ($typeData) { + "## Types" + } + + foreach ($typeInfo in $typeData) { + $memberDirectory = "./Types/$($typeInfo.TypeName)" + if (-not (Test-Path $memberDirectory)) { continue } + $psTypeNames = @(Get-ChildItem -Path $memberDirectory | + Where-Object Name -match 'PSTypeNames?\.txt$' | + Get-Content) + if (-not $psTypeNames) { + $psTypeNames = @($typeInfo.TypeName) + } + "### $($typeInfo.TypeName)" + + if ($psTypeNames.Count -gt 1) { + "> Also Known As:" + $psTypeNames | + Where-Object { $_ -ne $typeInfo.TypeName} | + Foreach-Object { "* $_"} + } + + + "#### Members" + "|Name|MemberType|" + "|-|-|" + + foreach ($memberName in $typeInfo.Members.Keys) { + "|$( + $memberPath = "./Types/$($typeInfo.TypeName)/$memberName.ps1" + if (Test-Path $memberPath) { + "[$memberName]($($memberPath -replace '^\./'))" + } + else { + $getPath = "./Types/$($typeInfo.TypeName)/get_$memberName.ps1" + $setPath = "./Types/$($typeInfo.TypeName)/set_$memberName.ps1" + if ( + (Test-Path $getPath) -and + (Test-Path $setPath)) { + "[get]($( + $getPath -replace '^\./' + ))/[set]($( + $setPath -replace '^\./' + ))_[$memberName]($( + $getPath -replace '^\./' + ))" + } + elseif (Test-Path $getPath) { + "[get_$memberName]($( + $getPath -replace '^\./' + ))" + } else { + $memberName + } + } + )|$( + $typeInfo.Members[$memberName].GetType().Name -replace 'Data$' + )|" + } + } +} +#endregion Exported Types + +#region Copyright Notice +if ($module.Copyright) { + "> $($module.Copyright)" +} + +if ($module.PrivateData.PSData.LicenseUri) { + "" + "> [LICENSE]($($module.PrivateData.PSData.LicenseUri))" +} +#endregion Copyright Notice + +Pop-Location \ No newline at end of file From 04ff5851eb2acbdef96f62c050f6deb39b5f4cff Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Wed, 18 Mar 2026 15:32:29 -0700 Subject: [PATCH 5/5] release: OpenGraph 0.1.1 Updating Manifest and CHANGELOG --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ OpenGraph.psd1 | 29 ++++++++++++++++++----------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8720e84..f8d880c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +Please: + +* [Like](https://github.com/PoshWeb/OpenGraph) +* [Share](https://github.com/PoshWeb/OpenGraph) +* [Subscribe](https://github.com/PoshWeb/) +* [Support](https://github.com/sponsors/StartAutomating) + +--- + +## OpenGraph 0.1.1 + +* Simplified Module Scaffolding (#14) +* Supporting open or closed tags (#15) +* `Get-OpenGraph -Html` supports direct content (#16) +* `Get-OpenGraph -Url` is now positional and pipeable (#17) +* Improving README (#18) + +--- + +## OpenGraph 0.1 + +* `OpenGraph.ToString()` now returns HTML (#10) +* `Get-OpenGraph` now caches results (#11) + +--- + ## OpenGraph 0.0.1 * Initial Release of OpenGraph Module (#1) diff --git a/OpenGraph.psd1 b/OpenGraph.psd1 index ff3ec4b..5f05b97 100644 --- a/OpenGraph.psd1 +++ b/OpenGraph.psd1 @@ -1,6 +1,6 @@ @{ RootModule = 'OpenGraph.psm1' - ModuleVersion = '0.1' + ModuleVersion = '0.1.1' GUID = 'be4e4070-1ea6-4a2e-8b6a-c6b7755e5ace' Author = 'JamesBrundage' CompanyName = 'Start-Automating' @@ -11,21 +11,28 @@ TypesToProcess = 'OpenGraph.types.ps1xml' PrivateData = @{ PSData = @{ - Tags = @('OpenGraph','SEO','Web','PowerShellWeb' ) - ProjectURI = 'https://github.com/PowerShellWeb/OpenGraph' - LicenseURI = 'https://github.com/PowerShellWeb/OpenGraph/blob/main/LICENSE' + Tags = @('OpenGraph','SEO','Web','PoshWeb','OpenGraphProtocol') + ProjectURI = 'https://github.com/PoshWeb/OpenGraph' + LicenseURI = 'https://github.com/PoshWeb/OpenGraph/blob/main/LICENSE' ReleaseNotes = @' -> Like It? [Star It](https://github.com/PowerShellWeb/OpenGraph) -> Love It? [Support It](https://github.com/sponsors/StartAutomating) +## OpenGraph 0.1.1 -## OpenGraph 0.1 - -* `OpenGraph.ToString()` now returns HTML (#10) -* `Get-OpenGraph` now caches results (#11) +* Simplified Module Scaffolding (#14) +* Supporting open or closed tags (#15) +* `Get-OpenGraph -Html` supports direct content (#16) +* `Get-OpenGraph -Url` is now positional and pipeable (#17) +* Improving README (#18) --- -Additional release notes can be found at [CHANGELOG.md](https://github.com/PowerShellWeb/OpenGraph/blob/main/CHANGELOG.md) +Please: + +* [Like](https://github.com/PoshWeb/OpenGraph) +* [Share](https://github.com/PoshWeb/OpenGraph) +* [Subscribe](https://github.com/PoshWeb/) +* [Support](https://github.com/sponsors/StartAutomating) + +Additional history found available in the [CHANGELOG.md](https://github.com/PoshWeb/OpenGraph/blob/main/CHANGELOG.md) '@ } }