Files
blog-site/src/content/articles/playground/content.md

28 KiB
Raw Blame History

Pagex Playground Article

this is sample text (playground)

Test Articles

Markdown Test Document

This document is designed to test all aspects of the pagex markdown renderer.

To modify the test document, make changes in /src/content/articles/playground/content.md.

Custom Elements

Voidcannon provides a set of custom html elements that can be used within the standard markdown html syntax.

<voidcannon-carousel>

<voidcannon-carousel> turns any content into a carousel. Carousels are not server-rendered.

Persona 5 Menu

Persona 5 Protagonist

Persona 5 Enemy

<voidcannon-carousel>
<voidcannon-slide>

![Persona 5 Menu](media/menu.jpg "p5 menu")

</voidcannon-slide>
<voidcannon-slide>

![Persona 5 Protagonist](media/joker.jpg "p5 joker")

</voidcannon-slide>
<voidcannon-slide>

![Persona 5 Enemy](media/enemy.jpg "p5 enemy")

</voidcannon-slide>
</voidcannon-carousel>

<voidcannon-slide>, <voidcannon-harness>

The <voidcannon-slide> and <voidcannon-harness> custom elements allow for slotting content.

<voidcannon-slide>

Intended for use within carousels in order to create holding containers for slides. Automatically scales images to use up all available visual carousel space. Will probably be replaced in favor of harness some day.

<voidcannon-slide>

![Persona 5 Enemy](media/enemy.jpg "p5 enemy")

</voidcannon-slide>

<voidcannon-harness>

Makes content take up more space horizontally in the article layout. Intended for big elements like images or important sections that should get more highlighting or emphasis. (Carousels use this style by default without needing a harness element)

<voidcannon-harness>

![Cat using computer](assets/Cat_using_computer.jpg "look at this cat")

</voidcannon-harness>

<voidcannon-cta>

Call-to-action that emphasizes an action or acts as a callout/hint. Can accept a button.

brightness_alert Big Warning! Go to Warner
<voidcannon-cta layout="button">
    <md-icon slot="icon">brightness_alert</md-icon>
    Big Warning!
    <md-text-button slot="button">Go to Warner</md-text-button>
</voidcannon-cta>

Other Custom Elements

The voidcannon frontend imports various other internal and external custom elements that can be server-rendered.

@material/web

Buttons warning breaking_news

Voidcannon ships a stripped down version of Material Symbols in production builds.

If an icon doesn't display properly in <md-icon> or <wf-icon> components, make sure the icon is included in voidcannon/scripts/generate-icon-font.js.

gm3 (1p)


To get an exhaustive list, check voidcannon/src/client/components.js. Client-only components are under voidcannon/src/client/components_client.js.

Headings

  • H1 Heading

  • H2 Heading

  • H3 Heading

  • H4 Heading

  • H5 Heading
  • H6 Heading

The first h1 in an article is considered to be the "article title" and gets different styling (size increase, smaller gap above).

Emphasis

  • Bold text
  • Italic text
  • Bold and italic text
  • Strikethrough text
  • Underlined text (if supported)

Lists

Unordered Lists

  • Item 1
  • Item 2
    • Subitem 1
    • Subitem 2
  • Item 3

Ordered Lists

  1. First item
  2. Second item
    1. Subitem 1
    2. Subitem 2
  3. Third item

Emojis

🦭

big seal

My favourite animals are the seal 🦭 and the otter 🦦. My favourite emoji is the skateboard 🛹 joycat 😹

🌈 ✨🤩💫☪🐟♏🦂🦀🦁🐍🐐🌃🍋‍🟩

  • 🏃🏾‍♀️‍➡️
  • 👨🏻‍❤️‍👨🏻
  • 🧑🏼‍❤️‍🧑🏾
  • 🫩
  • 🇩🇪

Supports discord-style shorthands

  • 🎉 (:tada:)
  • 🫶:skin-tone-1: (:heart_hands::skin-tone-1:)
  • :couple_with_heart_person_person_medium_light_skin_tone_medium_dark_skin_tone: (:couple_with_heart_person_person_medium_light_skin_tone_medium_dark_skin_tone:)
  • :person_in_motorized_wheelchair_facing_right_medium_light_skin_tone: (:person_in_motorized_wheelchair_facing_right_medium_light_skin_tone:)
  • :regional_indicator_b::regional_indicator_i::regional_indicator_g::regional_indicator_n::regional_indicator_u::regional_indicator_t::regional_indicator_t::regional_indicator_y:
  • :flag_de: 🏳️‍🌈
  • :face_with_bags_under_eyes: :splatter: :root_vegetable:

