Pueblo Client
Hyper Text Markup Language (http://www.w3.org)
Three kinds of client receive HTML tags: Pueblo clients (see pueblo), MXP clients, and the web portal. To utilize HTML, use one of the MUSH HTML Functions (see HTML FUNCTIONS for a list).
HTML tags are stripped when sent to any other client.
Pueblo and MXP are different dialects, not one extending the other. Most formatting tags are spelled alike, but a command link is not: Pueblo writes <a xch_cmd="..."> and MXP writes <send href="...">, and each client prints the other’s as text. Use CMDLINK() for a command link, and each client gets its own.
::: seealso
pueblo()
Section titled “pueblo()”pueblo(<player|descriptor>)
This function returns 1 if the given player or descriptor is currently Pueblo-enabled, and 0 otherwise. An MXP client is not a Pueblo client: it returns 0 unless the client also sent the Pueblo handshake. TERMINFO() lists “mxp” for an MXP client.
If used on a player/descriptor which is not connected, pueblo() returns #-1 NOT CONNECTED. Mortals can only give a
When used with a
::: seealso
- TERMINFO()
- HTML()
- pueblo :::
::: seealso
HTML Functions
Section titled “HTML Functions”HTML Functions are used to output HTML tags to HTML capable users: Pueblo and MXP clients, and the web portal. These tags will be stripped by the system for anything non-HTML related.
Available functions:
- tagwrap()
- cmdlink()
- wshtml()
- html(), tag() and endtag() (see their entries)
Things a client may have that are not tags (a sound, a picture, a pane, a screen to clear) are written once and rendered by each client in its own way. See MEDIA FUNCTIONS.
Examples
Section titled “Examples”> say tagwrap(a,href="https://sharpmush.com",SharpMUSH)> say cmdlink(Who is online?,+who)> say wshtml(<a href="https://sharpmush.com">SharpMUSH</a>)Mortals are restricted in the tags they may use. Most standard HTML tags are ok; command links (cmdlink(), and the SEND and XCH_CMD parameters) can only be sent by Wizards or those with the Send_OOB @power.
html()
Section titled “html()”html(<string>)
In PennMUSH this wizard-only function outputs #-1 USE TAGWRAP INSTEAD. Use TAGWRAP().
::: seealso
- pueblo
- HTML
- HTML FUNCTIONS :::
tag(<name>[, <param1>[, ... , <paramN>]])
In PennMUSH this outputs an opening HTML/Pueblo tag. SharpMUSH’s markup is a span over the text it applies to, so it has no tag without an end, and tag() returns #-1 USE TAGWRAP INSTEAD. Use TAGWRAP().
::: seealso
endtag()
Section titled “endtag()”endtag(<name>)
In PennMUSH this outputs a closing HTML/Pueblo tag. As with TAG(), SharpMUSH returns #-1 USE TAGWRAP INSTEAD. Use TAGWRAP().
::: seealso
tagwrap()
Section titled “tagwrap()”tagwrap(<name>[, <parameters>], <string>)
This function outputs
The tag is markup on
Example
Section titled “Example”tagwrap(a,href="https://sharpmush.com",SharpMUSH Downloads)Will output (in HTML):
<a href="https://sharpmush.com">SharpMUSH Downloads</a>The tag is written as given, so it has to mean something in the reader’s client. Most tags are spelled the same in Pueblo and MXP, but command links are not: use CMDLINK() for one.
Without Send_OOB, #-1 PERMISSION DENIED), and the #-1 INVALID TAG NAME for everyone.
A particularly important use of this function is tagwrap(pre, <string>). Because Pueblo works like an html browser, spaces and tabs are compressed to a single space. If you have code (a +who function, for example) that relies on exact spacing, surround its output with a tagwrap(pre,…) so that Pueblo will render it as “preformatted” text.
::: seealso
cmdlink()
Section titled “cmdlink()”cmdlink(<string>, <command>[, <hint>])
Outputs
Each client gets the link in its own dialect: <a xch_cmd> for Pueblo, <send href> for MXP, a clickable link in the web portal. Every other client gets
cmdlink() is SharpMUSH’s own. It needs a Wizard or the Send_OOB @power, as PennMUSH requires for XCH_CMD; anyone else gets #-1 PERMISSION DENIED. A #-1 INVALID ARGUMENT: a line break would have the client send the rest as a second command, and the others are not part of any command a player could type.
Example
Section titled “Example”> think cmdlink(Who is online?,+who,List the connected players)::: seealso
Media Functions
Section titled “Media Functions”Sounds, pictures, panes and the rest are said once, and each client is told about them in the way that client has. An MXP client gets MXP’s elements, a Pueblo client its xch_ ones, the web portal an HTML element it can act on, and a plain telnet client either nothing or the words that stand in for what it cannot show.
Available functions:
- sound() and music()
- stopsound()
- image()
- figure() (a picture with text art and text flowing round it; see LAYOUT FUNCTIONS)
- pane()
- preformat()
- clearscreen()
- prefetch()
- expirelinks()
None of them leaves anything in the plain text, so strlen() and listen patterns see what they saw before, except where a function stands words in for what a client cannot show, such as a picture’s description.
All but preformat() need a Wizard or the Send_OOB @power, as CMDLINK() does: they make a client fetch a file, play it, or clear what the player is looking at. Laying text out does not, so preformat() is open to anyone. image() and figure() also accept the Send_Image @power, which allows pictures and nothing else; the approved role holds it, so an approved character can show a picture in a pose or a description.
::: seealso
- HTML FUNCTIONS :::
sound()
Section titled “sound()”sound(<file>[, <volume>[, <repeats>]])
Plays a sound effect. -1 to play it until it is stopped.
MXP gets <SOUND>, Pueblo <img xch_sound>, the web portal an <audio> element the page decides whether to play, and a plain telnet client nothing at all.
Example
Section titled “Example”> @pemit %#=[sound(door.wav,80)]The door creaks open.::: seealso
music()
Section titled “music()”music(<file>[, <volume>[, <repeats>]])
As SOUND(), for background music: one piece plays at a time, and MXP has a channel of its own for it. music(theme.mid,,-1) plays until something stops it.
::: seealso
- SOUND()
- STOPSOUND() :::
stopsound()
Section titled “stopsound()”stopsound([<channel>])
Silences what is playing. effects or music; with none, both stop.
::: seealso
image()
Section titled “image()”image(<address>[, <description>[, <width>[, <height>]]])
A picture.
<IMAGE>, Pueblo and the portal <img>, and a terminal the words.
Put it inside CMDLINK() for a picture that runs a command when clicked.
It needs a Wizard, the Send_OOB @power or the Send_Image @power (which the approved role holds); anyone else gets #-1 PERMISSION DENIED. A host the image_hosts option refuses is shown as the words.
Example
Section titled “Example”> @pemit %#=image(map.png,A map of the city,200)> @pemit %#=cmdlink(image(map.png,A map),look map)pane()
Section titled “pane()”pane(<text>, <name>[, <title>])
Sends
A client with no panes shows the text where it is, which is why the text is inside the function rather than sent after it.
Example
Section titled “Example”> @pemit %#=pane(u(fun`map),map,The Map)preformat()
Section titled “preformat()”preformat(<text>)
Says
A client reading the stream as HTML (a Pueblo client, the portal) collapses runs of spaces and uses a variable width font, so anything drawn with spaces needs this around it or its columns will not line up. Pueblo gets <xch_mudtext>, the portal <pre>, and a terminal the text unchanged, since a terminal lays it out that way already.
align(), align() and TABLE() already say it for themselves, as do tables and code blocks in help and wiki text. This is for columns you draw yourself.
Example
Section titled “Example”> &cmd`who Globals=$+who: @nspemit %#=preformat(u(fun`who))::: seealso
clearscreen()
Section titled “clearscreen()”clearscreen()
Clears what the player has been shown. A terminal is sent the ANSI sequence for it, Pueblo <xch_page clear="text">, and the portal an element it acts on. MXP has no such instruction, and an MXP client is sent nothing.
prefetch()
Section titled “prefetch()”prefetch(<address>)
Asks the client to fetch something now that it will want soon, so it is already there when it is used. Pueblo and the portal act on it; every other client is sent nothing.
expirelinks()
Section titled “expirelinks()”expirelinks([<group>])
Makes links already on the player’s screen stop working: those in
::: seealso
- CMDLINK() :::
WebSockets
Section titled “WebSockets”WebSockets are a network protocol used by JavaScript-enabled web browsers to make persistent network connections, similar to the telnet connection you use to connect to SharpMUSH. With WebSockets enabled in mush.cnf, it is possible to connect from MUSH clients embedded in HTML pages using JavaScript. A WebSocket client can natively render HTML, but can also parse Pueblo links into HTML links that send a command to the MUSH when clicked. For safety, we separate plain text from the other kinds of HTML/Pueblo code that we want rendered. In order to render HTML/Pueblo, a player with the Pueblo_Send power uses special functions to embed HTML/Pueblo markup. Players without the PUEBLO_SEND power can not use these markup functions. Any HTML code strings that are not properly marked up will simply show up as unrendered plain text.
See https://github.com/grapenut/websockclient for an example client.
The different kinds of markup that can be sent to clients are:
- Plain text
- HTML tags
- Pueblo links
- JSON objects
- Prompts
Without using any HTML markup functions, output is rendered as normal plain text (including ANSI and xterm256 color).
See HTML FUNCTIONS for functions used to embed HTML markup tags one at a time.
See WSHTML() for help embedding large segments of raw HTML markup to be sent to WebSocket clients.
For clickable command links, use CMDLINK(), e.g. cmdlink(Who is online?,+who). The web portal and the example client above both follow it, and so do Pueblo and MXP clients, each in its own dialect.
You can also send data encapsulated in a JSON object.
See json() for information about formatting data into JSON object strings.
See OOB() for sending a JSON object to a WebSocket client as a JavaScript object, or to a telnet client over GMCP.
See @prompt for information about sending telnet GOAHEAD prompts. Support for prompts depends on the WebSocket client. The example client above shows prompts on their own line, separating the input and output windows, but requires PROMPT_NEWLINES to be turned off.
::: seealso
wshtml()
Section titled “wshtml()”wshtml(<html>[, <default>])
Turns an HTML fragment into markup and returns it, for whatever emits it to deliver: text becomes the text, each element becomes a tag over what it encloses, exactly as TAGWRAP() builds one tag at a time. A WebSocket, Pueblo or MXP client receives the tags; an ANSI client gets the styling it can show for <b>, <i>, <u> and <s> and the words for everything else; everything else gets the words. Nothing is sent by the function itself, and the value stores, slices and re-evaluates like any other string.
The fragment is read the way a browser reads it: an unclosed tag closes at the end, a stray closing tag is dropped, a bare < is text. An element that encloses nothing is dropped, since a tag has to cover something; <br> is a line break.
The gate is TAGWRAP()‘s. With the Send_OOB power (Pueblo_Send is its older name), any tag and any attribute. Without it, only the tags PennMUSH’s tagwrap() allows (one forbidden tag refuses the whole fragment) and only attributes a browser cannot be made to run, one forbidden attribute dropping them all from that tag.
PennMUSH’s wshtml(<html>, <default>) takes a second, plain-text string for clients without HTML, and its wsjson() embeds a JSON object the same way. Here <default> is accepted, so softcode written for PennMUSH still runs, but it is not used: the markup’s own text is what a client without HTML sees. There is no wsjson(): JSON is data for a program rather than text with a plain reading, so it goes by OOB(), which sends it where a connection can receive it.
For example:
@emit [wshtml(<a href="https://sharpmush.com">SharpMUSH</a>)]A player on the web portal or a Pueblo/MXP client sees a link reading SharpMUSH; a telnet player, and any listening object, sees SharpMUSH.
::: seealso