├── .github ├── FUNDING.yml └── workflows │ ├── BuildEmoji.yml │ └── DockEmoji.yml ├── Assets ├── Emoji.png └── Emoji.svg ├── Build ├── Emoji.Build.ps1 ├── Emoji.GitHubWorkflow.PSDevOps.ps1 ├── Emoji.PSSVG.ps1 ├── Emoji.ezout.ps1 └── GitHub │ ├── Jobs │ ├── BuildEmoji.psd1 │ └── DockEmoji.psd1 │ └── On │ └── PushToMain.psd1 ├── CHANGELOG.md ├── Commands ├── All-Emoji.ps.ps1 └── All-Emoji.ps1 ├── Data ├── AllEmojiBlocks.csv └── AllNamedEmoji.csv ├── Demos └── Emoji.demo.ps1 ├── Dockerfile ├── Emoji.format.ps1xml ├── Emoji.ps.psm1 ├── Emoji.psd1 ├── Emoji.psm1 ├── Emoji.tests.ps1 ├── Emoji.types.ps1xml ├── LICENSE ├── README.md ├── README.ps.md └── Types ├── Emoji.Block ├── Emoji.Block.format.ps1 ├── get_End.ps1 ├── get_Length.ps1 ├── get_Range.ps1 └── get_Start.ps1 ├── Emoji.Sequence └── Emoji.Sequence.format.ps1 ├── Emoji.Sequences ├── Add.ps1 ├── Alias.psd1 ├── Remove.ps1 └── get_All.ps1 ├── Emoji.Symbol ├── Alias.psd1 ├── Emoji.Symbol.format.ps1 ├── get_CSS.ps1 ├── get_HTML.ps1 ├── get_Number.ps1 └── get_PowerShell.ps1 └── Emoji ├── Alias.psd1 ├── Export.ps1 ├── Get.ps.ps1 ├── Get.ps1 ├── GetPagingParameters.ps1 ├── Import.ps1 ├── Search.ps.ps1 ├── Search.ps1 ├── Set.ps.ps1 ├── Set.ps1 ├── get_Blocks.ps1 ├── get_Demo.ps1 ├── get_Sequences.ps1 └── set_Sequences.ps1 /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [StartAutomating] 2 | -------------------------------------------------------------------------------- /.github/workflows/BuildEmoji.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Build Emoji 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | jobs: 8 | PowerShellStaticAnalysis: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: InstallScriptCop 12 | id: InstallScriptCop 13 | shell: pwsh 14 | run: | 15 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 16 | Install-Module -Name ScriptCop -Repository PSGallery -Force -Scope CurrentUser 17 | Import-Module ScriptCop -Force -PassThru 18 | - name: InstallPSScriptAnalyzer 19 | id: InstallPSScriptAnalyzer 20 | shell: pwsh 21 | run: | 22 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 23 | Install-Module -Name PSScriptAnalyzer -Repository PSGallery -Force -Scope CurrentUser 24 | Import-Module PSScriptAnalyzer -Force -PassThru 25 | - name: InstallPSDevOps 26 | id: InstallPSDevOps 27 | shell: pwsh 28 | run: | 29 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 30 | Install-Module -Name PSDevOps -Repository PSGallery -Force -Scope CurrentUser 31 | Import-Module PSDevOps -Force -PassThru 32 | - name: Check out repository 33 | uses: actions/checkout@v2 34 | - name: RunScriptCop 35 | id: RunScriptCop 36 | shell: pwsh 37 | run: | 38 | $Parameters = @{} 39 | $Parameters.ModulePath = ${env:ModulePath} 40 | foreach ($k in @($parameters.Keys)) { 41 | if ([String]::IsNullOrEmpty($parameters[$k])) { 42 | $parameters.Remove($k) 43 | } 44 | } 45 | Write-Host "::debug:: RunScriptCop $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')" 46 | & {param([string]$ModulePath) 47 | Import-Module ScriptCop, PSDevOps -PassThru | Out-Host 48 | 49 | if (-not $ModulePath) { 50 | $orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/" 51 | $ModulePath = ".\$moduleName.psd1" 52 | } 53 | if ($ModulePath -like '*PSDevOps*') { 54 | Remove-Module PSDeVOps # If running ScriptCop on PSDeVOps, we need to remove the global module first. 55 | } 56 | 57 | 58 | $importedModule =Import-Module $ModulePath -Force -PassThru 59 | 60 | $importedModule | Out-Host 61 | 62 | $importedModule | 63 | Test-Command | 64 | Tee-Object -Variable scriptCopIssues | 65 | Out-Host 66 | 67 | foreach ($issue in $scriptCopIssues) { 68 | Write-GitHubWarning -Message "$($issue.ItemWithProblem): $($issue.Problem)" 69 | } 70 | } @Parameters 71 | - name: RunPSScriptAnalyzer 72 | id: RunPSScriptAnalyzer 73 | shell: pwsh 74 | run: | 75 | Import-Module PSScriptAnalyzer, PSDevOps -PassThru | Out-Host 76 | $invokeScriptAnalyzerSplat = @{Path='.\'} 77 | if ($ENV:PSScriptAnalyzer_Recurse) { 78 | $invokeScriptAnalyzerSplat.Recurse = $true 79 | } 80 | $result = Invoke-ScriptAnalyzer @invokeScriptAnalyzerSplat 81 | 82 | foreach ($r in $result) { 83 | if ('information', 'warning' -contains $r.Severity) { 84 | Write-GitHubWarning -Message "$($r.RuleName) : $($r.Message)" -SourcePath $r.ScriptPath -LineNumber $r.Line -ColumnNumber $r.Column 85 | } 86 | elseif ($r.Severity -eq 'Error') { 87 | Write-GitHubError -Message "$($r.RuleName) : $($r.Message)" -SourcePath $r.ScriptPath -LineNumber $r.Line -ColumnNumber $r.Column 88 | } 89 | } 90 | TestPowerShellOnLinux: 91 | runs-on: ubuntu-latest 92 | steps: 93 | - name: InstallPester 94 | id: InstallPester 95 | shell: pwsh 96 | run: | 97 | $Parameters = @{} 98 | $Parameters.PesterMaxVersion = ${env:PesterMaxVersion} 99 | foreach ($k in @($parameters.Keys)) { 100 | if ([String]::IsNullOrEmpty($parameters[$k])) { 101 | $parameters.Remove($k) 102 | } 103 | } 104 | Write-Host "::debug:: InstallPester $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')" 105 | & {<# 106 | .Synopsis 107 | Installs Pester 108 | .Description 109 | Installs Pester 110 | #> 111 | param( 112 | # The maximum pester version. Defaults to 4.99.99. 113 | [string] 114 | $PesterMaxVersion = '4.99.99' 115 | ) 116 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 117 | Install-Module -Name Pester -Repository PSGallery -Force -Scope CurrentUser -MaximumVersion $PesterMaxVersion -SkipPublisherCheck -AllowClobber 118 | Import-Module Pester -Force -PassThru -MaximumVersion $PesterMaxVersion} @Parameters 119 | - name: Check out repository 120 | uses: actions/checkout@v2 121 | - name: RunPester 122 | id: RunPester 123 | shell: pwsh 124 | run: | 125 | $Parameters = @{} 126 | $Parameters.ModulePath = ${env:ModulePath} 127 | $Parameters.PesterMaxVersion = ${env:PesterMaxVersion} 128 | $Parameters.NoCoverage = ${env:NoCoverage} 129 | $Parameters.NoCoverage = $parameters.NoCoverage -match 'true'; 130 | foreach ($k in @($parameters.Keys)) { 131 | if ([String]::IsNullOrEmpty($parameters[$k])) { 132 | $parameters.Remove($k) 133 | } 134 | } 135 | Write-Host "::debug:: RunPester $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')" 136 | & {<# 137 | .Synopsis 138 | Runs Pester 139 | .Description 140 | Runs Pester tests after importing a PowerShell module 141 | #> 142 | param( 143 | # The module path. If not provided, will default to the second half of the repository ID. 144 | [string] 145 | $ModulePath, 146 | # The Pester max version. By default, this is pinned to 4.99.99. 147 | [string] 148 | $PesterMaxVersion = '4.99.99', 149 | 150 | # If set, will not collect code coverage. 151 | [switch] 152 | $NoCoverage 153 | ) 154 | 155 | $global:ErrorActionPreference = 'continue' 156 | $global:ProgressPreference = 'silentlycontinue' 157 | 158 | $orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/" 159 | if (-not $ModulePath) { $ModulePath = ".\$moduleName.psd1" } 160 | $importedPester = Import-Module Pester -Force -PassThru -MaximumVersion $PesterMaxVersion 161 | $importedModule = Import-Module $ModulePath -Force -PassThru 162 | $importedPester, $importedModule | Out-Host 163 | 164 | $codeCoverageParameters = @{ 165 | CodeCoverage = "$($importedModule | Split-Path)\*-*.ps1" 166 | CodeCoverageOutputFile = ".\$moduleName.Coverage.xml" 167 | } 168 | 169 | if ($NoCoverage) { 170 | $codeCoverageParameters = @{} 171 | } 172 | 173 | 174 | $result = 175 | Invoke-Pester -PassThru -Verbose -OutputFile ".\$moduleName.TestResults.xml" -OutputFormat NUnitXml @codeCoverageParameters 176 | 177 | "::set-output name=TotalCount::$($result.TotalCount)", 178 | "::set-output name=PassedCount::$($result.PassedCount)", 179 | "::set-output name=FailedCount::$($result.FailedCount)" | Out-Host 180 | if ($result.FailedCount -gt 0) { 181 | "::debug:: $($result.FailedCount) tests failed" 182 | foreach ($r in $result.TestResult) { 183 | if (-not $r.Passed) { 184 | "::error::$($r.describe, $r.context, $r.name -join ' ') $($r.FailureMessage)" 185 | } 186 | } 187 | throw "::error:: $($result.FailedCount) tests failed" 188 | } 189 | } @Parameters 190 | - name: PublishTestResults 191 | uses: actions/upload-artifact@v2 192 | with: 193 | name: PesterResults 194 | path: '**.TestResults.xml' 195 | if: ${{always()}} 196 | TagReleaseAndPublish: 197 | runs-on: ubuntu-latest 198 | if: ${{ success() }} 199 | steps: 200 | - name: Check out repository 201 | uses: actions/checkout@v2 202 | - name: TagModuleVersion 203 | id: TagModuleVersion 204 | shell: pwsh 205 | run: | 206 | $Parameters = @{} 207 | $Parameters.ModulePath = ${env:ModulePath} 208 | $Parameters.UserEmail = ${env:UserEmail} 209 | $Parameters.UserName = ${env:UserName} 210 | $Parameters.TagVersionFormat = ${env:TagVersionFormat} 211 | $Parameters.TagAnnotationFormat = ${env:TagAnnotationFormat} 212 | foreach ($k in @($parameters.Keys)) { 213 | if ([String]::IsNullOrEmpty($parameters[$k])) { 214 | $parameters.Remove($k) 215 | } 216 | } 217 | Write-Host "::debug:: TagModuleVersion $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')" 218 | & {param( 219 | [string] 220 | $ModulePath, 221 | 222 | # The user email associated with a git commit. 223 | [string] 224 | $UserEmail, 225 | 226 | # The user name associated with a git commit. 227 | [string] 228 | $UserName, 229 | 230 | # The tag version format (default value: 'v$(imported.Version)') 231 | # This can expand variables. $imported will contain the imported module. 232 | [string] 233 | $TagVersionFormat = 'v$($imported.Version)', 234 | 235 | # The tag version format (default value: '$($imported.Name) $(imported.Version)') 236 | # This can expand variables. $imported will contain the imported module. 237 | [string] 238 | $TagAnnotationFormat = '$($imported.Name) $($imported.Version)' 239 | ) 240 | 241 | 242 | $gitHubEvent = if ($env:GITHUB_EVENT_PATH) { 243 | [IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json 244 | } else { $null } 245 | 246 | 247 | @" 248 | ::group::GitHubEvent 249 | $($gitHubEvent | ConvertTo-Json -Depth 100) 250 | ::endgroup:: 251 | "@ | Out-Host 252 | 253 | if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?\d+)") -and 254 | (-not $gitHubEvent.psobject.properties['inputs'])) { 255 | "::warning::Pull Request has not merged, skipping Tagging" | Out-Host 256 | return 257 | } 258 | 259 | 260 | 261 | $imported = 262 | if (-not $ModulePath) { 263 | $orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/" 264 | Import-Module ".\$moduleName.psd1" -Force -PassThru -Global 265 | } else { 266 | Import-Module $modulePath -Force -PassThru -Global 267 | } 268 | 269 | if (-not $imported) { return } 270 | 271 | $targetVersion =$ExecutionContext.InvokeCommand.ExpandString($TagVersionFormat) 272 | $existingTags = git tag --list 273 | 274 | @" 275 | Target Version: $targetVersion 276 | 277 | Existing Tags: 278 | $($existingTags -join [Environment]::NewLine) 279 | "@ | Out-Host 280 | 281 | $versionTagExists = $existingTags | Where-Object { $_ -match $targetVersion } 282 | 283 | if ($versionTagExists) { 284 | "::warning::Version $($versionTagExists)" 285 | return 286 | } 287 | 288 | if (-not $UserName) { $UserName = $env:GITHUB_ACTOR } 289 | if (-not $UserEmail) { $UserEmail = "$UserName@github.com" } 290 | git config --global user.email $UserEmail 291 | git config --global user.name $UserName 292 | 293 | git tag -a $targetVersion -m $ExecutionContext.InvokeCommand.ExpandString($TagAnnotationFormat) 294 | git push origin --tags 295 | 296 | if ($env:GITHUB_ACTOR) { 297 | exit 0 298 | }} @Parameters 299 | - name: ReleaseModule 300 | id: ReleaseModule 301 | shell: pwsh 302 | run: | 303 | $Parameters = @{} 304 | $Parameters.ModulePath = ${env:ModulePath} 305 | $Parameters.UserEmail = ${env:UserEmail} 306 | $Parameters.UserName = ${env:UserName} 307 | $Parameters.TagVersionFormat = ${env:TagVersionFormat} 308 | $Parameters.ReleaseNameFormat = ${env:ReleaseNameFormat} 309 | $Parameters.ReleaseAsset = ${env:ReleaseAsset} 310 | $Parameters.ReleaseAsset = $parameters.ReleaseAsset -split ';' -replace '^[''"]' -replace '[''"]$' 311 | foreach ($k in @($parameters.Keys)) { 312 | if ([String]::IsNullOrEmpty($parameters[$k])) { 313 | $parameters.Remove($k) 314 | } 315 | } 316 | Write-Host "::debug:: ReleaseModule $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')" 317 | & {param( 318 | [string] 319 | $ModulePath, 320 | 321 | # The user email associated with a git commit. 322 | [string] 323 | $UserEmail, 324 | 325 | # The user name associated with a git commit. 326 | [string] 327 | $UserName, 328 | 329 | # The tag version format (default value: 'v$(imported.Version)') 330 | # This can expand variables. $imported will contain the imported module. 331 | [string] 332 | $TagVersionFormat = 'v$($imported.Version)', 333 | 334 | # The release name format (default value: '$($imported.Name) $($imported.Version)') 335 | [string] 336 | $ReleaseNameFormat = '$($imported.Name) $($imported.Version)', 337 | 338 | # Any assets to attach to the release. Can be a wildcard or file name. 339 | [string[]] 340 | $ReleaseAsset 341 | ) 342 | 343 | 344 | $gitHubEvent = if ($env:GITHUB_EVENT_PATH) { 345 | [IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json 346 | } else { $null } 347 | 348 | 349 | @" 350 | ::group::GitHubEvent 351 | $($gitHubEvent | ConvertTo-Json -Depth 100) 352 | ::endgroup:: 353 | "@ | Out-Host 354 | 355 | if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?\d+)") -and 356 | (-not $gitHubEvent.psobject.properties['inputs'])) { 357 | "::warning::Pull Request has not merged, skipping GitHub release" | Out-Host 358 | return 359 | } 360 | 361 | 362 | 363 | $imported = 364 | if (-not $ModulePath) { 365 | $orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/" 366 | Import-Module ".\$moduleName.psd1" -Force -PassThru -Global 367 | } else { 368 | Import-Module $modulePath -Force -PassThru -Global 369 | } 370 | 371 | if (-not $imported) { return } 372 | 373 | $targetVersion =$ExecutionContext.InvokeCommand.ExpandString($TagVersionFormat) 374 | $targetReleaseName = $targetVersion 375 | $releasesURL = 'https://api.github.com/repos/${{github.repository}}/releases' 376 | "Release URL: $releasesURL" | Out-Host 377 | $listOfReleases = Invoke-RestMethod -Uri $releasesURL -Method Get -Headers @{ 378 | "Accept" = "application/vnd.github.v3+json" 379 | "Authorization" = 'Bearer ${{ secrets.GITHUB_TOKEN }}' 380 | } 381 | 382 | $releaseExists = $listOfReleases | Where-Object tag_name -eq $targetVersion 383 | 384 | if ($releaseExists) { 385 | "::warning::Release '$($releaseExists.Name )' Already Exists" | Out-Host 386 | $releasedIt = $releaseExists 387 | } else { 388 | $releasedIt = Invoke-RestMethod -Uri $releasesURL -Method Post -Body ( 389 | [Ordered]@{ 390 | owner = '${{github.owner}}' 391 | repo = '${{github.repository}}' 392 | tag_name = $targetVersion 393 | name = $ExecutionContext.InvokeCommand.ExpandString($ReleaseNameFormat) 394 | body = 395 | if ($env:RELEASENOTES) { 396 | $env:RELEASENOTES 397 | } elseif ($imported.PrivateData.PSData.ReleaseNotes) { 398 | $imported.PrivateData.PSData.ReleaseNotes 399 | } else { 400 | "$($imported.Name) $targetVersion" 401 | } 402 | draft = if ($env:RELEASEISDRAFT) { [bool]::Parse($env:RELEASEISDRAFT) } else { $false } 403 | prerelease = if ($env:PRERELEASE) { [bool]::Parse($env:PRERELEASE) } else { $false } 404 | } | ConvertTo-Json 405 | ) -Headers @{ 406 | "Accept" = "application/vnd.github.v3+json" 407 | "Content-type" = "application/json" 408 | "Authorization" = 'Bearer ${{ secrets.GITHUB_TOKEN }}' 409 | } 410 | } 411 | 412 | 413 | 414 | 415 | 416 | if (-not $releasedIt) { 417 | throw "Release failed" 418 | } else { 419 | $releasedIt | Out-Host 420 | } 421 | 422 | $releaseUploadUrl = $releasedIt.upload_url -replace '\{.+$' 423 | 424 | if ($ReleaseAsset) { 425 | $fileList = Get-ChildItem -Recurse 426 | $filesToRelease = 427 | @(:nextFile foreach ($file in $fileList) { 428 | foreach ($relAsset in $ReleaseAsset) { 429 | if ($relAsset -match '[\*\?]') { 430 | if ($file.Name -like $relAsset) { 431 | $file; continue nextFile 432 | } 433 | } elseif ($file.Name -eq $relAsset -or $file.FullName -eq $relAsset) { 434 | $file; continue nextFile 435 | } 436 | } 437 | }) 438 | 439 | $releasedFiles = @{} 440 | foreach ($file in $filesToRelease) { 441 | if ($releasedFiles[$file.Name]) { 442 | Write-Warning "Already attached file $($file.Name)" 443 | continue 444 | } else { 445 | $fileBytes = [IO.File]::ReadAllBytes($file.FullName) 446 | $releasedFiles[$file.Name] = 447 | Invoke-RestMethod -Uri "${releaseUploadUrl}?name=$($file.Name)" -Headers @{ 448 | "Accept" = "application/vnd.github+json" 449 | "Authorization" = 'Bearer ${{ secrets.GITHUB_TOKEN }}' 450 | } -Body $fileBytes -ContentType Application/octet-stream 451 | $releasedFiles[$file.Name] 452 | } 453 | } 454 | 455 | "Attached $($releasedFiles.Count) file(s) to release" | Out-Host 456 | } 457 | 458 | 459 | 460 | } @Parameters 461 | - name: PublishPowerShellGallery 462 | id: PublishPowerShellGallery 463 | shell: pwsh 464 | run: | 465 | $Parameters = @{} 466 | $Parameters.ModulePath = ${env:ModulePath} 467 | $Parameters.Exclude = ${env:Exclude} 468 | $Parameters.Exclude = $parameters.Exclude -split ';' -replace '^[''"]' -replace '[''"]$' 469 | foreach ($k in @($parameters.Keys)) { 470 | if ([String]::IsNullOrEmpty($parameters[$k])) { 471 | $parameters.Remove($k) 472 | } 473 | } 474 | Write-Host "::debug:: PublishPowerShellGallery $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')" 475 | & {param( 476 | [string] 477 | $ModulePath, 478 | 479 | [string[]] 480 | $Exclude = @('*.png', '*.mp4', '*.jpg','*.jpeg', '*.gif', 'docs[/\]*') 481 | ) 482 | 483 | $gitHubEvent = if ($env:GITHUB_EVENT_PATH) { 484 | [IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json 485 | } else { $null } 486 | 487 | if (-not $Exclude) { 488 | $Exclude = @('*.png', '*.mp4', '*.jpg','*.jpeg', '*.gif','docs[/\]*') 489 | } 490 | 491 | 492 | @" 493 | ::group::GitHubEvent 494 | $($gitHubEvent | ConvertTo-Json -Depth 100) 495 | ::endgroup:: 496 | "@ | Out-Host 497 | 498 | @" 499 | ::group::PSBoundParameters 500 | $($PSBoundParameters | ConvertTo-Json -Depth 100) 501 | ::endgroup:: 502 | "@ | Out-Host 503 | 504 | if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?\d+)") -and 505 | (-not $gitHubEvent.psobject.properties['inputs'])) { 506 | "::warning::Pull Request has not merged, skipping Gallery Publish" | Out-Host 507 | return 508 | } 509 | 510 | 511 | $imported = 512 | if (-not $ModulePath) { 513 | $orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/" 514 | Import-Module ".\$moduleName.psd1" -Force -PassThru -Global 515 | } else { 516 | Import-Module $modulePath -Force -PassThru -Global 517 | } 518 | 519 | if (-not $imported) { return } 520 | 521 | $foundModule = try { Find-Module -Name $imported.Name -ErrorAction SilentlyContinue} catch {} 522 | 523 | if ($foundModule -and (([Version]$foundModule.Version) -ge ([Version]$imported.Version))) { 524 | "::warning::Gallery Version of $moduleName is more recent ($($foundModule.Version) >= $($imported.Version))" | Out-Host 525 | } else { 526 | 527 | $gk = '${{secrets.GALLERYKEY}}' 528 | 529 | $rn = Get-Random 530 | $moduleTempFolder = Join-Path $pwd "$rn" 531 | $moduleTempPath = Join-Path $moduleTempFolder $moduleName 532 | New-Item -ItemType Directory -Path $moduleTempPath -Force | Out-Host 533 | 534 | Write-Host "Staging Directory: $ModuleTempPath" 535 | 536 | $imported | Split-Path | 537 | Get-ChildItem -Force | 538 | Where-Object Name -NE $rn | 539 | Copy-Item -Destination $moduleTempPath -Recurse 540 | 541 | $moduleGitPath = Join-Path $moduleTempPath '.git' 542 | Write-Host "Removing .git directory" 543 | if (Test-Path $moduleGitPath) { 544 | Remove-Item -Recurse -Force $moduleGitPath 545 | } 546 | 547 | if ($Exclude) { 548 | "::notice::Attempting to Exlcude $exclude" | Out-Host 549 | Get-ChildItem $moduleTempPath -Recurse | 550 | Where-Object { 551 | foreach ($ex in $exclude) { 552 | if ($_.FullName -like $ex) { 553 | "::notice::Excluding $($_.FullName)" | Out-Host 554 | return $true 555 | } 556 | } 557 | } | 558 | Remove-Item 559 | } 560 | 561 | Write-Host "Module Files:" 562 | Get-ChildItem $moduleTempPath -Recurse 563 | Write-Host "Publishing $moduleName [$($imported.Version)] to Gallery" 564 | Publish-Module -Path $moduleTempPath -NuGetApiKey $gk 565 | if ($?) { 566 | Write-Host "Published to Gallery" 567 | } else { 568 | Write-Host "Gallery Publish Failed" 569 | exit 1 570 | } 571 | } 572 | } @Parameters 573 | BuildEmoji: 574 | runs-on: ubuntu-latest 575 | if: ${{ success() }} 576 | steps: 577 | - name: Check out repository 578 | uses: actions/checkout@v2 579 | - name: GitLogger 580 | uses: GitLogging/GitLoggerAction@main 581 | id: GitLogger 582 | - name: Use PSSVG Action 583 | uses: StartAutomating/PSSVG@main 584 | id: PSSVG 585 | - name: Use PipeScript Action 586 | uses: StartAutomating/PipeScript@main 587 | id: PipeScript 588 | - name: UseEZOut 589 | uses: StartAutomating/EZOut@master 590 | - name: UseHelpOut 591 | uses: StartAutomating/HelpOut@master 592 | 593 | -------------------------------------------------------------------------------- /.github/workflows/DockEmoji.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Dock Emoji 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - master 8 | paths-ignore: 9 | - 'docs/**' 10 | - '*.help.txt' 11 | - '*.md' 12 | jobs: 13 | DockEmoji: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | contents: read 17 | packages: write 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v4 21 | - name: Log in to the Container registry 22 | uses: docker/login-action@master 23 | with: 24 | registry: ${{ env.REGISTRY }} 25 | username: ${{ github.actor }} 26 | password: ${{ secrets.GITHUB_TOKEN }} 27 | - name: Extract metadata (tags, labels) for Docker 28 | id: meta 29 | uses: docker/metadata-action@master 30 | with: 31 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 32 | - name: Build and push Docker image 33 | uses: docker/build-push-action@master 34 | with: 35 | context: . 36 | push: true 37 | tags: ${{ steps.meta.outputs.tags }} 38 | labels: ${{ steps.meta.outputs.labels }} 39 | env: 40 | IMAGE_NAME: ${{ github.repository }} 41 | REGISTRY: ghcr.io 42 | -------------------------------------------------------------------------------- /Assets/Emoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StartAutomating/Emoji/f75c3356a62350b52fc88ccd94ffddbda0928d56/Assets/Emoji.png -------------------------------------------------------------------------------- /Assets/Emoji.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | emoji 10 | 😎😉😍🥰🤔😟 11 | 12 | -------------------------------------------------------------------------------- /Build/Emoji.Build.ps1: -------------------------------------------------------------------------------- 1 | [ValidatePattern("\s(?>Unicode|UCD)")] 2 | param() 3 | 4 | # Push to the current location (this is redundant inside of a Pipeline, but good practice for interactive use) 5 | Push-Location $PSScriptRoot 6 | 7 | #region Download Unicode Character Dataset 8 | # If we don't have the latest zip 9 | if (-not $latestUnicodeZip) { 10 | # download it 11 | $latestUnicodeZip = Invoke-WebRequest https://unicode.org/Public/zipped/latest/UCD.zip 12 | } 13 | 14 | # Put the contents into UCD 15 | $UCDZipPath = Join-Path $PSScriptRoot "UCD.zip" 16 | $UCDPath = Join-Path $PSScriptRoot "UCD" 17 | if (-not (Test-path $UCDZipPath)) { 18 | [IO.File]::WriteAllBytes("$UCDZipPath",$latestUnicodeZip.Content) 19 | Expand-Archive -Path "$UCDZipPath" -DestinationPath "$UCDPath" -Force 20 | } 21 | #endregion Download Unicode Character Dataset 22 | 23 | #region Extract, Transform, and Load Named Emoji 24 | $allNamedEmoji = 25 | Get-ChildItem -Path $UCDPath -Recurse -Filter 'DerivedName.txt' | 26 | Import-Csv -Delimiter ';' -Header HexCode, Name 27 | 28 | $allUniquelyNamedEmoji = $allNamedEmoji | 29 | Group-Object Name | 30 | Where-Object Count -eq 1 31 | 32 | $parentPath = $pwd | Split-Path 33 | $DataPath = Join-Path $parentPath "Data" 34 | 35 | if (-not (Test-Path $DataPath)) { 36 | New-Item -ItemType Directory -Path $DataPath -Force | Out-Null 37 | } 38 | $allNamedEmojiPath = (Join-Path $DataPath AllNamedEmoji.csv) 39 | @(foreach ($uniquelyNamedEmoji in $allUniquelyNamedEmoji) { 40 | $emojiName, $emojiHex = $uniquelyNamedEmoji.Name, "$($uniquelyNamedEmoji.Group[0].HexCode)".Trim() 41 | if ($emojiHex -match '\..') { continue } 42 | $emojiString = try { 43 | $ExecutionContext.InvokeCommand.ExpandString(('`u{',$emojiHex,'}' -join '')) 44 | } catch { 45 | $null 46 | } 47 | 48 | if ($emojiString) { 49 | [Ordered]@{Name="$emojiName";Hex="$emojiHex";String="$emojiString"} 50 | } 51 | }) | Export-Csv -Path $allNamedEmojiPath -Force 52 | 53 | Get-Item -Path $allNamedEmojiPath 54 | #endregion Extract, Transform, and Load Named Emoji 55 | 56 | #region Extract, Transform, and Load Emoji Blocks 57 | $allEmojiBlocks = 58 | Get-ChildItem -Path $UCDPath -Recurse -Filter 'Blocks.txt' | 59 | Import-Csv -Delimiter ';' -Header Range, BlockName | 60 | Where-Object Range | 61 | Where-Object Range -notlike '#*' 62 | 63 | $currentGeneralCategory = '' 64 | 65 | $allEmojiBlocksPath = (Join-Path $DataPath AllEmojiBlocks.csv) 66 | @(foreach ($emojiBlock in $allEmojiBlocks) { 67 | 68 | $rangeStart, $rangeEnd = $emojiBlock.Range -split '\.\.' 69 | 70 | [PSCustomObject][Ordered]@{ 71 | RangeStart = $rangeStart 72 | RangeEnd = $rangeEnd 73 | BlockName=$emojiBlock.BlockName 74 | } 75 | 76 | }) | Export-Csv -Path $allEmojiBlocksPath 77 | 78 | Get-Item $allEmojiBlocksPath 79 | #endregion Extract, Transform, and Load Emoji Categories 80 | 81 | 82 | Pop-Location -------------------------------------------------------------------------------- /Build/Emoji.GitHubWorkflow.PSDevOps.ps1: -------------------------------------------------------------------------------- 1 | #requires -Module PSDevOps 2 | Import-BuildStep -SourcePath ( 3 | Join-Path $PSScriptRoot 'GitHub' 4 | ) -BuildSystem GitHubWorkflow 5 | 6 | Push-Location ($PSScriptRoot | Split-Path) 7 | New-GitHubWorkflow -Name "Build Emoji" -On Push, 8 | PullRequest, 9 | Demand -Job PowerShellStaticAnalysis, 10 | TestPowerShellOnLinux, 11 | TagReleaseAndPublish, BuildEmoji -OutputPath .\.github\workflows\BuildEmoji.yml 12 | 13 | Pop-Location -------------------------------------------------------------------------------- /Build/Emoji.PSSVG.ps1: -------------------------------------------------------------------------------- 1 | #requires -Module PSSVG 2 | 3 | $AssetsPath = $PSScriptRoot | Split-Path | Join-Path -ChildPath "Assets" 4 | 5 | if (-not (Test-Path $AssetsPath)) { 6 | New-Item -ItemType Directory -Path $AssetsPath | Out-Null 7 | } 8 | 9 | $fontName = 'Anta' 10 | $fontName = 'Heebo' 11 | $fontName = 'Noto Sans' 12 | 13 | svg -content $( 14 | $commonParameters = [Ordered]@{ 15 | Fill = '#4488FF' 16 | # Stroke = 'black' 17 | # StrokeWidth = '0.05' 18 | } 19 | 20 | SVG.GoogleFont -FontName $fontName 21 | 22 | svg.symbol -Id psChevron -Content @( 23 | svg.polygon -Points (@( 24 | "40,20" 25 | "45,20" 26 | "60,50" 27 | "35,80" 28 | "32.5,80" 29 | "55,50" 30 | ) -join ' ') 31 | ) -ViewBox 100, 100 32 | 33 | 34 | svg.use -Href '#psChevron' -X -45% -Y 37.5% @commonParameters -Height 25% -Opacity .9 35 | svg.text -Text 'emoji' -X 50% -Y 50% -FontSize 4em -FontFamily sans-serif @commonParameters -DominantBaseline 'middle' -TextAnchor 'middle' -Style "font-family:'$fontName'" 36 | svg.text -Text '😎😉😍🥰🤔😟' -X 50% -Y 80% -FontSize .5em @commonParameters -DominantBaseline 'middle' -TextAnchor 'middle' 37 | ) -ViewBox 0, 0, 200, 100 -OutputPath $( 38 | Join-Path $assetsPath Emoji.svg 39 | ) 40 | 41 | -------------------------------------------------------------------------------- /Build/Emoji.ezout.ps1: -------------------------------------------------------------------------------- 1 | #requires -Module EZOut 2 | # Install-Module EZOut or https://github.com/StartAutomating/EZOut 3 | $myFile = $MyInvocation.MyCommand.ScriptBlock.File 4 | $myModuleName = 'Emoji' 5 | $myRoot = $myFile | Split-Path | Split-Path 6 | Push-Location $myRoot 7 | $formatting = @( 8 | # Add your own Write-FormatView here, 9 | # or put them in a Formatting or Views directory 10 | foreach ($potentialDirectory in 'Formatting','Views','Types') { 11 | Join-Path $myRoot $potentialDirectory | 12 | Get-ChildItem -ea ignore | 13 | Import-FormatView -FilePath {$_.Fullname} 14 | } 15 | ) 16 | 17 | $destinationRoot = $myRoot 18 | 19 | if ($formatting) { 20 | $myFormatFilePath = Join-Path $destinationRoot "$myModuleName.format.ps1xml" 21 | # You can also output to multiple paths by passing a hashtable to -OutputPath. 22 | $formatting | Out-FormatData -Module $MyModuleName -OutputPath $myFormatFilePath 23 | } 24 | 25 | $types = @( 26 | # Add your own Write-TypeView statements here 27 | # or declare them in the 'Types' directory 28 | Join-Path $myRoot Types | 29 | Get-Item -ea ignore | 30 | Import-TypeView 31 | 32 | ) 33 | 34 | if ($types) { 35 | $myTypesFilePath = Join-Path $destinationRoot "$myModuleName.types.ps1xml" 36 | # You can also output to multiple paths by passing a hashtable to -OutputPath. 37 | $types | Out-TypeData -OutputPath $myTypesFilePath 38 | } 39 | Pop-Location 40 | -------------------------------------------------------------------------------- /Build/GitHub/Jobs/BuildEmoji.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | "runs-on" = "ubuntu-latest" 3 | if = '${{ success() }}' 4 | steps = @( 5 | @{ 6 | name = 'Check out repository' 7 | uses = 'actions/checkout@v2' 8 | }, 9 | @{ 10 | name = 'GitLogger' 11 | uses = 'GitLogging/GitLoggerAction@main' 12 | id = 'GitLogger' 13 | }, 14 | @{ 15 | name = 'Use PSSVG Action' 16 | uses = 'StartAutomating/PSSVG@main' 17 | id = 'PSSVG' 18 | }, 19 | @{ 20 | name = 'Use PipeScript Action' 21 | uses = 'StartAutomating/PipeScript@main' 22 | id = 'PipeScript' 23 | } 24 | 'RunEZOut', 25 | 'RunHelpOut' 26 | ) 27 | } -------------------------------------------------------------------------------- /Build/GitHub/Jobs/DockEmoji.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | 'runs-on'='ubuntu-latest' 3 | 'permissions' = @{ 4 | 'contents'='read' 5 | 'packages'='write' 6 | } 7 | steps = @( 8 | @{ 9 | 'name'='Checkout repository' 10 | 'uses'='actions/checkout@v4' 11 | }, 12 | @{ 13 | 'name'='Log in to the Container registry' 14 | 'uses'='docker/login-action@master' 15 | 'with'=@{ 16 | 'registry'='${{ env.REGISTRY }}' 17 | 'username'='${{ github.actor }}' 18 | 'password'='${{ secrets.GITHUB_TOKEN }}' 19 | } 20 | }, 21 | @{ 22 | 'name'='Extract metadata (tags, labels) for Docker' 23 | 'id'='meta' 24 | 'uses'='docker/metadata-action@master' 25 | 'with'=@{ 26 | 'images'='${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}' 27 | } 28 | }, 29 | @{ 30 | 'name'='Build and push Docker image' 31 | 'uses'='docker/build-push-action@master' 32 | 'with'=@{ 33 | 'context'='.' 34 | 'push'='true' 35 | 'tags'='${{ steps.meta.outputs.tags }}' 36 | 'labels'='${{ steps.meta.outputs.labels }}' 37 | } 38 | } 39 | 40 | ) 41 | } -------------------------------------------------------------------------------- /Build/GitHub/On/PushToMain.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | push = @{ 3 | branches =@('main','master') 4 | "paths-ignore" = @("docs/**","*.help.txt", "*.md") 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Emoji 0.1.5: 2 | 3 | * Emoji.Symbol.HTML (#66) 4 | * ... and new views (#62) 5 | * Emoji Docker Support (#63, #64, #65) 6 | 7 | --- 8 | 9 | ## Emoji 0.1.4: 10 | 11 | * Emoji.Symbol.CSS (#58) 12 | * ... and new views (#60) 13 | * Also making color more tolerant of strict mode (#59) 14 | 15 | --- 16 | 17 | ## Emoji 0.1.3: 18 | 19 | * Improved Formatting 20 | * Now with Color (and better padding) (#46) 21 | * Adding Custom formats (#47) 22 | * Adding PowerShell formats (#49) 23 | * Emoji Sequences: 24 | * Get-Emoji -Sequence (#55) 25 | * Emoji.Sequences.All (#41) 26 | * Emoji.Sequences.Add (#39) 27 | * Emoji.Sequences.Remove (#40) 28 | * Emoji.get/set Sequence (#35) 29 | * Sequence Formatting (#54) 30 | * Added `Emoji.get_Demos` (#42) 31 | * Added `/Demos/Emoji.demo.ps1` (#43) 32 | * Set-Emoji 33 | * Added -ScriptBlock (#51) 34 | * Defaulting Value (#52) 35 | 36 | --- 37 | 38 | ## Emoji 0.1.2: 39 | 40 | ### Updating Emoji: 41 | 42 | * Paging Parameter Fixes: 43 | * Emoji.GetPagingParameters (#32) 44 | * Search-Emoji Paging (#34) 45 | * Get-Emoji Paging (#30) 46 | * Adding Emoji.tests.ps1 (#33) 47 | 48 | --- 49 | 50 | ## Emoji 0.1.1: 51 | 52 | ### More Emoji 53 | 54 | * Find/Search-Emoji improvements: 55 | * Supporting Multiple -Patterns (#15 ) (thanks @I-Am-Jakoby !) 56 | * Supporting -Word (#16) 57 | * Get-Emoji: 58 | * Get-Emoji -Block (#23) 59 | * Get-Emoji -First/-Skip (#26) 60 | * Emoji Block Support: 61 | * `Emoji.get_Blocks` (#17) 62 | * Emoji.Block pseudotype (#18, #19, #20, #21, #22) 63 | * Added Logo (#28) 64 | 65 | --- 66 | 67 | ## Emoji 0.1: 68 | 69 | ### Initial Release of Emoji 70 | 71 | * Emoji is PowerShell Module for Emoji (#1) 72 | * It is built from the [Unicode Character Dataset](https://unicode.org/Public/UCD/latest/ucd/), using [PipeScript](https://github.com/StartAutomating/PipeScript) (#2) 73 | * It builds an object model around Emoji, using [EZOut](https://github.com/StartAutomating/EZOut) 74 | * That model is used as the basis for a single command, `Emoji` (#4) 75 | * The `Emoji` function can be accessed with several verbs: 76 | * Import-Emoji imports (#5) 77 | * Find/Search-Emoji searches loaded emoji (#6) 78 | * Get-Emoji gets emoji (#7) 79 | * Set-Emoji sets variables or functions (#8) 80 | * Export-Emoji exports named characters (#13) 81 | * `Emoji.Symbol` types make each emoji nicer to work with: 82 | * By formatting nicely (#10) 83 | * By adding a ScriptProperty, .Number (#11) 84 | * By aliasing an AliasProperty, .Emoji (#12) 85 | 86 | --- 87 | 88 | Full history in [CHANGELOG](https://github.com/StartAutomating/Emoji/blob/main/CHANGELOG.md) 89 | 90 | Like it? Star It! Love it? Support It! -------------------------------------------------------------------------------- /Commands/All-Emoji.ps.ps1: -------------------------------------------------------------------------------- 1 | function Emoji 2 | { 3 | <# 4 | .SYNOPSIS 5 | ⟩⚡PowerShell Emoji 😎😉😍🥰 🤔😟 6 | .DESCRIPTION 7 | Helps you work with Emoji in PowerShell. 8 | #> 9 | [Alias( 10 | 'Get-Emoji','Set-Emoji', 11 | 'Find-Emoji', 'Search-Emoji', 12 | 'Import-Emoji', 'Export-Emoji' 13 | )] 14 | [CmdletBinding(PositionalBinding=$false,SupportsShouldProcess,SupportsPaging)] 15 | param() 16 | 17 | dynamicParam { 18 | $myName = $MyInvocation.InvocationName 19 | $myVerb, $myNoun = 20 | if ($myName -match '-') { $myName -split '-',2 } 21 | else { $myName -split '\p{P}',2 } 22 | 23 | if (-not $myNoun) { 24 | $myNoun = $myVerb 25 | $myVerb = "Get" 26 | } 27 | 28 | if (-not $myNoun) { return } 29 | 30 | $nounTypeData = Get-TypeData -TypeName $myNoun 31 | 32 | $DynamicParameters = [Management.Automation.RuntimeDefinedParameterDictionary]::new() 33 | 34 | $typeDataForVerb = $nounTypeData.Members[$myVerb] 35 | if ( 36 | ($typeDataForVerb -is [Management.Automation.Runspaces.AliasPropertyData]) -and 37 | ($nounTypeData.Members[$typeDataForVerb.ReferencedMemberName] -is 38 | [Management.Automation.Runspaces.ScriptMethodData]) 39 | ) { 40 | $typeDataForVerb = $nounTypeData.Members[$typeDataForVerb.ReferencedMemberName] 41 | } 42 | 43 | if ($typeDataForVerb -is [Management.Automation.Runspaces.ScriptMethodData]) { 44 | $function:TempFunction = $typeDataForVerb.Script 45 | $tempFunctionMetadata = [Management.Automation.CommandMetadata]$ExecutionContext.SessionState.InvokeCommand.GetCommand('TempFunction','Function') 46 | foreach ($functionParameter in $tempFunctionMetadata.Parameters.Values) { 47 | $DynamicParameters.Add($functionParameter.Name, 48 | [Management.Automation.RuntimeDefinedParameter]::new( 49 | $functionParameter.Name,$functionParameter.ParameterType, @( 50 | $functionParameter.Attributes 51 | ) 52 | ) 53 | ) 54 | } 55 | } 56 | return $DynamicParameters 57 | } 58 | 59 | process { 60 | $myName = $MyInvocation.InvocationName 61 | $myVerb, $myNoun = $myName -split '-',2 62 | if (-not $myNoun) { 63 | $myNoun = $myVerb 64 | $myVerb = "Get" 65 | } 66 | if (-not $myNoun) { 67 | return $Emoji 68 | } 69 | $nounTypeData = Get-TypeData -TypeName $myNoun 70 | $typeDataForVerb = $nounTypeData.Members[$myVerb] 71 | if ( 72 | ($typeDataForVerb -is [Management.Automation.Runspaces.AliasPropertyData]) -and 73 | ($nounTypeData.Members[$typeDataForVerb.ReferencedMemberName] -is 74 | [Management.Automation.Runspaces.ScriptMethodData]) 75 | ) { 76 | $typeDataForVerb = $nounTypeData.Members[$typeDataForVerb.ReferencedMemberName] 77 | } 78 | if (-not $typeDataForVerb) { return } 79 | $parametersForScript = [Ordered]@{} + $PSBoundParameters 80 | $function:InnerCommand = $typeDataForVerb.Script 81 | $innerCommandMetadata = $ExecutionContext.SessionState.InvokeCommand.GetCommand('InnerCommand','Function') -as 82 | [Management.Automation.CommandMetadata] 83 | foreach ($parameterName in @($parametersForScript.Keys)) { 84 | if (-not $innerCommandMetadata.Parameters[$parameterName]) { 85 | $parametersForScript.Remove($parameterName) 86 | } 87 | } 88 | if ($innerCommandMetadata.SupportsPaging) { 89 | if ($PSBoundParameters.First) { 90 | $parametersForScript.First = $PSBoundParameters.First 91 | } 92 | if ($PSBoundParameters.Skip) { 93 | $parametersForScript.Skip = $PSBoundParameters.Skip 94 | } 95 | } 96 | & $typeDataForVerb.Script @parametersForScript 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Commands/All-Emoji.ps1: -------------------------------------------------------------------------------- 1 | function Emoji { 2 | 3 | <# 4 | .SYNOPSIS 5 | ⟩⚡PowerShell Emoji 😎😉😍🥰 🤔😟 6 | .DESCRIPTION 7 | Helps you work with Emoji in PowerShell. 8 | #> 9 | [Alias( 10 | 'Get-Emoji','Set-Emoji', 11 | 'Find-Emoji', 'Search-Emoji', 12 | 'Import-Emoji', 'Export-Emoji' 13 | )] 14 | [CmdletBinding(PositionalBinding=$false,SupportsShouldProcess,SupportsPaging)] 15 | param() 16 | 17 | dynamicParam { 18 | $myName = $MyInvocation.InvocationName 19 | $myVerb, $myNoun = 20 | if ($myName -match '-') { $myName -split '-',2 } 21 | else { $myName -split '\p{P}',2 } 22 | 23 | if (-not $myNoun) { 24 | $myNoun = $myVerb 25 | $myVerb = "Get" 26 | } 27 | 28 | if (-not $myNoun) { return } 29 | 30 | $nounTypeData = Get-TypeData -TypeName $myNoun 31 | 32 | $DynamicParameters = [Management.Automation.RuntimeDefinedParameterDictionary]::new() 33 | 34 | $typeDataForVerb = $nounTypeData.Members[$myVerb] 35 | if ( 36 | ($typeDataForVerb -is [Management.Automation.Runspaces.AliasPropertyData]) -and 37 | ($nounTypeData.Members[$typeDataForVerb.ReferencedMemberName] -is 38 | [Management.Automation.Runspaces.ScriptMethodData]) 39 | ) { 40 | $typeDataForVerb = $nounTypeData.Members[$typeDataForVerb.ReferencedMemberName] 41 | } 42 | 43 | if ($typeDataForVerb -is [Management.Automation.Runspaces.ScriptMethodData]) { 44 | $function:TempFunction = $typeDataForVerb.Script 45 | $tempFunctionMetadata = [Management.Automation.CommandMetadata]$ExecutionContext.SessionState.InvokeCommand.GetCommand('TempFunction','Function') 46 | foreach ($functionParameter in $tempFunctionMetadata.Parameters.Values) { 47 | $DynamicParameters.Add($functionParameter.Name, 48 | [Management.Automation.RuntimeDefinedParameter]::new( 49 | $functionParameter.Name,$functionParameter.ParameterType, @( 50 | $functionParameter.Attributes 51 | ) 52 | ) 53 | ) 54 | } 55 | } 56 | return $DynamicParameters 57 | } 58 | 59 | process { 60 | $myName = $MyInvocation.InvocationName 61 | $myVerb, $myNoun = $myName -split '-',2 62 | if (-not $myNoun) { 63 | $myNoun = $myVerb 64 | $myVerb = "Get" 65 | } 66 | if (-not $myNoun) { 67 | return $Emoji 68 | } 69 | $nounTypeData = Get-TypeData -TypeName $myNoun 70 | $typeDataForVerb = $nounTypeData.Members[$myVerb] 71 | if ( 72 | ($typeDataForVerb -is [Management.Automation.Runspaces.AliasPropertyData]) -and 73 | ($nounTypeData.Members[$typeDataForVerb.ReferencedMemberName] -is 74 | [Management.Automation.Runspaces.ScriptMethodData]) 75 | ) { 76 | $typeDataForVerb = $nounTypeData.Members[$typeDataForVerb.ReferencedMemberName] 77 | } 78 | if (-not $typeDataForVerb) { return } 79 | $parametersForScript = [Ordered]@{} + $PSBoundParameters 80 | $function:InnerCommand = $typeDataForVerb.Script 81 | $innerCommandMetadata = $ExecutionContext.SessionState.InvokeCommand.GetCommand('InnerCommand','Function') -as 82 | [Management.Automation.CommandMetadata] 83 | foreach ($parameterName in @($parametersForScript.Keys)) { 84 | if (-not $innerCommandMetadata.Parameters[$parameterName]) { 85 | $parametersForScript.Remove($parameterName) 86 | } 87 | } 88 | if ($innerCommandMetadata.SupportsPaging) { 89 | if ($PSBoundParameters.First) { 90 | $parametersForScript.First = $PSBoundParameters.First 91 | } 92 | if ($PSBoundParameters.Skip) { 93 | $parametersForScript.Skip = $PSBoundParameters.Skip 94 | } 95 | } 96 | & $typeDataForVerb.Script @parametersForScript 97 | } 98 | 99 | } 100 | 101 | -------------------------------------------------------------------------------- /Data/AllEmojiBlocks.csv: -------------------------------------------------------------------------------- 1 | "RangeStart","RangeEnd","BlockName" 2 | "0000","007F","Basic Latin" 3 | "0080","00FF","Latin-1 Supplement" 4 | "0100","017F","Latin Extended-A" 5 | "0180","024F","Latin Extended-B" 6 | "0250","02AF","IPA Extensions" 7 | "02B0","02FF","Spacing Modifier Letters" 8 | "0300","036F","Combining Diacritical Marks" 9 | "0370","03FF","Greek and Coptic" 10 | "0400","04FF","Cyrillic" 11 | "0500","052F","Cyrillic Supplement" 12 | "0530","058F","Armenian" 13 | "0590","05FF","Hebrew" 14 | "0600","06FF","Arabic" 15 | "0700","074F","Syriac" 16 | "0750","077F","Arabic Supplement" 17 | "0780","07BF","Thaana" 18 | "07C0","07FF","NKo" 19 | "0800","083F","Samaritan" 20 | "0840","085F","Mandaic" 21 | "0860","086F","Syriac Supplement" 22 | "0870","089F","Arabic Extended-B" 23 | "08A0","08FF","Arabic Extended-A" 24 | "0900","097F","Devanagari" 25 | "0980","09FF","Bengali" 26 | "0A00","0A7F","Gurmukhi" 27 | "0A80","0AFF","Gujarati" 28 | "0B00","0B7F","Oriya" 29 | "0B80","0BFF","Tamil" 30 | "0C00","0C7F","Telugu" 31 | "0C80","0CFF","Kannada" 32 | "0D00","0D7F","Malayalam" 33 | "0D80","0DFF","Sinhala" 34 | "0E00","0E7F","Thai" 35 | "0E80","0EFF","Lao" 36 | "0F00","0FFF","Tibetan" 37 | "1000","109F","Myanmar" 38 | "10A0","10FF","Georgian" 39 | "1100","11FF","Hangul Jamo" 40 | "1200","137F","Ethiopic" 41 | "1380","139F","Ethiopic Supplement" 42 | "13A0","13FF","Cherokee" 43 | "1400","167F","Unified Canadian Aboriginal Syllabics" 44 | "1680","169F","Ogham" 45 | "16A0","16FF","Runic" 46 | "1700","171F","Tagalog" 47 | "1720","173F","Hanunoo" 48 | "1740","175F","Buhid" 49 | "1760","177F","Tagbanwa" 50 | "1780","17FF","Khmer" 51 | "1800","18AF","Mongolian" 52 | "18B0","18FF","Unified Canadian Aboriginal Syllabics Extended" 53 | "1900","194F","Limbu" 54 | "1950","197F","Tai Le" 55 | "1980","19DF","New Tai Lue" 56 | "19E0","19FF","Khmer Symbols" 57 | "1A00","1A1F","Buginese" 58 | "1A20","1AAF","Tai Tham" 59 | "1AB0","1AFF","Combining Diacritical Marks Extended" 60 | "1B00","1B7F","Balinese" 61 | "1B80","1BBF","Sundanese" 62 | "1BC0","1BFF","Batak" 63 | "1C00","1C4F","Lepcha" 64 | "1C50","1C7F","Ol Chiki" 65 | "1C80","1C8F","Cyrillic Extended-C" 66 | "1C90","1CBF","Georgian Extended" 67 | "1CC0","1CCF","Sundanese Supplement" 68 | "1CD0","1CFF","Vedic Extensions" 69 | "1D00","1D7F","Phonetic Extensions" 70 | "1D80","1DBF","Phonetic Extensions Supplement" 71 | "1DC0","1DFF","Combining Diacritical Marks Supplement" 72 | "1E00","1EFF","Latin Extended Additional" 73 | "1F00","1FFF","Greek Extended" 74 | "2000","206F","General Punctuation" 75 | "2070","209F","Superscripts and Subscripts" 76 | "20A0","20CF","Currency Symbols" 77 | "20D0","20FF","Combining Diacritical Marks for Symbols" 78 | "2100","214F","Letterlike Symbols" 79 | "2150","218F","Number Forms" 80 | "2190","21FF","Arrows" 81 | "2200","22FF","Mathematical Operators" 82 | "2300","23FF","Miscellaneous Technical" 83 | "2400","243F","Control Pictures" 84 | "2440","245F","Optical Character Recognition" 85 | "2460","24FF","Enclosed Alphanumerics" 86 | "2500","257F","Box Drawing" 87 | "2580","259F","Block Elements" 88 | "25A0","25FF","Geometric Shapes" 89 | "2600","26FF","Miscellaneous Symbols" 90 | "2700","27BF","Dingbats" 91 | "27C0","27EF","Miscellaneous Mathematical Symbols-A" 92 | "27F0","27FF","Supplemental Arrows-A" 93 | "2800","28FF","Braille Patterns" 94 | "2900","297F","Supplemental Arrows-B" 95 | "2980","29FF","Miscellaneous Mathematical Symbols-B" 96 | "2A00","2AFF","Supplemental Mathematical Operators" 97 | "2B00","2BFF","Miscellaneous Symbols and Arrows" 98 | "2C00","2C5F","Glagolitic" 99 | "2C60","2C7F","Latin Extended-C" 100 | "2C80","2CFF","Coptic" 101 | "2D00","2D2F","Georgian Supplement" 102 | "2D30","2D7F","Tifinagh" 103 | "2D80","2DDF","Ethiopic Extended" 104 | "2DE0","2DFF","Cyrillic Extended-A" 105 | "2E00","2E7F","Supplemental Punctuation" 106 | "2E80","2EFF","CJK Radicals Supplement" 107 | "2F00","2FDF","Kangxi Radicals" 108 | "2FF0","2FFF","Ideographic Description Characters" 109 | "3000","303F","CJK Symbols and Punctuation" 110 | "3040","309F","Hiragana" 111 | "30A0","30FF","Katakana" 112 | "3100","312F","Bopomofo" 113 | "3130","318F","Hangul Compatibility Jamo" 114 | "3190","319F","Kanbun" 115 | "31A0","31BF","Bopomofo Extended" 116 | "31C0","31EF","CJK Strokes" 117 | "31F0","31FF","Katakana Phonetic Extensions" 118 | "3200","32FF","Enclosed CJK Letters and Months" 119 | "3300","33FF","CJK Compatibility" 120 | "3400","4DBF","CJK Unified Ideographs Extension A" 121 | "4DC0","4DFF","Yijing Hexagram Symbols" 122 | "4E00","9FFF","CJK Unified Ideographs" 123 | "A000","A48F","Yi Syllables" 124 | "A490","A4CF","Yi Radicals" 125 | "A4D0","A4FF","Lisu" 126 | "A500","A63F","Vai" 127 | "A640","A69F","Cyrillic Extended-B" 128 | "A6A0","A6FF","Bamum" 129 | "A700","A71F","Modifier Tone Letters" 130 | "A720","A7FF","Latin Extended-D" 131 | "A800","A82F","Syloti Nagri" 132 | "A830","A83F","Common Indic Number Forms" 133 | "A840","A87F","Phags-pa" 134 | "A880","A8DF","Saurashtra" 135 | "A8E0","A8FF","Devanagari Extended" 136 | "A900","A92F","Kayah Li" 137 | "A930","A95F","Rejang" 138 | "A960","A97F","Hangul Jamo Extended-A" 139 | "A980","A9DF","Javanese" 140 | "A9E0","A9FF","Myanmar Extended-B" 141 | "AA00","AA5F","Cham" 142 | "AA60","AA7F","Myanmar Extended-A" 143 | "AA80","AADF","Tai Viet" 144 | "AAE0","AAFF","Meetei Mayek Extensions" 145 | "AB00","AB2F","Ethiopic Extended-A" 146 | "AB30","AB6F","Latin Extended-E" 147 | "AB70","ABBF","Cherokee Supplement" 148 | "ABC0","ABFF","Meetei Mayek" 149 | "AC00","D7AF","Hangul Syllables" 150 | "D7B0","D7FF","Hangul Jamo Extended-B" 151 | "D800","DB7F","High Surrogates" 152 | "DB80","DBFF","High Private Use Surrogates" 153 | "DC00","DFFF","Low Surrogates" 154 | "E000","F8FF","Private Use Area" 155 | "F900","FAFF","CJK Compatibility Ideographs" 156 | "FB00","FB4F","Alphabetic Presentation Forms" 157 | "FB50","FDFF","Arabic Presentation Forms-A" 158 | "FE00","FE0F","Variation Selectors" 159 | "FE10","FE1F","Vertical Forms" 160 | "FE20","FE2F","Combining Half Marks" 161 | "FE30","FE4F","CJK Compatibility Forms" 162 | "FE50","FE6F","Small Form Variants" 163 | "FE70","FEFF","Arabic Presentation Forms-B" 164 | "FF00","FFEF","Halfwidth and Fullwidth Forms" 165 | "FFF0","FFFF","Specials" 166 | "10000","1007F","Linear B Syllabary" 167 | "10080","100FF","Linear B Ideograms" 168 | "10100","1013F","Aegean Numbers" 169 | "10140","1018F","Ancient Greek Numbers" 170 | "10190","101CF","Ancient Symbols" 171 | "101D0","101FF","Phaistos Disc" 172 | "10280","1029F","Lycian" 173 | "102A0","102DF","Carian" 174 | "102E0","102FF","Coptic Epact Numbers" 175 | "10300","1032F","Old Italic" 176 | "10330","1034F","Gothic" 177 | "10350","1037F","Old Permic" 178 | "10380","1039F","Ugaritic" 179 | "103A0","103DF","Old Persian" 180 | "10400","1044F","Deseret" 181 | "10450","1047F","Shavian" 182 | "10480","104AF","Osmanya" 183 | "104B0","104FF","Osage" 184 | "10500","1052F","Elbasan" 185 | "10530","1056F","Caucasian Albanian" 186 | "10570","105BF","Vithkuqi" 187 | "10600","1077F","Linear A" 188 | "10780","107BF","Latin Extended-F" 189 | "10800","1083F","Cypriot Syllabary" 190 | "10840","1085F","Imperial Aramaic" 191 | "10860","1087F","Palmyrene" 192 | "10880","108AF","Nabataean" 193 | "108E0","108FF","Hatran" 194 | "10900","1091F","Phoenician" 195 | "10920","1093F","Lydian" 196 | "10980","1099F","Meroitic Hieroglyphs" 197 | "109A0","109FF","Meroitic Cursive" 198 | "10A00","10A5F","Kharoshthi" 199 | "10A60","10A7F","Old South Arabian" 200 | "10A80","10A9F","Old North Arabian" 201 | "10AC0","10AFF","Manichaean" 202 | "10B00","10B3F","Avestan" 203 | "10B40","10B5F","Inscriptional Parthian" 204 | "10B60","10B7F","Inscriptional Pahlavi" 205 | "10B80","10BAF","Psalter Pahlavi" 206 | "10C00","10C4F","Old Turkic" 207 | "10C80","10CFF","Old Hungarian" 208 | "10D00","10D3F","Hanifi Rohingya" 209 | "10E60","10E7F","Rumi Numeral Symbols" 210 | "10E80","10EBF","Yezidi" 211 | "10EC0","10EFF","Arabic Extended-C" 212 | "10F00","10F2F","Old Sogdian" 213 | "10F30","10F6F","Sogdian" 214 | "10F70","10FAF","Old Uyghur" 215 | "10FB0","10FDF","Chorasmian" 216 | "10FE0","10FFF","Elymaic" 217 | "11000","1107F","Brahmi" 218 | "11080","110CF","Kaithi" 219 | "110D0","110FF","Sora Sompeng" 220 | "11100","1114F","Chakma" 221 | "11150","1117F","Mahajani" 222 | "11180","111DF","Sharada" 223 | "111E0","111FF","Sinhala Archaic Numbers" 224 | "11200","1124F","Khojki" 225 | "11280","112AF","Multani" 226 | "112B0","112FF","Khudawadi" 227 | "11300","1137F","Grantha" 228 | "11400","1147F","Newa" 229 | "11480","114DF","Tirhuta" 230 | "11580","115FF","Siddham" 231 | "11600","1165F","Modi" 232 | "11660","1167F","Mongolian Supplement" 233 | "11680","116CF","Takri" 234 | "11700","1174F","Ahom" 235 | "11800","1184F","Dogra" 236 | "118A0","118FF","Warang Citi" 237 | "11900","1195F","Dives Akuru" 238 | "119A0","119FF","Nandinagari" 239 | "11A00","11A4F","Zanabazar Square" 240 | "11A50","11AAF","Soyombo" 241 | "11AB0","11ABF","Unified Canadian Aboriginal Syllabics Extended-A" 242 | "11AC0","11AFF","Pau Cin Hau" 243 | "11B00","11B5F","Devanagari Extended-A" 244 | "11C00","11C6F","Bhaiksuki" 245 | "11C70","11CBF","Marchen" 246 | "11D00","11D5F","Masaram Gondi" 247 | "11D60","11DAF","Gunjala Gondi" 248 | "11EE0","11EFF","Makasar" 249 | "11F00","11F5F","Kawi" 250 | "11FB0","11FBF","Lisu Supplement" 251 | "11FC0","11FFF","Tamil Supplement" 252 | "12000","123FF","Cuneiform" 253 | "12400","1247F","Cuneiform Numbers and Punctuation" 254 | "12480","1254F","Early Dynastic Cuneiform" 255 | "12F90","12FFF","Cypro-Minoan" 256 | "13000","1342F","Egyptian Hieroglyphs" 257 | "13430","1345F","Egyptian Hieroglyph Format Controls" 258 | "14400","1467F","Anatolian Hieroglyphs" 259 | "16800","16A3F","Bamum Supplement" 260 | "16A40","16A6F","Mro" 261 | "16A70","16ACF","Tangsa" 262 | "16AD0","16AFF","Bassa Vah" 263 | "16B00","16B8F","Pahawh Hmong" 264 | "16E40","16E9F","Medefaidrin" 265 | "16F00","16F9F","Miao" 266 | "16FE0","16FFF","Ideographic Symbols and Punctuation" 267 | "17000","187FF","Tangut" 268 | "18800","18AFF","Tangut Components" 269 | "18B00","18CFF","Khitan Small Script" 270 | "18D00","18D7F","Tangut Supplement" 271 | "1AFF0","1AFFF","Kana Extended-B" 272 | "1B000","1B0FF","Kana Supplement" 273 | "1B100","1B12F","Kana Extended-A" 274 | "1B130","1B16F","Small Kana Extension" 275 | "1B170","1B2FF","Nushu" 276 | "1BC00","1BC9F","Duployan" 277 | "1BCA0","1BCAF","Shorthand Format Controls" 278 | "1CF00","1CFCF","Znamenny Musical Notation" 279 | "1D000","1D0FF","Byzantine Musical Symbols" 280 | "1D100","1D1FF","Musical Symbols" 281 | "1D200","1D24F","Ancient Greek Musical Notation" 282 | "1D2C0","1D2DF","Kaktovik Numerals" 283 | "1D2E0","1D2FF","Mayan Numerals" 284 | "1D300","1D35F","Tai Xuan Jing Symbols" 285 | "1D360","1D37F","Counting Rod Numerals" 286 | "1D400","1D7FF","Mathematical Alphanumeric Symbols" 287 | "1D800","1DAAF","Sutton SignWriting" 288 | "1DF00","1DFFF","Latin Extended-G" 289 | "1E000","1E02F","Glagolitic Supplement" 290 | "1E030","1E08F","Cyrillic Extended-D" 291 | "1E100","1E14F","Nyiakeng Puachue Hmong" 292 | "1E290","1E2BF","Toto" 293 | "1E2C0","1E2FF","Wancho" 294 | "1E4D0","1E4FF","Nag Mundari" 295 | "1E7E0","1E7FF","Ethiopic Extended-B" 296 | "1E800","1E8DF","Mende Kikakui" 297 | "1E900","1E95F","Adlam" 298 | "1EC70","1ECBF","Indic Siyaq Numbers" 299 | "1ED00","1ED4F","Ottoman Siyaq Numbers" 300 | "1EE00","1EEFF","Arabic Mathematical Alphabetic Symbols" 301 | "1F000","1F02F","Mahjong Tiles" 302 | "1F030","1F09F","Domino Tiles" 303 | "1F0A0","1F0FF","Playing Cards" 304 | "1F100","1F1FF","Enclosed Alphanumeric Supplement" 305 | "1F200","1F2FF","Enclosed Ideographic Supplement" 306 | "1F300","1F5FF","Miscellaneous Symbols and Pictographs" 307 | "1F600","1F64F","Emoticons" 308 | "1F650","1F67F","Ornamental Dingbats" 309 | "1F680","1F6FF","Transport and Map Symbols" 310 | "1F700","1F77F","Alchemical Symbols" 311 | "1F780","1F7FF","Geometric Shapes Extended" 312 | "1F800","1F8FF","Supplemental Arrows-C" 313 | "1F900","1F9FF","Supplemental Symbols and Pictographs" 314 | "1FA00","1FA6F","Chess Symbols" 315 | "1FA70","1FAFF","Symbols and Pictographs Extended-A" 316 | "1FB00","1FBFF","Symbols for Legacy Computing" 317 | "20000","2A6DF","CJK Unified Ideographs Extension B" 318 | "2A700","2B73F","CJK Unified Ideographs Extension C" 319 | "2B740","2B81F","CJK Unified Ideographs Extension D" 320 | "2B820","2CEAF","CJK Unified Ideographs Extension E" 321 | "2CEB0","2EBEF","CJK Unified Ideographs Extension F" 322 | "2EBF0","2EE5F","CJK Unified Ideographs Extension I" 323 | "2F800","2FA1F","CJK Compatibility Ideographs Supplement" 324 | "30000","3134F","CJK Unified Ideographs Extension G" 325 | "31350","323AF","CJK Unified Ideographs Extension H" 326 | "E0000","E007F","Tags" 327 | "E0100","E01EF","Variation Selectors Supplement" 328 | "F0000","FFFFF","Supplementary Private Use Area-A" 329 | "100000","10FFFF","Supplementary Private Use Area-B" 330 | -------------------------------------------------------------------------------- /Demos/Emoji.demo.ps1: -------------------------------------------------------------------------------- 1 | #1. 😎 2 | 3 | # Emoji is a cute little module to work with Emoji. 4 | 5 | # It has every named character in the unicode dataset. 6 | 7 | # Find-Emoji lets us search by keyword. 8 | Find-Emoji "sunglasses" 9 | 10 | # (that's why it's also called Search-Emoji). 11 | Search-Emoji "boat" 12 | 13 | # Get-Emoji can get emoji by name. 14 | Get-Emoji -Name "sailboat" 15 | 16 | #2. 😉 17 | 18 | # Find-Emoji is more powerful than it looks. 19 | 20 | # By default, it uses a regular expression. 21 | 22 | # Let's find all emoji ending in cat or dog 23 | Find-Emoji "(?>Cat|Dog)$" 24 | 25 | # We can also narrow it down with -Word, which will only look for whole words 26 | Find-Emoji "(?>Lion|Tiger|Bear)" -Word 27 | 28 | # Don't like regex? Just use -like: 29 | Find-Emoji -Like "*left*arrow*" 30 | 31 | #3. 😍 32 | 33 | # We can also get all of the character blocks: 34 | 35 | Get-Emoji -Block 36 | 37 | # Or see a specific block 38 | Get-Emoji -BlockName Emoticons 39 | 40 | # Don't forget the object pipeline, it's your friend: 41 | 42 | Get-Emoji -Block | 43 | Where-Object BlockName -like '*box*' | 44 | Get-Emoji 45 | 46 | #4. 🥰 47 | 48 | # Emoji are playful. 49 | 50 | # Here are a few games we can play with Emoji. 51 | 52 | # Cards: 53 | Search-Emoji "Playing Card" 54 | 55 | # Chess: 56 | Search-Emoji "chess" | 57 | Where-Object Number -lt 10kb 58 | 59 | # Dominos: 60 | Search-Emoji "Domino" 61 | 62 | # Mahjong: 63 | Get-Emoji -BlockName 'Mahjong Tiles' 64 | 65 | # Emoji can make music: 66 | Get-Emoji -BlockName 'Musical Symbols' 67 | 68 | # It can even show you how the Ancient Greeks made music: 69 | Get-Emoji -BlockName 'Ancient Greek Musical Notation' 70 | 71 | # Or we could learn some alchemy: 72 | Get-Emoji -BlockName 'Alchemical Symbols' 73 | 74 | # Maybe try to learn Hieroglyphs? 75 | Get-Emoji -BlockName 'Egyptian Hieroglyphs' 76 | 77 | # Not ancient enough for you? 78 | # How about some Linear A / Linear B: 79 | Get-Emoji -Block | 80 | Where-Object BlockName -like 'Linear *' | 81 | Get-Emoji 82 | 83 | # There are a lot of Emoji to play with. 84 | 85 | # Of course, the Emoji module can do more than just search Emoji. -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/powershell 2 | ENV PSModulePath ./Modules 3 | COPY . ./Modules/Emoji 4 | RUN pwsh -c "New-Item -Path /root/.config/powershell/Microsoft.PowerShell_profile.ps1 -Value 'Import-Module Emoji' -Force" 5 | 6 | -------------------------------------------------------------------------------- /Emoji.format.ps1xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Emoji.Block 6 | 7 | Emoji.Block 8 | 9 | 10 | 11 | 12 | 13 | Right 14 | 15 | 16 | Center 17 | 18 | 19 | Left 20 | 21 | 22 | 23 | 24 | 25 | 26 | Start 27 | 28 | 29 | BlockName 30 | 31 | 32 | End 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | Emoji.Sequence 41 | 42 | Emoji.Sequence 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | Name 61 | 62 | 63 | $_.ExportedCommands.Keys -join [Environment]::NewLine 64 | 65 | 66 | $_.ExportedVariables.Keys -join [Environment]::NewLine 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | Emoji.Symbol 75 | 76 | Emoji.Symbol 77 | 78 | 79 | 80 | 81 | 82 | 83 | Left 84 | 85 | 86 | 87 | Center 88 | 89 | 90 | 91 | Right 92 | 93 | 94 | 95 | 96 | 97 | 98 | $_.Emoji.ToString().PadRight(3) 99 | 100 | 101 | 102 | 103 | $CellColorValue = $($Script:_LastCellStyle ='Foreground.Green';$Script:_LastCellStyle) 104 | 105 | $CellColorValue = if ($psStyle) { 106 | @(foreach ($styleProp in $CellColorValue) { 107 | if ($styleProp -match '^\$') { 108 | $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) 109 | } 110 | elseif ($styleProp -match '\.') { 111 | $targetObject = $psStyle 112 | foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { 113 | if ( 114 | ($targetObject.psobject.Members['Item'] -and 115 | ($targetObject.Item -is [Management.Automation.PSMethodInfo]) 116 | ) -or 117 | $targetObject -is [Collections.IDictionary] 118 | ) { 119 | $targetObject = $targetObject[$dotProperty] 120 | } else { 121 | $targetObject = $targetObject.$dotProperty 122 | } 123 | } 124 | if ($targetObject) { 125 | $targetObject 126 | } 127 | } 128 | else { 129 | $psStyle.$styleProp 130 | } 131 | }) -join '' 132 | } 133 | 134 | $output = . {$_.'Name'} 135 | @($CellColorValue; $output; $psStyle.Reset) -join '' 136 | 137 | 138 | 139 | 140 | 141 | $CellColorValue = $($Script:_LastCellStyle ='Foreground.Cyan';$Script:_LastCellStyle) 142 | 143 | $CellColorValue = if ($psStyle) { 144 | @(foreach ($styleProp in $CellColorValue) { 145 | if ($styleProp -match '^\$') { 146 | $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) 147 | } 148 | elseif ($styleProp -match '\.') { 149 | $targetObject = $psStyle 150 | foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { 151 | if ( 152 | ($targetObject.psobject.Members['Item'] -and 153 | ($targetObject.Item -is [Management.Automation.PSMethodInfo]) 154 | ) -or 155 | $targetObject -is [Collections.IDictionary] 156 | ) { 157 | $targetObject = $targetObject[$dotProperty] 158 | } else { 159 | $targetObject = $targetObject.$dotProperty 160 | } 161 | } 162 | if ($targetObject) { 163 | $targetObject 164 | } 165 | } 166 | else { 167 | $psStyle.$styleProp 168 | } 169 | }) -join '' 170 | } 171 | 172 | $output = . {$_.'Hex'} 173 | @($CellColorValue; $output; $psStyle.Reset) -join '' 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | PowerShell 183 | 184 | Emoji.Symbol 185 | 186 | 187 | 188 | 189 | 190 | 191 | Left 192 | 193 | 194 | 195 | Center 196 | 197 | 198 | Right 199 | 200 | 201 | 202 | 203 | 204 | 205 | $_.Emoji.ToString().PadRight(3) 206 | 207 | 208 | 209 | 210 | $CellColorValue = $($Script:_LastCellStyle ='Foreground.Green';$Script:_LastCellStyle) 211 | 212 | $CellColorValue = if ($psStyle) { 213 | @(foreach ($styleProp in $CellColorValue) { 214 | if ($styleProp -match '^\$') { 215 | $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) 216 | } 217 | elseif ($styleProp -match '\.') { 218 | $targetObject = $psStyle 219 | foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { 220 | if ( 221 | ($targetObject.psobject.Members['Item'] -and 222 | ($targetObject.Item -is [Management.Automation.PSMethodInfo]) 223 | ) -or 224 | $targetObject -is [Collections.IDictionary] 225 | ) { 226 | $targetObject = $targetObject[$dotProperty] 227 | } else { 228 | $targetObject = $targetObject.$dotProperty 229 | } 230 | } 231 | if ($targetObject) { 232 | $targetObject 233 | } 234 | } 235 | else { 236 | $psStyle.$styleProp 237 | } 238 | }) -join '' 239 | } 240 | 241 | $output = . {$_.'Name'} 242 | @($CellColorValue; $output; $psStyle.Reset) -join '' 243 | 244 | 245 | 246 | PowerShell 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | Emoji 255 | 256 | Emoji.Symbol 257 | 258 | 259 | 260 | 261 | 262 | Left 263 | 264 | 265 | 266 | 267 | 268 | 269 | Emoji 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | CSS 278 | 279 | Emoji.Symbol 280 | 281 | 282 | 283 | 284 | 285 | Left 286 | 287 | 288 | 289 | 290 | 291 | 292 | CSS 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | Html 301 | 302 | Emoji.Symbol 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | Left 314 | 315 | 316 | 317 | 318 | 319 | 320 | Emoji 321 | 322 | 323 | 324 | 325 | $CellColorValue = $($Script:_LastCellStyle ='Foreground.Green';$Script:_LastCellStyle) 326 | 327 | $CellColorValue = if ($psStyle) { 328 | @(foreach ($styleProp in $CellColorValue) { 329 | if ($styleProp -match '^\$') { 330 | $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) 331 | } 332 | elseif ($styleProp -match '\.') { 333 | $targetObject = $psStyle 334 | foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { 335 | if ( 336 | ($targetObject.psobject.Members['Item'] -and 337 | ($targetObject.Item -is [Management.Automation.PSMethodInfo]) 338 | ) -or 339 | $targetObject -is [Collections.IDictionary] 340 | ) { 341 | $targetObject = $targetObject[$dotProperty] 342 | } else { 343 | $targetObject = $targetObject.$dotProperty 344 | } 345 | } 346 | if ($targetObject) { 347 | $targetObject 348 | } 349 | } 350 | else { 351 | $psStyle.$styleProp 352 | } 353 | }) -join '' 354 | } 355 | 356 | $output = . {$_.'Name'} 357 | @($CellColorValue; $output; $psStyle.Reset) -join '' 358 | 359 | 360 | 361 | HTML 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | Emoji.Symbol 370 | 371 | Emoji.Symbol 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | $_.Emoji.PadRight(4) 380 | 381 | 382 | 383 | if ($psStyle) { 384 | @(foreach ($styleProp in 'Foreground.Green') { 385 | 386 | if ($styleProp -match '^\$') { 387 | $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) 388 | } 389 | elseif ($styleProp -match '\.') { 390 | $targetObject = $psStyle 391 | foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { 392 | if ( 393 | ($targetObject.psobject.Members['Item'] -and 394 | ($targetObject.Item -is [Management.Automation.PSMethodInfo]) 395 | ) -or 396 | $targetObject -is [Collections.IDictionary] 397 | ) { 398 | $targetObject = $targetObject[$dotProperty] 399 | } else { 400 | $targetObject = $targetObject.$dotProperty 401 | } 402 | } 403 | if ($targetObject) { 404 | $targetObject 405 | } 406 | } 407 | else { 408 | $psStyle.$styleProp 409 | } 410 | 411 | }) -ne '' -join '' 412 | } 413 | 414 | 415 | Name 416 | 417 | 418 | 419 | if ($PSStyle) { 420 | $PSStyle.Reset 421 | } 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | Emoji 431 | 432 | Emoji.Symbol 433 | 434 | 435 | 436 | 437 | 438 | 439 | Emoji 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | PowerShell 448 | 449 | Emoji.Symbol 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | $_.Emoji.PadRight(4) 458 | 459 | 460 | 461 | if ($psStyle) { 462 | @(foreach ($styleProp in 'Foreground.Cyan') { 463 | 464 | if ($styleProp -match '^\$') { 465 | $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) 466 | } 467 | elseif ($styleProp -match '\.') { 468 | $targetObject = $psStyle 469 | foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { 470 | if ( 471 | ($targetObject.psobject.Members['Item'] -and 472 | ($targetObject.Item -is [Management.Automation.PSMethodInfo]) 473 | ) -or 474 | $targetObject -is [Collections.IDictionary] 475 | ) { 476 | $targetObject = $targetObject[$dotProperty] 477 | } else { 478 | $targetObject = $targetObject.$dotProperty 479 | } 480 | } 481 | if ($targetObject) { 482 | $targetObject 483 | } 484 | } 485 | else { 486 | $psStyle.$styleProp 487 | } 488 | 489 | }) -ne '' -join '' 490 | } 491 | 492 | 493 | PowerShell 494 | 495 | 496 | 497 | if ($PSStyle) { 498 | $PSStyle.Reset 499 | } 500 | 501 | 502 | 503 | if ($psStyle) { 504 | @(foreach ($styleProp in 'Foreground.Green') { 505 | 506 | if ($styleProp -match '^\$') { 507 | $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) 508 | } 509 | elseif ($styleProp -match '\.') { 510 | $targetObject = $psStyle 511 | foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { 512 | if ( 513 | ($targetObject.psobject.Members['Item'] -and 514 | ($targetObject.Item -is [Management.Automation.PSMethodInfo]) 515 | ) -or 516 | $targetObject -is [Collections.IDictionary] 517 | ) { 518 | $targetObject = $targetObject[$dotProperty] 519 | } else { 520 | $targetObject = $targetObject.$dotProperty 521 | } 522 | } 523 | if ($targetObject) { 524 | $targetObject 525 | } 526 | } 527 | else { 528 | $psStyle.$styleProp 529 | } 530 | 531 | }) -ne '' -join '' 532 | } 533 | 534 | 535 | Name 536 | 537 | 538 | 539 | if ($PSStyle) { 540 | $PSStyle.Reset 541 | } 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | CSS 551 | 552 | Emoji.Symbol 553 | 554 | 555 | 556 | 557 | 558 | /* 559 | 560 | 561 | $_.Emoji.PadRight(3) 562 | 563 | 564 | */ 565 | 566 | 567 | CSS 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | HTML 576 | 577 | Emoji.Symbol 578 | 579 | 580 | 581 | 582 | 583 | 584 | HTML 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | -------------------------------------------------------------------------------- /Emoji.ps.psm1: -------------------------------------------------------------------------------- 1 | $CommandsPath = Join-Path $PSScriptRoot Commands 2 | [include('*-*.ps1')]$CommandsPath 3 | 4 | $myModule = $MyInvocation.MyCommand.ScriptBlock.Module 5 | $myModule.pstypenames.insert(0,$myModule.Name) 6 | Set-Item -Path "variable:$($myModule.Name)" -Value $myModule 7 | 8 | $newDriveCommonParameters = 9 | @{PSProvider='FileSystem';Scope='Global';ErrorAction='Ignore'} 10 | New-PSDrive -Name $myModule.name @newDriveCommonParameters -Root ($myModule | Split-Path) 11 | 12 | if ($home) { 13 | $MyMyModule= "My$($myModule.name)" 14 | New-PSDrive -Name $MyMyModule @newDriveCommonParameters -Root (Join-Path $home $MyMyModule) 15 | } 16 | 17 | 18 | Export-ModuleMember -Function * -Alias * -Variable $myModule.Name -------------------------------------------------------------------------------- /Emoji.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | ModuleVersion = '0.1.5' 3 | RootModule = 'Emoji.psm1' 4 | 5 | Description = '⟩⚡PowerShell Emoji 😎😉😍🥰🤔😟' 6 | 7 | FormatsToProcess = 'Emoji.format.ps1xml' 8 | TypesToProcess = 'Emoji.types.ps1xml' 9 | 10 | Guid = 'a82424bc-4a28-4151-8b9e-79289775c29b' 11 | CompanyName = 'Start-Automating' 12 | Author = 'James Brundage' 13 | Copyright = '2024 Start-Automating' 14 | 15 | PrivateData = @{ 16 | PSData = @{ 17 | ProjectURI = 'https://github.com/StartAutomating/Emoji' 18 | LicenseURI = 'https://github.com/StartAutomating/blob/main/LICENSE' 19 | Tags = 'Emoji', 'PowerShell' 20 | ReleaseNotes = @' 21 | ## Emoji 0.1.5: 22 | 23 | * Emoji.Symbol.HTML (#66) 24 | * ... and new views (#62) 25 | * Emoji Docker Support (#63, #64, #65) 26 | 27 | --- 28 | 29 | Full history in [CHANGELOG](https://github.com/StartAutomating/Emoji/blob/main/CHANGELOG.md) 30 | 31 | > Like It? [Star It](https://github.com/StartAutomating/Emoji) 32 | > Love It? [Support It](https://github.com/sponsors/StartAutomating) 33 | 34 | '@ 35 | } 36 | Recommends = 'Posh','PipeScript','EZOut' 37 | } 38 | } -------------------------------------------------------------------------------- /Emoji.psm1: -------------------------------------------------------------------------------- 1 | $CommandsPath = Join-Path $PSScriptRoot Commands 2 | :ToIncludeFiles foreach ($file in (Get-ChildItem -Path "$CommandsPath" -Filter "*-*.ps1" -Recurse)) { 3 | if ($file.Extension -ne '.ps1') { continue } # Skip if the extension is not .ps1 4 | foreach ($exclusion in '\.[^\.]+\.ps1$') { 5 | if (-not $exclusion) { continue } 6 | if ($file.Name -match $exclusion) { 7 | continue ToIncludeFiles # Skip excluded files 8 | } 9 | } 10 | . $file.FullName 11 | } 12 | 13 | $myModule = $MyInvocation.MyCommand.ScriptBlock.Module 14 | $myModule.pstypenames.insert(0,$myModule.Name) 15 | Set-Item -Path "variable:$($myModule.Name)" -Value $myModule 16 | 17 | $newDriveCommonParameters = 18 | @{PSProvider='FileSystem';Scope='Global';ErrorAction='Ignore'} 19 | New-PSDrive -Name $myModule.name @newDriveCommonParameters -Root ($myModule | Split-Path) 20 | 21 | if ($home) { 22 | $MyMyModule= "My$($myModule.name)" 23 | New-PSDrive -Name $MyMyModule @newDriveCommonParameters -Root (Join-Path $home $MyMyModule) 24 | } 25 | 26 | 27 | Export-ModuleMember -Function * -Alias * -Variable $myModule.Name 28 | -------------------------------------------------------------------------------- /Emoji.tests.ps1: -------------------------------------------------------------------------------- 1 | describe Emoji { 2 | context "Emoji is a PowerShell Emoji Module" { 3 | it "Can Get-Emoji" { 4 | Get-Emoji -Name SOLIDUS | 5 | Select-Object -ExpandProperty String | 6 | Should -Be '/' 7 | } 8 | 9 | it "Can Find-Emoji" { 10 | Find-Emoji -Pattern "Face" | 11 | Select-Object -ExpandProperty Name | 12 | Should -BeLike '*Face*' 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Emoji.types.ps1xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Emoji 5 | 6 | 7 | Demos 8 | Demo 9 | 10 | 11 | Find 12 | Search 13 | 14 | 15 | Sequence 16 | Sequences 17 | 18 | 19 | Export 20 | 50 | 51 | 52 | Get 53 | 165 | 166 | 167 | GetPagingParameters 168 | 197 | 198 | 199 | Import 200 | 246 | 247 | 248 | Search 249 | 299 | 300 | 301 | Set 302 | 346 | 347 | 348 | Blocks 349 | 350 | if (-not $this.'.Blocks') { 351 | $theseBlocks = [Ordered]@{} 352 | $allEmojiBlocks = Get-Module Emoji | Split-Path | Join-Path -ChildPath "Data" | Join-Path -ChildPath "AllEmojiBlocks.csv" | Import-Csv 353 | foreach ($emojiBlock in $allEmojiBlocks) { 354 | $emojiBlock.pstypenames.clear() 355 | $emojiBlock.pstypenames.add('Emoji.Block') 356 | $theseBlocks[$emojiBlock.BlockName] = $emojiBlock 357 | } 358 | Add-Member -InputObject $this -MemberType NoteProperty -Force -Name ".Blocks" -Value $theseBlocks 359 | } 360 | 361 | $this.'.Blocks' 362 | 363 | 364 | 365 | Demo 366 | 367 | <# 368 | .SYNOPSIS 369 | Gets module demos 370 | .DESCRIPTION 371 | Gets demo files related to a module. 372 | .EXAMPLE 373 | $Posh.Demos 374 | .LINK 375 | https://github.com/StartAutomating/ShowDemo 376 | #> 377 | $this | 378 | Split-Path | 379 | Get-ChildItem -Recurse -Filter *.demo.ps1 380 | 381 | 382 | 383 | Sequences 384 | 385 | <# 386 | .SYNOPSIS 387 | Emoji Sequences 388 | .DESCRIPTION 389 | Gets the Emoji Sequences Collection 390 | #> 391 | if (-not $this.'.Sequences') { 392 | $this | Add-Member NoteProperty '.Sequences' ( 393 | [PSCustomObject]@{PSTypeName='Emoji.Sequences'} 394 | ) -Force 395 | } 396 | 397 | $this.'.Sequences' 398 | 399 | 400 | <# 401 | .SYNOPSIS 402 | Sets Emoji Sequences 403 | .DESCRIPTION 404 | Sets the Emoji Sequences Collection. 405 | .NOTES 406 | Any string arguments will be considered the sequence. 407 | The first non-string argument will be considered the value. 408 | #> 409 | param() 410 | 411 | $unrolledArgs = $args | . { process { $_ } } 412 | 413 | if (-not $this.'.Sequences') { 414 | $this | Add-Member NoteProperty '.Sequences' ( 415 | [PSCustomObject]@{PSTypeName='Emoji.Sequences'} 416 | ) -Force 417 | } 418 | 419 | $Value = $null 420 | $emojiSequence = foreach ($arg in $unrolledArgs) { 421 | if ($arg -is [string]) { 422 | $arg 423 | } elseif (-not $value) { 424 | $value = $arg 425 | } 426 | } 427 | 428 | if ($emojiSequence -and $Value) { 429 | $this.'.Sequences'.Add($emojiSequence -join '', $value) 430 | } 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | Emoji.Block 440 | 441 | 442 | End 443 | 444 | <# 445 | .SYNOPSIS 446 | Get an Emoji Block's End 447 | .DESCRIPTION 448 | Gets the end of an Emoji Block's range. 449 | #> 450 | "0x$($this.RangeEnd)" -as [int] 451 | 452 | 453 | 454 | Length 455 | 456 | <# 457 | .SYNOPSIS 458 | Get an Emoji Block's Length 459 | .DESCRIPTION 460 | Gets the number of characters in an Emoji Block's range. 461 | #> 462 | param() 463 | $this.End - $this.Start 464 | 465 | 466 | 467 | Range 468 | 469 | <# 470 | .SYNOPSIS 471 | Get an Emoji Block's Range 472 | .DESCRIPTION 473 | Gets the range of an Emoji Block. 474 | #> 475 | param() 476 | ($this.Start)..($this.End) -as [int[]] 477 | 478 | 479 | 480 | Start 481 | 482 | "0x$($this.RangeStart)" -as [int] 483 | 484 | 485 | 486 | 487 | 488 | Emoji.Sequence 489 | 490 | 491 | 492 | 493 | Emoji.Sequences 494 | 495 | 496 | Set 497 | Add 498 | 499 | 500 | Add 501 | 548 | 549 | 550 | Remove 551 | 567 | 568 | 569 | All 570 | 571 | <# 572 | .SYNOPSIS 573 | Gets Emoji Sequences 574 | .DESCRIPTION 575 | Gets all loaded Emoji Sequences 576 | #> 577 | param() 578 | foreach ($property in $this.psobject.properties) { 579 | if (-not $property.IsInstance) { continue } 580 | if ($property -isnot [psnoteproperty]) { continue } 581 | $property.Value 582 | } 583 | 584 | 585 | 586 | 587 | 588 | Emoji.Symbol 589 | 590 | 591 | Emoji 592 | String 593 | 594 | 595 | CSS 596 | 597 | <# 598 | .SYNOPSIS 599 | Gets an Emoji as CSS 600 | .DESCRIPTION 601 | Gets an Emoji as a CSS rule 602 | #> 603 | param() 604 | 605 | $className = $this.Name.ToLower() -replace '\s','-' 606 | ".${className}::before { content: `"$($this.Emoji)`"; }" 607 | 608 | 609 | 610 | 611 | HTML 612 | 613 | <# 614 | .SYNOPSIS 615 | Gets an Emoji as HTML 616 | .DESCRIPTION 617 | Gets an Emoji as an HTML span 618 | .EXAMPLE 619 | (Get-Emoji -Name 'Grinning Face').HTML 620 | #> 621 | param() 622 | 623 | "<span>$([Web.HttpUtility]::HtmlEncode($this.Emoji))</span>" 624 | 625 | 626 | 627 | 628 | Number 629 | 630 | <# 631 | .SYNOPSIS 632 | Gets the Emoji Number 633 | .DESCRIPTION 634 | Gets the Emoji's number, as an integer. 635 | #> 636 | "0x$($this.Hex)" -as [int] 637 | 638 | 639 | 640 | 641 | PowerShell 642 | 643 | <# 644 | .SYNOPSIS 645 | Gets an Emoji's PowerShell string 646 | .DESCRIPTION 647 | Gets a PowerShell string that would reproduce the Emoji. 648 | 649 | These strings will only work on PowerShell Core. 650 | #> 651 | param() 652 | '"`u{' + $this.Hex + '}"' 653 | 654 | 655 | 656 | 657 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 James Brundage 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | emoji 3 | 4 | 5 | 6 |
7 | ❤️ 8 | 9 |
10 | 11 | # Emoji 12 | ⟩⚡PowerShell Emoji 😎😉😍🥰🤔😟 13 | 14 | Emoji is a little PowerShell module to help you work with Emoji. 15 | 16 | It is built from the Unicode Character Dataset, which includes 44120 named symbols. 17 | 18 | ## Installing and Importing 19 | 20 | Emoji is on the PowerShell Gallery. 21 | 22 | You can install and import Emoji by using: 23 | 24 | ~~~PowerShell 25 | Install-Module Emoji -Scope CurrentUser -Force 26 | Import-Module Emoji 27 | ~~~ 28 | 29 | ## Searching Emoji 30 | 31 | Search-Emoji or Find-Emoji can be used to search loaded Emoji 32 | 33 | ~~~PowerShell 34 | # Find all of the Emoji faces 35 | Find-Emoji -Pattern "Face" 36 | ~~~ 37 | 38 | ~~~PowerShell 39 | # Search all emoji ending in cats and dogs 40 | Search-Emoji -Pattern "(Cat|Dog)$" 41 | ~~~ 42 | 43 | ~~~PowerShell 44 | # Find all emoji grins 45 | Find-Emoji -Pattern "*grin*" -Like 46 | ~~~ 47 | -------------------------------------------------------------------------------- /README.ps.md: -------------------------------------------------------------------------------- 1 |
2 | emoji 3 | 4 | 5 | 6 |
7 | ❤️ 8 | 9 |
10 | 11 | # Emoji 12 | ⟩⚡PowerShell Emoji 😎😉😍🥰🤔😟 13 | 14 | Emoji is a little PowerShell module to help you work with Emoji. 15 | 16 | It is built from the Unicode Character Dataset, which includes ```.>{@(Import-Csv (Join-Path "$pwd" Data | Join-Path -ChildPath "AllNamedEmoji.csv")).Length}<.``` named symbols. 17 | 18 | ## Installing and Importing 19 | 20 | Emoji is on the PowerShell Gallery. 21 | 22 | You can install and import Emoji by using: 23 | 24 | ~~~PowerShell 25 | Install-Module Emoji -Scope CurrentUser -Force 26 | Import-Module Emoji 27 | ~~~ 28 | 29 | ## Searching Emoji 30 | 31 | Search-Emoji or Find-Emoji can be used to search loaded Emoji 32 | 33 | ~~~PowerShell 34 | # Find all of the Emoji faces 35 | Find-Emoji -Pattern "Face" 36 | ~~~ 37 | 38 | ~~~PowerShell 39 | # Search all emoji ending in cats and dogs 40 | Search-Emoji -Pattern "(Cat|Dog)$" 41 | ~~~ 42 | 43 | ~~~PowerShell 44 | # Find all emoji grins 45 | Find-Emoji -Pattern "*grin*" -Like 46 | ~~~ -------------------------------------------------------------------------------- /Types/Emoji.Block/Emoji.Block.format.ps1: -------------------------------------------------------------------------------- 1 | Write-FormatView -TypeName Emoji.Block -Property 'Start', 'BlockName', 'End' -AlignProperty @{ 2 | Start = 'Right' 3 | End = 'Left' 4 | BlockName = 'Center' 5 | } -AutoSize 6 | -------------------------------------------------------------------------------- /Types/Emoji.Block/get_End.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Get an Emoji Block's End 4 | .DESCRIPTION 5 | Gets the end of an Emoji Block's range. 6 | #> 7 | "0x$($this.RangeEnd)" -as [int] -------------------------------------------------------------------------------- /Types/Emoji.Block/get_Length.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Get an Emoji Block's Length 4 | .DESCRIPTION 5 | Gets the number of characters in an Emoji Block's range. 6 | #> 7 | param() 8 | $this.End - $this.Start -------------------------------------------------------------------------------- /Types/Emoji.Block/get_Range.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Get an Emoji Block's Range 4 | .DESCRIPTION 5 | Gets the range of an Emoji Block. 6 | #> 7 | param() 8 | ($this.Start)..($this.End) -as [int[]] -------------------------------------------------------------------------------- /Types/Emoji.Block/get_Start.ps1: -------------------------------------------------------------------------------- 1 | "0x$($this.RangeStart)" -as [int] -------------------------------------------------------------------------------- /Types/Emoji.Sequence/Emoji.Sequence.format.ps1: -------------------------------------------------------------------------------- 1 | Write-FormatView -TypeName Emoji.Sequence -Property Name, ExportedCommands, ExportedVariables -VirtualProperty @{ 2 | ExportedCommands = { $_.ExportedCommands.Keys -join [Environment]::NewLine } 3 | ExportedVariables = { $_.ExportedVariables.Keys -join [Environment]::NewLine } 4 | } -Wrap -------------------------------------------------------------------------------- /Types/Emoji.Sequences/Add.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Adds an Emoji sequence 4 | .DESCRIPTION 5 | Adds an Emoji sequence to the cache 6 | #> 7 | param( 8 | # The Emoji Sequence 9 | [string] 10 | $EmojiSequence, 11 | 12 | # The value of the Emoji sequence. 13 | [PSObject] 14 | $Value 15 | ) 16 | 17 | 18 | if (-not $EmojiSequence) { return } 19 | $dynamicModule = 20 | if ($EmojiSequence -and $value -is [ScriptBlock]) { 21 | New-Module -Name $EmojiSequence -ScriptBlock ([ScriptBlock]::Create( 22 | "function $EmojiSequence { 23 | . `${$EmojiSequence} 24 | } 25 | 26 | `${$EmojiSequence} = `$args[0] 27 | 28 | Export-ModuleMember -Function * -Variable * -Alias *" 29 | )) -ArgumentList $value 30 | } 31 | else { 32 | New-Module -Name $EmojiSequence -ScriptBlock ([ScriptBlock]::Create( 33 | "`${$EmojiSequence} = `$args[0] 34 | Export-ModuleMember -Function * -Variable * -Alias *" 35 | )) -ArgumentList $value 36 | } 37 | 38 | if ($dynamicModule) { 39 | $addedModule = $dynamicModule | Import-Module -Global -Force -DisableNameChecking -PassThru 40 | $addedModule.pstypenames.insert(0,'Emoji.Sequence') 41 | $addedModule 42 | $this | Add-Member NoteProperty $EmojiSequence -Value $addedModule -Force 43 | } else { 44 | $this | Add-Member NoteProperty $EmojiSequence -Value $value -Force 45 | } -------------------------------------------------------------------------------- /Types/Emoji.Sequences/Alias.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | "Set" = "Add" 3 | } -------------------------------------------------------------------------------- /Types/Emoji.Sequences/Remove.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Removes an Emoji sequence 4 | .DESCRIPTION 5 | Removes an Emoji sequence from the cache 6 | #> 7 | param( 8 | # The emoji sequence 9 | [string] 10 | $EmojiSequence 11 | ) 12 | 13 | if (-not $this.$EmojiSequence) { return } 14 | $this.psobject.properties.Remove($EmojiSequence) -------------------------------------------------------------------------------- /Types/Emoji.Sequences/get_All.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Gets Emoji Sequences 4 | .DESCRIPTION 5 | Gets all loaded Emoji Sequences 6 | #> 7 | param() 8 | foreach ($property in $this.psobject.properties) { 9 | if (-not $property.IsInstance) { continue } 10 | if ($property -isnot [psnoteproperty]) { continue } 11 | $property.Value 12 | } -------------------------------------------------------------------------------- /Types/Emoji.Symbol/Alias.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | Emoji = 'String' 3 | } -------------------------------------------------------------------------------- /Types/Emoji.Symbol/Emoji.Symbol.format.ps1: -------------------------------------------------------------------------------- 1 | Write-FormatView -TypeName Emoji.Symbol -Property Emoji, Name, Hex -AlignProperty @{ 2 | Emoji = 'Left' 3 | Hex = 'Right' 4 | Name = 'Center' 5 | } -AutoSize -VirtualProperty @{ 6 | Emoji = { $_.Emoji.ToString().PadRight(3) } 7 | } -StyleProperty @{ 8 | Hex = 'Foreground.Cyan' 9 | Name = 'Foreground.Green' 10 | } 11 | 12 | Write-FormatView -TypeName Emoji.Symbol -Property Emoji, Name, PowerShell -AlignProperty @{ 13 | Emoji = 'Left' 14 | PowerShell = 'Right' 15 | Name = 'Center' 16 | } -AutoSize -VirtualProperty @{ 17 | Emoji = { $_.Emoji.ToString().PadRight(3) } 18 | } -StyleProperty @{ 19 | Hex = 'Foreground.Cyan' 20 | Name = 'Foreground.Green' 21 | } -Name PowerShell 22 | 23 | Write-FormatView -TypeName Emoji.Symbol -Property Emoji -AlignProperty @{ 24 | Emoji = 'Left' 25 | } -AutoSize -Name Emoji 26 | 27 | Write-FormatView -TypeName Emoji.Symbol -Property CSS -AlignProperty @{ 28 | CSS = 'Left' 29 | } -AutoSize -Name CSS 30 | 31 | Write-FormatView -TypeName Emoji.Symbol -Property Emoji, Name, HTML -AlignProperty @{ 32 | Html = 'Left' 33 | } -AutoSize -Name Html -StyleProperty @{ 34 | Name = 'Foreground.Green' 35 | } 36 | 37 | Write-FormatView -TypeName Emoji.Symbol -Action { 38 | Write-FormatViewExpression -ScriptBlock { 39 | $_.Emoji.PadRight(4) 40 | } 41 | 42 | Write-FormatViewExpression -Property Name -Style Foreground.Green 43 | } 44 | 45 | Write-FormatView -TypeName Emoji.Symbol -Action { 46 | Write-FormatViewExpression -Property Emoji 47 | } -Name Emoji 48 | 49 | Write-FormatView -TypeName Emoji.Symbol -Action { 50 | Write-FormatViewExpression -ScriptBlock { 51 | $_.Emoji.PadRight(4) 52 | } 53 | 54 | Write-FormatViewExpression -Property PowerShell -Style Foreground.Cyan 55 | 56 | Write-FormatViewExpression -Property Name -Style Foreground.Green 57 | } -Name PowerShell 58 | 59 | Write-FormatView -TypeName Emoji.Symbol -Action { 60 | Write-FormatViewExpression -Text "/*" 61 | Write-FormatViewExpression -ScriptBlock { 62 | $_.Emoji.PadRight(3) 63 | } 64 | 65 | Write-FormatViewExpression -Text "*/" 66 | Write-FormatViewExpression -Newline 67 | Write-FormatViewExpression -Property CSS 68 | } -Name CSS 69 | 70 | Write-FormatView -TypeName Emoji.Symbol -Action { 71 | Write-FormatViewExpression -Property HTML 72 | } -Name HTML -------------------------------------------------------------------------------- /Types/Emoji.Symbol/get_CSS.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Gets an Emoji as CSS 4 | .DESCRIPTION 5 | Gets an Emoji as a CSS rule 6 | #> 7 | param() 8 | 9 | $className = $this.Name.ToLower() -replace '\s','-' 10 | ".${className}::before { content: `"$($this.Emoji)`"; }" 11 | -------------------------------------------------------------------------------- /Types/Emoji.Symbol/get_HTML.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Gets an Emoji as HTML 4 | .DESCRIPTION 5 | Gets an Emoji as an HTML span 6 | .EXAMPLE 7 | (Get-Emoji -Name 'Grinning Face').HTML 8 | #> 9 | param() 10 | 11 | "$([Web.HttpUtility]::HtmlEncode($this.Emoji))" 12 | -------------------------------------------------------------------------------- /Types/Emoji.Symbol/get_Number.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Gets the Emoji Number 4 | .DESCRIPTION 5 | Gets the Emoji's number, as an integer. 6 | #> 7 | "0x$($this.Hex)" -as [int] 8 | -------------------------------------------------------------------------------- /Types/Emoji.Symbol/get_PowerShell.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Gets an Emoji's PowerShell string 4 | .DESCRIPTION 5 | Gets a PowerShell string that would reproduce the Emoji. 6 | 7 | These strings will only work on PowerShell Core. 8 | #> 9 | param() 10 | '"`u{' + $this.Hex + '}"' -------------------------------------------------------------------------------- /Types/Emoji/Alias.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | Demos = 'Demo' 3 | Sequence = 'Sequences' 4 | Find = 'Search' 5 | } -------------------------------------------------------------------------------- /Types/Emoji/Export.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Exports Emoji 4 | .DESCRIPTION 5 | Exports All Named Emoji. 6 | #> 7 | param( 8 | # The export path. 9 | [string] 10 | $EmojiPath, 11 | 12 | # If set, will overwrite any file at the exportPath 13 | [switch] 14 | $Force 15 | ) 16 | 17 | 18 | if (-not $this) { 19 | $this = Get-Module Emoji 20 | } 21 | if ($this.'.EmojiCache') { 22 | $exporterNoun = @($EmojiPath -split '[\\/]')[-1] -replace '.+\.' 23 | $exporters = $ExecutionContext.SessionState.InvokeCommand.GetCommands("Export-$exporterNoun", 'Function,Cmdlet,Alias', $true) 24 | if ($exporters -and $exporters.Count -eq 1) { 25 | $this.'.EmojiCache' | & $exporters $EmojiPath 26 | Get-Item $EmojiPath 27 | } 28 | } -------------------------------------------------------------------------------- /Types/Emoji/Get.ps.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Gets one or more Emoji 4 | .DESCRIPTION 5 | Gets Emoji by exact name or number. 6 | 7 | If neither name or number is provided, returns the Emoji module. 8 | #> 9 | [CmdletBinding(SupportsPaging)] 10 | param( 11 | # One or more specific Emoji names 12 | [ArgumentCompleter({ 13 | param ( $commandName,$parameterName,$wordToComplete,$commandAst, $fakeBoundParameters ) 14 | 15 | if (-not $script:EmojiNames) { 16 | $script:EmojiNames = @(Import-Emoji| Select-Object -ExpandProperty Name) 17 | } 18 | if ($wordToComplete) { 19 | $toComplete = $wordToComplete -replace "^'" -replace "'$" 20 | return @($script:emojiNames -like "$toComplete*" -replace '^', "'" -replace '$',"'") 21 | } else { 22 | return @($script:emojiNames -replace '^', "'" -replace '$',"'") 23 | } 24 | })] 25 | [Alias('String')] 26 | [string[]] 27 | $Name, 28 | 29 | # One or more specific emoji numbers 30 | [vbn()] 31 | [Alias('Range')] 32 | [int[]] 33 | $Number, 34 | 35 | # If set, will get Emoji blocks 36 | [vbn()] 37 | [Alias('AllBlock','AllBlocks','ListBlock','ListBlocks','Blocks')] 38 | [switch] 39 | $Block, 40 | 41 | # If set, will list Emoji sequences 42 | [vbn()] 43 | [Alias('AllSequence','AllSequences','ListSequences','ListSequence','Sequences')] 44 | [switch] 45 | $Sequence, 46 | 47 | # One or more block names 48 | [vbn()] 49 | [ValidValues(Values={ 50 | $pwd | 51 | Split-Path | 52 | Split-Path | 53 | Join-Path -ChildPath "Data" | 54 | Join-Path -ChildPath "AllEmojiBlocks.csv" | 55 | Import-Csv | 56 | Select-Object -ExpandProperty BlockName 57 | })] 58 | [string[]] 59 | $BlockName 60 | ) 61 | 62 | $allSelectedEmoji = Import-Emoji 63 | 64 | if (-not $this) { 65 | $this = Get-Module Emoji 66 | } 67 | 68 | if ($BlockName) { 69 | foreach ($nameOfBlock in $BlockName) { 70 | $blockRange = $this.Blocks[$nameOfBlock].Range 71 | if ($blockRange) { 72 | $number += $blockRange 73 | } 74 | } 75 | } 76 | 77 | if ($Name) { 78 | if ($Name -match '\p{P}') { 79 | if ($name -match '\*' -and $name -notmatch '[\[\]\.\?\(\)]') { 80 | $allSelectedEmoji = Search-Emoji -Like -Pattern $name 81 | } else { 82 | $allSelectedEmoji = Search-Emoji -Pattern $name 83 | } 84 | } else { 85 | $allSelectedEmoji = $allSelectedEmoji | Where-Object Name -In $Name 86 | } 87 | } 88 | if ($Number) { 89 | $allSelectedEmoji = $allSelectedEmoji | Where-Object Number -In $Number 90 | } 91 | 92 | $selectSplat = $Emoji.GetPagingParameters($PSCmdlet.PagingParameters) 93 | if ($name -or $number) { 94 | if ($selectSplat.Count -gt 1) { 95 | $allSelectedEmoji | Select-Object @selectSplat 96 | } else { 97 | $allSelectedEmoji 98 | } 99 | } 100 | elseif ($Block) { 101 | if ($selectSplat.Count) { 102 | $emoji.Blocks.Values | Select-Object @selectSplat 103 | } else { 104 | $emoji.Blocks.Values 105 | } 106 | } 107 | elseif ($Sequence) { 108 | if ($selectSplat.Count) { 109 | $emoji.Sequences.All | Select-Object @selectSplat 110 | } else { 111 | $emoji.Sequences.All 112 | } 113 | } 114 | else { 115 | $Emoji 116 | } 117 | -------------------------------------------------------------------------------- /Types/Emoji/Get.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Gets one or more Emoji 4 | .DESCRIPTION 5 | Gets Emoji by exact name or number. 6 | 7 | If neither name or number is provided, returns the Emoji module. 8 | #> 9 | [CmdletBinding(SupportsPaging)] 10 | param( 11 | # One or more specific Emoji names 12 | [ArgumentCompleter({ 13 | param ( $commandName,$parameterName,$wordToComplete,$commandAst, $fakeBoundParameters ) 14 | 15 | if (-not $script:EmojiNames) { 16 | $script:EmojiNames = @(Import-Emoji| Select-Object -ExpandProperty Name) 17 | } 18 | if ($wordToComplete) { 19 | $toComplete = $wordToComplete -replace "^'" -replace "'$" 20 | return @($script:emojiNames -like "$toComplete*" -replace '^', "'" -replace '$',"'") 21 | } else { 22 | return @($script:emojiNames -replace '^', "'" -replace '$',"'") 23 | } 24 | })] 25 | [Alias('String')] 26 | [string[]] 27 | $Name, 28 | 29 | # One or more specific emoji numbers 30 | [Parameter(ValueFromPipelineByPropertyName)] 31 | [Alias('Range')] 32 | [int[]] 33 | $Number, 34 | 35 | # If set, will get Emoji blocks 36 | [Parameter(ValueFromPipelineByPropertyName)] 37 | [Alias('AllBlock','AllBlocks','ListBlock','ListBlocks','Blocks')] 38 | [switch] 39 | $Block, 40 | 41 | # If set, will list Emoji sequences 42 | [Parameter(ValueFromPipelineByPropertyName)] 43 | [Alias('AllSequence','AllSequences','ListSequences','ListSequence','Sequences')] 44 | [switch] 45 | $Sequence, 46 | 47 | # One or more block names 48 | [Parameter(ValueFromPipelineByPropertyName)] 49 | [ValidateSet('Basic Latin','Latin-1 Supplement','Latin Extended-A','Latin Extended-B','IPA Extensions','Spacing Modifier Letters','Combining Diacritical Marks','Greek and Coptic','Cyrillic','Cyrillic Supplement','Armenian','Hebrew','Arabic','Syriac','Arabic Supplement','Thaana','NKo','Samaritan','Mandaic','Syriac Supplement','Arabic Extended-B','Arabic Extended-A','Devanagari','Bengali','Gurmukhi','Gujarati','Oriya','Tamil','Telugu','Kannada','Malayalam','Sinhala','Thai','Lao','Tibetan','Myanmar','Georgian','Hangul Jamo','Ethiopic','Ethiopic Supplement','Cherokee','Unified Canadian Aboriginal Syllabics','Ogham','Runic','Tagalog','Hanunoo','Buhid','Tagbanwa','Khmer','Mongolian','Unified Canadian Aboriginal Syllabics Extended','Limbu','Tai Le','New Tai Lue','Khmer Symbols','Buginese','Tai Tham','Combining Diacritical Marks Extended','Balinese','Sundanese','Batak','Lepcha','Ol Chiki','Cyrillic Extended-C','Georgian Extended','Sundanese Supplement','Vedic Extensions','Phonetic Extensions','Phonetic Extensions Supplement','Combining Diacritical Marks Supplement','Latin Extended Additional','Greek Extended','General Punctuation','Superscripts and Subscripts','Currency Symbols','Combining Diacritical Marks for Symbols','Letterlike Symbols','Number Forms','Arrows','Mathematical Operators','Miscellaneous Technical','Control Pictures','Optical Character Recognition','Enclosed Alphanumerics','Box Drawing','Block Elements','Geometric Shapes','Miscellaneous Symbols','Dingbats','Miscellaneous Mathematical Symbols-A','Supplemental Arrows-A','Braille Patterns','Supplemental Arrows-B','Miscellaneous Mathematical Symbols-B','Supplemental Mathematical Operators','Miscellaneous Symbols and Arrows','Glagolitic','Latin Extended-C','Coptic','Georgian Supplement','Tifinagh','Ethiopic Extended','Cyrillic Extended-A','Supplemental Punctuation','CJK Radicals Supplement','Kangxi Radicals','Ideographic Description Characters','CJK Symbols and Punctuation','Hiragana','Katakana','Bopomofo','Hangul Compatibility Jamo','Kanbun','Bopomofo Extended','CJK Strokes','Katakana Phonetic Extensions','Enclosed CJK Letters and Months','CJK Compatibility','CJK Unified Ideographs Extension A','Yijing Hexagram Symbols','CJK Unified Ideographs','Yi Syllables','Yi Radicals','Lisu','Vai','Cyrillic Extended-B','Bamum','Modifier Tone Letters','Latin Extended-D','Syloti Nagri','Common Indic Number Forms','Phags-pa','Saurashtra','Devanagari Extended','Kayah Li','Rejang','Hangul Jamo Extended-A','Javanese','Myanmar Extended-B','Cham','Myanmar Extended-A','Tai Viet','Meetei Mayek Extensions','Ethiopic Extended-A','Latin Extended-E','Cherokee Supplement','Meetei Mayek','Hangul Syllables','Hangul Jamo Extended-B','High Surrogates','High Private Use Surrogates','Low Surrogates','Private Use Area','CJK Compatibility Ideographs','Alphabetic Presentation Forms','Arabic Presentation Forms-A','Variation Selectors','Vertical Forms','Combining Half Marks','CJK Compatibility Forms','Small Form Variants','Arabic Presentation Forms-B','Halfwidth and Fullwidth Forms','Specials','Linear B Syllabary','Linear B Ideograms','Aegean Numbers','Ancient Greek Numbers','Ancient Symbols','Phaistos Disc','Lycian','Carian','Coptic Epact Numbers','Old Italic','Gothic','Old Permic','Ugaritic','Old Persian','Deseret','Shavian','Osmanya','Osage','Elbasan','Caucasian Albanian','Vithkuqi','Linear A','Latin Extended-F','Cypriot Syllabary','Imperial Aramaic','Palmyrene','Nabataean','Hatran','Phoenician','Lydian','Meroitic Hieroglyphs','Meroitic Cursive','Kharoshthi','Old South Arabian','Old North Arabian','Manichaean','Avestan','Inscriptional Parthian','Inscriptional Pahlavi','Psalter Pahlavi','Old Turkic','Old Hungarian','Hanifi Rohingya','Rumi Numeral Symbols','Yezidi','Arabic Extended-C','Old Sogdian','Sogdian','Old Uyghur','Chorasmian','Elymaic','Brahmi','Kaithi','Sora Sompeng','Chakma','Mahajani','Sharada','Sinhala Archaic Numbers','Khojki','Multani','Khudawadi','Grantha','Newa','Tirhuta','Siddham','Modi','Mongolian Supplement','Takri','Ahom','Dogra','Warang Citi','Dives Akuru','Nandinagari','Zanabazar Square','Soyombo','Unified Canadian Aboriginal Syllabics Extended-A','Pau Cin Hau','Devanagari Extended-A','Bhaiksuki','Marchen','Masaram Gondi','Gunjala Gondi','Makasar','Kawi','Lisu Supplement','Tamil Supplement','Cuneiform','Cuneiform Numbers and Punctuation','Early Dynastic Cuneiform','Cypro-Minoan','Egyptian Hieroglyphs','Egyptian Hieroglyph Format Controls','Anatolian Hieroglyphs','Bamum Supplement','Mro','Tangsa','Bassa Vah','Pahawh Hmong','Medefaidrin','Miao','Ideographic Symbols and Punctuation','Tangut','Tangut Components','Khitan Small Script','Tangut Supplement','Kana Extended-B','Kana Supplement','Kana Extended-A','Small Kana Extension','Nushu','Duployan','Shorthand Format Controls','Znamenny Musical Notation','Byzantine Musical Symbols','Musical Symbols','Ancient Greek Musical Notation','Kaktovik Numerals','Mayan Numerals','Tai Xuan Jing Symbols','Counting Rod Numerals','Mathematical Alphanumeric Symbols','Sutton SignWriting','Latin Extended-G','Glagolitic Supplement','Cyrillic Extended-D','Nyiakeng Puachue Hmong','Toto','Wancho','Nag Mundari','Ethiopic Extended-B','Mende Kikakui','Adlam','Indic Siyaq Numbers','Ottoman Siyaq Numbers','Arabic Mathematical Alphabetic Symbols','Mahjong Tiles','Domino Tiles','Playing Cards','Enclosed Alphanumeric Supplement','Enclosed Ideographic Supplement','Miscellaneous Symbols and Pictographs','Emoticons','Ornamental Dingbats','Transport and Map Symbols','Alchemical Symbols','Geometric Shapes Extended','Supplemental Arrows-C','Supplemental Symbols and Pictographs','Chess Symbols','Symbols and Pictographs Extended-A','Symbols for Legacy Computing','CJK Unified Ideographs Extension B','CJK Unified Ideographs Extension C','CJK Unified Ideographs Extension D','CJK Unified Ideographs Extension E','CJK Unified Ideographs Extension F','CJK Unified Ideographs Extension I','CJK Compatibility Ideographs Supplement','CJK Unified Ideographs Extension G','CJK Unified Ideographs Extension H','Tags','Variation Selectors Supplement','Supplementary Private Use Area-A','Supplementary Private Use Area-B')] 50 | [string[]] 51 | $BlockName 52 | ) 53 | 54 | $allSelectedEmoji = Import-Emoji 55 | 56 | if (-not $this) { 57 | $this = Get-Module Emoji 58 | } 59 | 60 | if ($BlockName) { 61 | foreach ($nameOfBlock in $BlockName) { 62 | $blockRange = $this.Blocks[$nameOfBlock].Range 63 | if ($blockRange) { 64 | $number += $blockRange 65 | } 66 | } 67 | } 68 | 69 | if ($Name) { 70 | if ($Name -match '\p{P}') { 71 | if ($name -match '\*' -and $name -notmatch '[\[\]\.\?\(\)]') { 72 | $allSelectedEmoji = Search-Emoji -Like -Pattern $name 73 | } else { 74 | $allSelectedEmoji = Search-Emoji -Pattern $name 75 | } 76 | } else { 77 | $allSelectedEmoji = $allSelectedEmoji | Where-Object Name -In $Name 78 | } 79 | } 80 | if ($Number) { 81 | $allSelectedEmoji = $allSelectedEmoji | Where-Object Number -In $Number 82 | } 83 | 84 | $selectSplat = $Emoji.GetPagingParameters($PSCmdlet.PagingParameters) 85 | if ($name -or $number) { 86 | if ($selectSplat.Count -gt 1) { 87 | $allSelectedEmoji | Select-Object @selectSplat 88 | } else { 89 | $allSelectedEmoji 90 | } 91 | } 92 | elseif ($Block) { 93 | if ($selectSplat.Count) { 94 | $emoji.Blocks.Values | Select-Object @selectSplat 95 | } else { 96 | $emoji.Blocks.Values 97 | } 98 | } 99 | elseif ($Sequence) { 100 | if ($selectSplat.Count) { 101 | $emoji.Sequences.All | Select-Object @selectSplat 102 | } else { 103 | $emoji.Sequences.All 104 | } 105 | } 106 | else { 107 | $Emoji 108 | } 109 | 110 | -------------------------------------------------------------------------------- /Types/Emoji/GetPagingParameters.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Gets the paging parameters 4 | .DESCRIPTION 5 | Gets the paging parameters as a Dictionary for Select-Object. 6 | .LINK 7 | Select-Object 8 | #> 9 | param( 10 | $Parameter 11 | ) 12 | 13 | $SelectParameters = [Ordered]@{} 14 | 15 | if ($Parameter.First -as [int]) { 16 | $SelectParameters.First = $Parameter.First -as [int] 17 | } 18 | 19 | if ($Parameter.Skip -as [int]) { 20 | $SelectParameters.Skip = $Parameter.Skip -as [int] 21 | } 22 | 23 | return $SelectParameters 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Types/Emoji/Import.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Imports Emoji 4 | .DESCRIPTION 5 | Imports all named Emoji from an -EmojiPath. 6 | 7 | If the -EmojiPath is not provided, it will import it's local copy 8 | #> 9 | param( 10 | # The path to the emoji data 11 | [string] 12 | $EmojiPath, 13 | 14 | # If set, will overwrite existing data. 15 | [switch] 16 | $Force 17 | ) 18 | 19 | 20 | if (-not $this) { 21 | $this = Get-Module Emoji 22 | } 23 | if ((-not $this.'.EmojiCache') -or $Force) { 24 | if (-not $EmojiPath) { 25 | $EmojiPath = $this | 26 | Split-Path | 27 | Join-Path -ChildPath Data | 28 | Join-Path -ChildPath "AllNamedEmoji.csv" 29 | } 30 | if (Test-Path $EmojiPath) { 31 | $impoterNoun = @($EmojiPath -split '[\\/]')[-1] -replace '.+\.' 32 | $importers = $ExecutionContext.SessionState.InvokeCommand.GetCommands("Import-$impoterNoun", 'Function,Cmdlet,Alias', $true) 33 | if ($importers -and $importers.Count -eq 1) { 34 | $importedEmojiList = & $importers $EmojiPath 35 | if ($importedEmojiList.Length -gt 1 -and $importedEmojiList[0].Hex -match '[0-9a-f]{4,}') { 36 | Add-Member -InputObject $this -MemberType NoteProperty -Force -Name ".EmojiCache" -Value @(foreach ($importedEmoji in $importedEmojiList) { 37 | $importedEmoji.pstypenames.insert(0,'Emoji.Symbol') 38 | $importedEmoji 39 | }) 40 | } 41 | } 42 | } 43 | } 44 | $this.'.EmojiCache' -------------------------------------------------------------------------------- /Types/Emoji/Search.ps.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Find Emoji 4 | .DESCRIPTION 5 | Searches for Emoji 6 | #> 7 | [CmdletBinding(SupportsPaging)] 8 | param( 9 | # One or more search patterns 10 | [vbn()] 11 | [string[]] 12 | $Pattern, 13 | 14 | # If set, will search using the -like operator. By default, will search using -match 15 | [vbn()] 16 | [switch] 17 | $Like, 18 | 19 | # If set, will look for an exact word. This is not compatible with -Like. 20 | [vbn()] 21 | [switch] 22 | $Word 23 | ) 24 | 25 | if (-not $this) { 26 | $this = Get-Module Emoji 27 | } 28 | 29 | if ($word) { 30 | $like = $false 31 | $Pattern = $Pattern -replace '^', '(?<=(?>^|\s))' -replace '$', '(?=(?>$|\s))' 32 | } 33 | 34 | $SelectParameters = $Emoji.GetPagingParameters($PSCmdlet.PagingParameters) 35 | 36 | @(foreach ($condition in $Pattern) { 37 | foreach ($namedEmoji in $this.Import()) { 38 | if ($like) { 39 | if ($namedEmoji.Name -like $condition) { 40 | $namedEmoji 41 | } 42 | } elseif ($namedEmoji.Name -match $condition) { 43 | $namedEmoji 44 | } 45 | } 46 | }) | Select-Object @SelectParameters 47 | -------------------------------------------------------------------------------- /Types/Emoji/Search.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Find Emoji 4 | .DESCRIPTION 5 | Searches for Emoji 6 | #> 7 | [CmdletBinding(SupportsPaging)] 8 | param( 9 | # One or more search patterns 10 | [Parameter(ValueFromPipelineByPropertyName)] 11 | [string[]] 12 | $Pattern, 13 | 14 | # If set, will search using the -like operator. By default, will search using -match 15 | [Parameter(ValueFromPipelineByPropertyName)] 16 | [switch] 17 | $Like, 18 | 19 | # If set, will look for an exact word. This is not compatible with -Like. 20 | [Parameter(ValueFromPipelineByPropertyName)] 21 | [switch] 22 | $Word 23 | ) 24 | 25 | if (-not $this) { 26 | $this = Get-Module Emoji 27 | } 28 | 29 | if ($word) { 30 | $like = $false 31 | $Pattern = $Pattern -replace '^', '(?<=(?>^|\s))' -replace '$', '(?=(?>$|\s))' 32 | } 33 | 34 | $SelectParameters = $Emoji.GetPagingParameters($PSCmdlet.PagingParameters) 35 | 36 | @(foreach ($condition in $Pattern) { 37 | foreach ($namedEmoji in $this.Import()) { 38 | if ($like) { 39 | if ($namedEmoji.Name -like $condition) { 40 | $namedEmoji 41 | } 42 | } elseif ($namedEmoji.Name -match $condition) { 43 | $namedEmoji 44 | } 45 | } 46 | }) | Select-Object @SelectParameters 47 | 48 | -------------------------------------------------------------------------------- /Types/Emoji/Set.ps.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Sets an Emoji 4 | .DESCRIPTION 5 | Sets an Emoji Sequence. 6 | 7 | This creates a command or variable (using some emoji), and sets it to a -Value or -ScriptBlock. 8 | 9 | If a -Value or -ScriptBlock is not provided, the -Value will default to a [ScriptBlock] that outputs the sequence. 10 | #> 11 | param( 12 | # The Emoji Sequence. 13 | [vbn()] 14 | [string[]] 15 | $EmojiSequence, 16 | 17 | # The value to set. 18 | [vbn()] 19 | [PSObject] 20 | $Value, 21 | 22 | # A ScriptBlock value. If provided, this will override -Value. 23 | [vbn()] 24 | [scriptblock] 25 | $ScriptBlock 26 | ) 27 | 28 | $joinedSequence = $EmojiSequence -join '' 29 | 30 | if ($ScriptBlock) { 31 | $Value = $ScriptBlock 32 | } 33 | 34 | if (-not $value) { 35 | $value = [ScriptBlock]::Create("'$($joinedSequence -replace "'","''")'") 36 | } 37 | 38 | $emoji.Sequence.Add($joinedSequence, $value) 39 | 40 | 41 | -------------------------------------------------------------------------------- /Types/Emoji/Set.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Sets an Emoji 4 | .DESCRIPTION 5 | Sets an Emoji Sequence. 6 | 7 | This creates a command or variable (using some emoji), and sets it to a -Value or -ScriptBlock. 8 | 9 | If a -Value or -ScriptBlock is not provided, the -Value will default to a [ScriptBlock] that outputs the sequence. 10 | #> 11 | param( 12 | # The Emoji Sequence. 13 | [Parameter(ValueFromPipelineByPropertyName)] 14 | [string[]] 15 | $EmojiSequence, 16 | 17 | # The value to set. 18 | [Parameter(ValueFromPipelineByPropertyName)] 19 | [PSObject] 20 | $Value, 21 | 22 | # A ScriptBlock value. If provided, this will override -Value. 23 | [Parameter(ValueFromPipelineByPropertyName)] 24 | [scriptblock] 25 | $ScriptBlock 26 | ) 27 | 28 | $joinedSequence = $EmojiSequence -join '' 29 | 30 | if ($ScriptBlock) { 31 | $Value = $ScriptBlock 32 | } 33 | 34 | if (-not $value) { 35 | $value = [ScriptBlock]::Create("'$($joinedSequence -replace "'","''")'") 36 | } 37 | 38 | $emoji.Sequence.Add($joinedSequence, $value) 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Types/Emoji/get_Blocks.ps1: -------------------------------------------------------------------------------- 1 | if (-not $this.'.Blocks') { 2 | $theseBlocks = [Ordered]@{} 3 | $allEmojiBlocks = Get-Module Emoji | Split-Path | Join-Path -ChildPath "Data" | Join-Path -ChildPath "AllEmojiBlocks.csv" | Import-Csv 4 | foreach ($emojiBlock in $allEmojiBlocks) { 5 | $emojiBlock.pstypenames.clear() 6 | $emojiBlock.pstypenames.add('Emoji.Block') 7 | $theseBlocks[$emojiBlock.BlockName] = $emojiBlock 8 | } 9 | Add-Member -InputObject $this -MemberType NoteProperty -Force -Name ".Blocks" -Value $theseBlocks 10 | } 11 | 12 | $this.'.Blocks' -------------------------------------------------------------------------------- /Types/Emoji/get_Demo.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Gets module demos 4 | .DESCRIPTION 5 | Gets demo files related to a module. 6 | .EXAMPLE 7 | $Posh.Demos 8 | .LINK 9 | https://github.com/StartAutomating/ShowDemo 10 | #> 11 | $this | 12 | Split-Path | 13 | Get-ChildItem -Recurse -Filter *.demo.ps1 -------------------------------------------------------------------------------- /Types/Emoji/get_Sequences.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Emoji Sequences 4 | .DESCRIPTION 5 | Gets the Emoji Sequences Collection 6 | #> 7 | if (-not $this.'.Sequences') { 8 | $this | Add-Member NoteProperty '.Sequences' ( 9 | [PSCustomObject]@{PSTypeName='Emoji.Sequences'} 10 | ) -Force 11 | } 12 | 13 | $this.'.Sequences' -------------------------------------------------------------------------------- /Types/Emoji/set_Sequences.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Sets Emoji Sequences 4 | .DESCRIPTION 5 | Sets the Emoji Sequences Collection. 6 | .NOTES 7 | Any string arguments will be considered the sequence. 8 | The first non-string argument will be considered the value. 9 | #> 10 | param() 11 | 12 | $unrolledArgs = $args | . { process { $_ } } 13 | 14 | if (-not $this.'.Sequences') { 15 | $this | Add-Member NoteProperty '.Sequences' ( 16 | [PSCustomObject]@{PSTypeName='Emoji.Sequences'} 17 | ) -Force 18 | } 19 | 20 | $Value = $null 21 | $emojiSequence = foreach ($arg in $unrolledArgs) { 22 | if ($arg -is [string]) { 23 | $arg 24 | } elseif (-not $value) { 25 | $value = $arg 26 | } 27 | } 28 | 29 | if ($emojiSequence -and $Value) { 30 | $this.'.Sequences'.Add($emojiSequence -join '', $value) 31 | } 32 | 33 | 34 | --------------------------------------------------------------------------------