Supports discord custom emoji

  • <:meowblob:1245470561296187504>
  • <:catsmile:1271230456188375111>Love<:catsmile:1271230456188375111>❤️
  • webp-only animated emoji <a:cubus:1402437389095534623>

Custom emoji (Persona 3 Reload)

  • :p3smile: :p3worried: :p3surprised:
  • :p3arrowup: :p3heart: :p3brokenheart: :p3burger: :p3camera: :p3cat: :p3dog: :p3cloud: :p3cup: :p3moon: :p3fullmoon: :p3pill: :p3rainbow: :p3snowman: :p3star: :p3sun: :p3thumbsup: :p3umbrella: :p3yen:

Task Lists

  • Unchecked task
  • Checked task
  • Another unchecked task

Images

The custom <voidcannon-harness> element can be used to render full-width sections. Images will automatically stretch to fill the available width.

Cat using computer

Alt text Alt text

Code

Inline Code

  • print("Hello, world!")

Code Blocks

def greet(name):
    print(f"Hello, {name}!")

greet("World")

This codeblock is expandable to save on space.

import {
    VoidcannonContentType,
    VoidcannonSectionType
} from "voidcannon";

import {PagexResourceTransformer} from "pagex";
import CollectionContentTransformer from "voidcannon/src/transformers/CollectionContent.transformer.js";

export default {
    type: VoidcannonContentType.EDITORIAL,
    id: "index",
    name: "Voidcannon Home",
    description: "Voidcannon Home",
    color: null,
    sections: [
        {
            type: VoidcannonSectionType.CAROUSEL,
            content: {
                _transform: CollectionContentTransformer.id,
                collection_id: "featured"
            },
            label: "Featured Articles",
            target: "collections/featured"
        },
        {
            type: VoidcannonSectionType.EDITORIAL,
            content: {
                _transform: PagexResourceTransformer.MARKDOWN,
                path: "./content.md"
            }
        },
        {
            type: VoidcannonSectionType.CONTENT_GRID,
            content: {
                _transform: CollectionContentTransformer.id,
                collection_id: "recent"
            },
            label: "Recent Articles"
        }
    ]
}
function sayHello(name) {
    console.log("Hello, " + name + "!");
}

sayHello("World");

function foo(name) {
    console.log("Hello, " + name + "!");
}

foo("bar");
No language specified
This is a plain code block.

Advanced Formatting

// Additions and Removals

Helo// [!code --]
Helo// [!code --]
Helo// [!code --]
Hello// [!code ++]
Hello// [!code ++]
Hello// [!code ++]

// Errors and Warnings
guh()
pluh()// [!code warning]
pluhey()// [!code error]

// Highlighting
// [!code highlight:5]
dong.expand();
// This is a large highlighted section
const a = "b";
console.log("a" + a);
function b(c) {return d;}
diff --git a/pages/resources/integration.mdx b/pages/resources/integration.mdx
index 21d48f59..49445b53 100644
--- a/pages/resources/integration.mdx
+++ b/pages/resources/integration.mdx
@@ -110,19 +110,22 @@ Integrations represent a connection between a service and a guild. This may incl
 
 ###### GIF Media Format
 
