Skip to content

StartAutomating/MarkX

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Hello World

Greetings from MarkX!

MarkX PowerShell Gallery

What Is MarkX?

MarkX is a useful little tool built around a useful little trick.

Markdown is text that turns into nicely balanced and escaped HTML.

We can put that HTML into any <tag> and treat it as <xml>.

This lets us query and manipulate markdown, giving us the best of both worlds.

It's easy to write text, and an easy to read document tree.

Installing and Importing

You can install MarkX from the PowerShell Gallery, using Install-Module:

Install-Module MarkX

Once install, you can import it with Import-Module

Import-Module MarkX

Getting Started

Let's start simple, by making some markdown:

"# Hello World" | MarkX

When we run this, we should see two properties: Markdown and XML.

Whenever we change the Markdown, everything else is updated.

Getting Links

Let's see how this can be useful, by getting some links.

$markXLinks =
"* [My Website](https://MrPowerShell.com/)",
"* [GitHub](https://github.com/StartAutomating)",
"* [BlueSky](https://bsky.app/profile/mrpowershell.com)" | 
    markx

@($markXLinks.Links.Href |        
    ForEach-Object { 
        "* $($_)"
    }) -join [Environment]::NewLine

When we run this, we get:

Getting Images

Let's see how this can be fun, by getting some images.

$markXImages =
"* ![Mind Blown Stranger Things](https://media1.tenor.com/m/rReKAT-J3nsAAAAd/mind-blown-boom.gif)",
    "* ![Mind Blown Big Mouth](https://media1.tenor.com/m/rD98-O3i1xYAAAAC/what-mind-blown.gif)"
     | markx
@(
$markXImages

$markXImages.Images |        
    ForEach-Object { 
        "* [$($_.alt)]($($_.src))"
    }
) -join [Environment]::NewLine

When we run this, we get:

  • Mind Blown Stranger Things
  • Mind Blown Big Mouth

Making Tables

Let's make some tables

$timesTable = @(
    "#### TimesTable"
    foreach ($rowN in 1..9) {
        $row = [Ordered]@{}
        foreach ($colN in 1..9) {
            $row["$colN"] = $colN * $rowN
        }
        $row
    }
) | MarkX

$timesTable

When we run this, we get:

TimesTable

123456789
123456789
24681012141618
369121518212427
4812162024283236
51015202530354045
61218243036424854
71421283542495663
81624324048566472
91827364554637281

Tables Become Data

Ok, this gets really cool.

Tables become data!

Because we can easily extract out the <table> elements inside of markdown, we can turn it into data.

And because the .NET framework includes a nifty in-memory database, we can turn this into something we can query.

The Nearest Heading Is The Table Name

A blockquote is the description

a b c
1 2 3
$markxTables = @'
#### abc
|a|b|c|
|-|-|-|
|1|2|3|
|4|5|6|
|7|8|9|

#### def

|d|e|f|
|-|-|-|
|1|2|3|
|2|4|6|
|3|6|9|
|4|8|12|

'@ | MarkX 
$markxTables
$markxTables.DB.Tables["abc"].Compute('sum(a)','') # | Should -Be 12    
$markxTables.DB.Tables["def"].Compute('sum(d)','') # | Should -Be 10

When we run this example, we get:

abc

abc
123
456
789

def

def
123
246
369
4812
12 10

Markdown Lexicons

Since we can extra tables and data Markdown, we can also get any data of a particular known shape.

The first special shape MarkX supports is an at protocol lexicon

MarkX current supports lexicon type definitions. It will support query and procedure definitions in the future.

A type definition consists of a namespace identifier, a description, and a series of properties.

com.example.happy.birthday

An example lexicon to record birthday messages

Property Type Description
$type [string] The type of the object. Must be com.example.happy.birthday
message [string] A birthday message
forUri [uri] A link
birthday [datetime] The birthday
createdAt [datetime] The time the record was created

To extract out a lexicon from the text above, we can:

$lexiconMarkdown.Lexicon | ConvertTo-Json -Depth 5

Which gives us:

{
  "lexicon": 1,
  "id": "com.example.happy.birthday",
  "defs": {
    "main": {
      "type": "record",
      "description": "com.example.happy.birthday",
      "required": [
        "message"
      ],
      "properties": {
        "message": {
          "type": "string",
          "description": "A birthday message"
        },
        "forUri": {
          "type": "uri",
          "description": "A link"
        },
        "birthday": {
          "type": "datetime",
          "description": "The birthday"
        },
        "createdAt": {
          "type": "datetime",
          "description": "The time the record was created"
        }
      }
    }
  }
}

As you can see, we can take rich data within Markdown and process it into lexicons (or anything else we might want)

Get-MarkX

Gets MarkX

Gets MarkX - Markdown as XML

This allows us to query, extract, and customize markdown.

'Hello World' In Markdown / MarkX

'# Hello World' | MarkX

MarkX is aliased to Markdown 'Hello World' as Markdown as XML

'# Hello World' | Markdown | Select -Expand XML

We can generate tables by piping in objects

@{n1=1;n2=2}, @{n1=2;n3=3} | MarkX

Make a TimesTable in MarkX

@(
    "#### TimesTable"
    foreach ($rowN in 1..9) {
        $row = [Ordered]@{}
        foreach ($colN in 1..9) {
            $row["$colN"] = $colN * $rowN
        }
        $row
    }
) | Get-MarkX

We can pipe a command into MarkX This will get the command help as Markdown

Get-Command Get-MarkX | MarkX

We can pipe help into MarkX

Get-Help Get-MarkX | MarkX

We can get code from markdown

Get-Help Get-MarkX | 
    MarkX | 
    Select-Object -ExpandProperty Code

In Summary

MarkX is a simple and powerful tool. It allows us to turn many objects into Markdown, and turn Markdown into many objects.

Please pay around and see what you can do.

About

MarkX - Markdown, XML, and PowerShell

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published