Skip to content

ANSI

Canonical source: protos/lib/text/ANSI.protos at locked revision e99b712ecf658a527b1fe82c8beba2c1286d8dc9.

// THE LICENSED WORK IS PROVIDED UNDER THE TERMS OF THE ADAPTIVE PUBLIC LICENSE
// ("LICENSE") AS FIRST COMPLETED BY: Guillermo Adrián Molina. ANY USE, PUBLIC
// DISPLAY, PUBLIC PERFORMANCE, REPRODUCTION OR DISTRIBUTION OF, OR PREPARATION OF
// DERIVATIVE WORKS BASED ON, THE LICENSED WORK CONSTITUTES RECIPIENT'S ACCEPTANCE
// OF THIS LICENSE AND ITS TERMS, WHETHER OR NOT SUCH RECIPIENT READS THE TERMS OF
// THE LICENSE. "LICENSED WORK" AND "RECIPIENT" ARE DEFINED IN THE LICENSE. A COPY
// OF THE LICENSE IS LOCATED IN THE TEXT FILE ENTITLED "LICENSE.TXT" ACCOMPANYING
// THE CONTENTS OF THIS FILE. IF A COPY OF THE LICENSE DOES NOT ACCOMPANY THIS
// FILE, A COPY OF THE LICENSE MAY ALSO BE OBTAINED AT THE FOLLOWING WEB SITE:
// https://github.com/guillermomolina/protos
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
// the specific language governing rights and limitations under the License.
//! Pure rendering of `std:text/StyledText` values to Strings with ANSI SGR
//! foreground sequences. Rendering only transforms its arguments: it consults
//! no environment, terminal, process, writer, or global configuration, and
//! whether styling is enabled is decided entirely by the caller.
//!
//! Run text is copied unchanged. The renderer is neither a sanitizer nor an
//! ANSI parser: escape and other control characters already present in the
//! text pass through as content, and only the sequences the renderer itself
//! generates are known to it.
/// Answers the String rendering of `styledText`, which must be a styled text
/// recognized by `std:text/StyledText`. `stylingEnabled` must be exactly
/// `true` or `false`; any other argument signals an Error, and no argument is
/// converted.
///
/// With `false` the result is the text of every run, in order, and contains
/// no generated escape sequence. With `true` each non-default foreground
/// starts with its SGR sequence (`ESC[30m` black, `ESC[31m` red, `ESC[32m`
/// green, `ESC[33m` yellow, `ESC[34m` blue, `ESC[35m` magenta, `ESC[36m` cyan,
/// `ESC[37m` white). Leaving a foreground for the default foreground, for a
/// different foreground, or at the end of the result emits `ESC[0m` first.
/// Default-foreground text, and empty styled text, generate no sequence.
render: ((styledTextFacility, styleFacility) => (styledText, stylingEnabled) => {
StyledText: import("std:text/StyledText")
(StyledText.recognizes(styledText) && ((stylingEnabled === true) || (stylingEnabled === false))).ifFalse(() => {
Error().signal()
})
runs: styledTextFacility.state(styledText)
result: ""
stylingEnabled.ifTrueIfFalse(() => {
escape: "\u{1B}["
codes: Map()
codes["black"] = "30"
codes["red"] = "31"
codes["green"] = "32"
codes["yellow"] = "33"
codes["blue"] = "34"
codes["magenta"] = "35"
codes["cyan"] = "36"
codes["white"] = "37"
reset: escape.concat("0m")
active: "default"
runs.each((run) => {
foreground: styleFacility.state(run[1])
(foreground != active).ifTrue(() => {
(active != "default").ifTrue(() => {
result = result.concat(reset)
})
(foreground != "default").ifTrue(() => {
result = result.concat(escape, codes[foreground], "m")
})
active = foreground
})
result = result.concat(run[0])
})
(active != "default").ifTrue(() => {
result = result.concat(reset)
})
}, () => {
runs.each((run) => {
result = result.concat(run[0])
})
})
result
})(_styledTextFacility, _styleFacility)
// The runtime-provisioned facilities of std:text/StyledText and std:text/Style
// are captured privately above; they are not module surface.
context.removeSlot("_styledTextFacility")
context.removeSlot("_styleFacility")

← text family · Standard-library source