-| Value     | Description                          |
-| --------- | ------------------------------------ |
-| mp4       | MP4 video                            |
-| tinymp4   | MP4 video in a smaller size          |
-| nanomp4   | MP4 video in a very small size       |
-| loopedmp4 | MP4 video that loops (same as `mp4`) |
-| webm      | WebM video                           |
-| tinywebm  | WebM video in a smaller size         |
-| nanowebm  | WebM video in a very small size      |
-| gif       | GIF image                            |
-| mediumgif | GIF image in a medium size           |
-| tinygif   | GIF image in a smaller size          |
-| nanogif   | GIF image in a very small size       |
+| Value     | Description                              | Description                              | Description                              |
+| --------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
+| mp4       | MP4 video                                | MP4 video                                | MP4 video                                |
+| tinymp4   | MP4 video in a smaller size              | MP4 video in a smaller size              | MP4 video in a smaller size              |
+| nanomp4   | MP4 video in a very small size           | MP4 video in a very small size           | MP4 video in a very small size           |
+| loopedmp4 | MP4 video that loops (same as `mp4`)     | MP4 video that loops (same as `mp4`)     | MP4 video that loops (same as `mp4`)     |
+| webm      | WebM video                               | WebM video                               | WebM video                               |
+| tinywebm  | WebM video in a smaller size             | WebM video in a smaller size             | WebM video in a smaller size             |
+| nanowebm  | WebM video in a very small size          | WebM video in a very small size          | WebM video in a very small size          |
+| gif       | GIF image                                | GIF image                                | GIF image                                |
+| mediumgif | GIF image in a medium size               | GIF image in a medium size               | GIF image in a medium size               |
+| tinygif   | GIF image in a smaller size              | GIF image in a smaller size              | GIF image in a smaller size              |
+| nanogif   | GIF image in a very small size           | GIF image in a very small size           | GIF image in a very small size           |
+| webp      | Animated WebP image                      | Animated WebP image                      | Animated WebP image                      |
+| tinywebp  | Animated WebP image in a smaller size    | Animated WebP image in a smaller size    | Animated WebP image in a smaller size    |
+| nanowebp  | Animated WebP image in a very small size | Animated WebP image in a very small size | Animated WebP image in a very small size |
 
 ###### Example GIF
 
@@ -337,15 +340,17 @@ Returns a list of [GIF](#gif-structure) objects based on the provided query.
 
 ###### Query String Parameters
 
-| Field         | Type    | Description                                           |
-| ------------- | ------- | ----------------------------------------------------- |
-| q             | string  | The search query to use                               |
-| limit? ^1^    | integer | The maximum number of GIFs to return (20-500)         |
-| media_format? | string  | The media format to use (default `mediumgif`)         |
-| locale?       | string  | The locale to use in search results (default `en-US`) |
+| Field            | Type    | Description                                                 |
+| ---------------- | ------- | ----------------------------------------------------------- |
+| q                | string  | The search query to use                                     |
+| limit? ^1^       | integer | The maximum number of GIFs to return (20-500) (default 100) |
+| media_format ^2^ | string  | The [media format](#gif-media-format) to use                |
+| locale?          | string  | The locale to use in search results (default `en-US`)       |
 
 ^1^ The limit is only a suggestion; the API may return fewer GIFs.
 
+^2^ Invalid values default to `gif`.
+
 <RouteHeader method="GET" url="/gifs/trending" unauthenticated>
   Get Trending GIF Categories
 </RouteHeader>
@@ -354,10 +359,10 @@ Returns trending GIF categories and their associated preview GIFs.
 
 ###### Query String Parameters
 
-| Field         | Type   | Description                                           |
-| ------------- | ------ | ----------------------------------------------------- |
-| media_format? | string | The media format to use (default `mediumgif`)         |
-| locale?       | string | The locale to use in search results (default `en-US`) |
+| Field        | Type   | Description                                           |
+| ------------ | ------ | ----------------------------------------------------- |
+| media_format | string | The [media format](#gif-media-format) to use          |
+| locale?      | string | The locale to use in search results (default `en-US`) |
 
 ###### Response Body
 
@@ -406,11 +411,11 @@ Returns a list of [GIF](#gif-structure) objects that are currently trending.
 
 ###### Query String Parameters
 
-| Field         | Type    | Description                                           |
-| ------------- | ------- | ----------------------------------------------------- |
-| limit? ^1^    | integer | The maximum number of GIFs to return (20-500)         |
-| media_format? | string  | The media format to use (default `mediumgif`)         |
-| locale?       | string  | The locale to use in search results (default `en-US`) |
+| Field        | Type    | Description                                           |
+| ------------ | ------- | ----------------------------------------------------- |
+| limit? ^1^   | integer | The maximum number of GIFs to return (20-500)         |
+| media_format | string  | The [media format](#gif-media-format) to use          |
+| locale?      | string  | The locale to use in search results (default `en-US`) |
 
 ^1^ The limit is only a suggestion; the API may return fewer GIFs.
 

syntax = "proto3";

package bignutty.pagex;

    🍋‍🟩

// Represents preprocessed metadata for pagex media items.
message PagexProcessedMedia {
  // The version of this metadata payload.
  int32 version = 1;
  // Preprocessed LQIP value for this media item.
  int32 lqip = 2;
  // Attributions
  repeated PagexMediaAttribution attributions = 3;
}

// An attribution (copyright, source) for a media item.
message PagexMediaAttribution {
  // Text label (i.e Copyright 2025 bignutty).
  string label = 1;
  // URL linking to the original source or author.
  optional string url = 2;
}

Horizontal Rule


Blockquotes

This is a blockquote. It can span multiple lines.

And even be nested.

Tables

Header 1 Header 2 Header 3 Header 3 Header 3 Header 3 Header 3 Header 3 Header 3 Header 3 Header 3 Header 3 Header 3 Header 3 Header 3
Cell 1 Cell 2 Cell 3 Cell 3 Cell 3 Cell 3 Cell 3 Cell 3 Cell 3 Cell 3 Cell 3 Cell 3 Cell 3 Cell 3 Cell 3
Cell 4 Cell 5 Cell 6 Cell 6 Cell 6 Cell 6 Cell 6 Cell 6 Cell 6 Cell 6 Cell 6 Cell 6 Cell 6 Cell 6 Cell 6
Field Type Description
id snowflake The ID of the message
channel_id snowflake The ID of the channel the message was sent in
lobby_id? snowflake The ID of the lobby the message was sent in
author ^1^ partial user object The author of the message
content ^2^ string Contents of the message
timestamp ISO8601 timestamp When this message was sent
edited_timestamp ?ISO8601 timestamp When this message was last edited
tts boolean Whether this message will be read out by TTS
mention_everyone boolean Whether this message mentions everyone
mentions array[partial user object] Users specifically mentioned in the message
mention_roles array[snowflake] Roles specifically mentioned in this message
mention_channels? ^3^ array[partial channel object] Channels specifically mentioned in this message
attachments ^2^ array[attachment object] The attached files
embeds ^2^ array[embed object] Content embedded in the message
reactions? array[reaction object] Reactions on the message
nonce? integer | string The message's nonce, used for message deduplication
pinned boolean Whether this message is pinned
webhook_id? snowflake The ID of the webhook that send the message
type integer The type of message
activity? message activity object The rich presence activity the author is inviting users to
application? integration application object The application of the message's rich presence activity
application_id? snowflake The ID of the application; only sent for interaction responses and messages created through OAuth2
flags integer The message's flags
message_reference? ^4^ message reference object The source of a crosspost, snapshot, channel follow add, pin, or reply message
referenced_message? ^5^ ^4^ ?message object The message associated with the message_reference
message_snapshots? ^4^ array[message snapshot object] The partial message snapshot associated with the message_reference
call? message call object The private channel call that prompted this message
interaction? (deprecated) message interaction object The interaction the message is responding to
interaction_metadata? message interaction metadata object The interaction the message originated from
resolved? resolved data object Data for users, members, channels, and roles referenced in this message
thread? channel object The thread that was started from this message, with the member key representing thread member data
role_subscription_data? message role subscription object The role subscription purchase or renewal that prompted this message
purchase_notification? message purchase notification object The guild purchase that prompted this message
gift_info? message gift info object Information on the gift that prompted this message
components ^2^ array[message component object] The message's components (e.g. buttons, select menus)
sticker_items? array[sticker item object] The message's sticker items
stickers? array[sticker object] Extra rich information for the message's sticker items; only available in some contexts
poll? ^2^ poll object A poll!
changelog_id? snowflake The ID of the changelog that prompted this message
soundboard_sounds? array[soundboard sound object] The message's soundboard sounds
potions? array[potion object] Potions applied to the message
shared_client_theme? shared client theme object The shared client theme

HTML

This is some HTML text.

Test convert_to_text this is a cta rendered from a markdown document pluh

Line Breaks

This is a line.
This is another line.

Escaping

* * * * *

Special Characters

` ~ ! @ # $ % ^ & * ( ) - _ = + [ ] { } | ; : ' " , . / < > ?