A user-friendly RichText module to help assist with RichText formatting using functions so you don’t have to memorize the formatting.
I’m releasing this early as a part of my future utilities package because for some reason I cant find anyone who has made this yet.
It’s free and fully strictly typed.
RichTextUtilities.lua
--!strict
--[=[
local RichTextUtilities = require(script.RichTextUtilities)
local tag = RichTextUtilities.tag
local fontToFaceFormat = RichTextUtilities.fontToFaceFormat
local fontToFamilyFormat = RichTextUtilities.fontToFamilyFormat
local colorToRgbFormat = RichTextUtilities.colorToRgbFormat
local colorToHexFormat = RichTextUtilities.colorToHexFormat
local font = RichTextUtilities.font
local fontFunction = RichTextUtilities.fontFunction
local fontFace = RichTextUtilities.fontFace
local fontFamily = RichTextUtilities.fontFamily
local fontWeight = RichTextUtilities.fontWeight
local fontColor = RichTextUtilities.fontColor
local fontSize = RichTextUtilities.fontSize
local fontTransparency = RichTextUtilities.fontTransparency
local stroke = RichTextUtilities.stroke
local strokeFunction = RichTextUtilities.strokeFunction
local strokeColor = RichTextUtilities.strokeColor
local strokeThickness = RichTextUtilities.strokeThickness
local strokeTransparency = RichTextUtilities.strokeTransparency
local strokeJoins = RichTextUtilities.strokeJoins
local bold = RichTextUtilities.bold
local italic = RichTextUtilities.italic
local underline = RichTextUtilities.underline
local strikethrough = RichTextUtilities.strikethrough
local uppercase = RichTextUtilities.uppercase
local smallcaps = RichTextUtilities.smallcaps
local comment = RichTextUtilities.comment
local linebreak = RichTextUtilities.linebreak
]=]
local RichTextUtilities = {}
local MappedFontEnumToFamily: {[Enum.Font]: string} = {}
do
pcall(function(): ()
for _: number, fontEnum: Enum.Font in Enum.Font:GetEnumItems() do
local font: Font = Font.fromEnum(fontEnum)
MappedFontEnumToFamily[fontEnum] = font.Family
end
end)
end
function RichTextUtilities.fontToFaceFormat(font: Enum.Font): string
return if font ~= Enum.Font.Unknown then font.Name else Enum.Font.BuilderSans.Name
end
function RichTextUtilities.fontToFamilyFormat(font: Enum.Font): string
return MappedFontEnumToFamily[font] or MappedFontEnumToFamily[Enum.Font.BuilderSans]
end
function RichTextUtilities.colorToRgbFormat(color: Color3): string
return `rgb({math.round(color.R * 255)}, {math.round(color.G * 255)}, {math.round(color.B * 255)})`
end
function RichTextUtilities.colorToHexFormat(color: Color3): string
return `#{color:ToHex()}`
end
function RichTextUtilities.tag(text: string, tag: string, attributes: {[string]: string | number}?): string
local attributesString: string = ``
if attributes ~= nil then
for attribute: string, value: string | number in attributes do
attributesString = `{attributesString} {attribute}="{value}"`
end
end
return `<{tag}{attributesString}>{text}</{tag}>`
end
local function generateFontAttributes(font: Enum.Font?, weight: Enum.FontWeight?, color: Color3?, size: number?, transparency: number?, fontUsesFamily: boolean?, colorUsesHex: boolean?): {[string]: string | number}?
local fontAttributes: {[string]: string | number} = {}
if font ~= nil then
fontAttributes[if fontUsesFamily == true then `family` else `face`] = if fontUsesFamily == true then RichTextUtilities.fontToFamilyFormat(font) else RichTextUtilities.fontToFaceFormat(font)
end
if weight ~= nil then
fontAttributes[`weight`] = weight.Value
end
if color ~= nil then
fontAttributes[`color`] = if colorUsesHex == true then RichTextUtilities.colorToHexFormat(color) else RichTextUtilities.colorToRgbFormat(color)
end
if size ~= nil then
fontAttributes[`size`] = size
end
if transparency ~= nil then
fontAttributes[`transparency`] = transparency
end
return if next(fontAttributes) ~= nil then fontAttributes else nil
end
function RichTextUtilities.font(text: string, font: Enum.Font?, weight: Enum.FontWeight?, color: Color3?, size: number?, transparency: number?, fontUsesFamily: boolean?, colorUsesHex: boolean?): string
return RichTextUtilities.tag(text, `font`, generateFontAttributes(font, weight, color, size, transparency, fontUsesFamily, colorUsesHex))
end
function RichTextUtilities.fontFunction(font: Enum.Font?, weight: Enum.FontWeight?, color: Color3?, size: number?, transparency: number?, fontUsesFamily: boolean?, colorUsesHex: boolean?): (text: string) -> string
local fontAttributes: {[string]: string | number}? = generateFontAttributes(font, weight, color, size, transparency, fontUsesFamily, colorUsesHex)
return function(text: string): string
return RichTextUtilities.tag(text, `font`, fontAttributes)
end
end
function RichTextUtilities.fontFace(text: string, face: Enum.Font): string
return RichTextUtilities.font(text, face, nil, nil, nil, nil, nil, nil)
end
function RichTextUtilities.fontFamily(text: string, family: Enum.Font): string
return RichTextUtilities.font(text, family, nil, nil, nil, nil, true, nil)
end
function RichTextUtilities.fontWeight(text: string, weight: Enum.FontWeight): string
return RichTextUtilities.font(text, nil, weight, nil, nil, nil, true, nil)
end
function RichTextUtilities.fontColor(text: string, color: Color3, colorUsesHex: boolean?): string
return RichTextUtilities.font(text, nil, nil, color, nil, nil, nil, colorUsesHex)
end
function RichTextUtilities.fontSize(text: string, size: number): string
return RichTextUtilities.font(text, nil, nil, nil, size, nil, nil, nil)
end
function RichTextUtilities.fontTransparency(text: string, transparency: number): string
return RichTextUtilities.font(text, nil, nil, nil, nil, transparency, nil, nil)
end
local function generateStrokeAttributes(color: Color3?, thickness: number?, transparency: number?, joins: Enum.LineJoinMode?, colorUsesHex: boolean?): {[string]: string | number}?
local strokeAttributes: {[string]: string | number} = {}
if color ~= nil then
strokeAttributes[`color`] = if colorUsesHex == true then RichTextUtilities.colorToHexFormat(color) else RichTextUtilities.colorToRgbFormat(color)
end
if thickness ~= nil then
strokeAttributes[`thickness`] = thickness
end
if joins ~= nil then
strokeAttributes[`joins`] = string.lower(joins.Name)
end
return if next(strokeAttributes) ~= nil then strokeAttributes else nil
end
function RichTextUtilities.stroke(text: string, color: Color3?, thickness: number?, transparency: number?, joins: Enum.LineJoinMode?, colorUsesHex: boolean?): string
return RichTextUtilities.tag(text, `stroke`, generateStrokeAttributes(color, thickness, transparency, joins, colorUsesHex))
end
function RichTextUtilities.strokeFunction(color: Color3?, thickness: number?, transparency: number?, joins: Enum.LineJoinMode?, colorUsesHex: boolean?): (text: string) -> string
local strokeAttributes: {[string]: string | number}? = generateStrokeAttributes(color, thickness, transparency, joins, colorUsesHex)
return function(text: string): string
return RichTextUtilities.tag(text, `stroke`, strokeAttributes)
end
end
function RichTextUtilities.strokeColor(text: string, color: Color3, colorUsesHex: boolean?): string
return RichTextUtilities.stroke(text, color, nil, nil, nil, colorUsesHex)
end
function RichTextUtilities.strokeThickness(text: string, thickness: number): string
return RichTextUtilities.stroke(text, nil, thickness, nil, nil, nil)
end
function RichTextUtilities.strokeTransparency(text: string, transparency: number): string
return RichTextUtilities.stroke(text, nil, nil, transparency, nil, nil)
end
function RichTextUtilities.strokeJoins(text: string, joins: Enum.LineJoinMode): string
return RichTextUtilities.stroke(text, nil, nil, nil, joins, nil)
end
function RichTextUtilities.bold(text: string): string
return RichTextUtilities.tag(text, `b`)
end
function RichTextUtilities.italic(text: string): string
return RichTextUtilities.tag(text, `i`)
end
function RichTextUtilities.underline(text: string): string
return RichTextUtilities.tag(text, `u`)
end
function RichTextUtilities.strikethrough(text: string): string
return RichTextUtilities.tag(text, `s`)
end
function RichTextUtilities.uppercase(text: string, useLongFormat: boolean?): string
return RichTextUtilities.tag(text, if useLongFormat == nil or useLongFormat == false then `uc` else `uppercase`)
end
function RichTextUtilities.smallcaps(text: string, useLongFormat: boolean?): string
return RichTextUtilities.tag(text, if useLongFormat == nil or useLongFormat == false then `sc` else `smallcaps`)
end
function RichTextUtilities.comment(text: string): string
return `<!--{text}-->`
end
function RichTextUtilities.linebreak(): string
return `<br />`
end
return table.freeze(RichTextUtilities)
Usage and Examples
--!strict
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RichTextUtilities = require(ReplicatedStorage.RichTextUtilities)
local tag = RichTextUtilities.tag
local fontToFaceFormat = RichTextUtilities.fontToFaceFormat
local fontToFamilyFormat = RichTextUtilities.fontToFamilyFormat
local colorToRgbFormat = RichTextUtilities.colorToRgbFormat
local colorToHexFormat = RichTextUtilities.colorToHexFormat
local font = RichTextUtilities.font
local fontFunction = RichTextUtilities.fontFunction
local fontFace = RichTextUtilities.fontFace
local fontFamily = RichTextUtilities.fontFamily
local fontWeight = RichTextUtilities.fontWeight
local fontColor = RichTextUtilities.fontColor
local fontSize = RichTextUtilities.fontSize
local fontTransparency = RichTextUtilities.fontTransparency
local stroke = RichTextUtilities.stroke
local strokeFunction = RichTextUtilities.strokeFunction
local strokeColor = RichTextUtilities.strokeColor
local strokeThickness = RichTextUtilities.strokeThickness
local strokeTransparency = RichTextUtilities.strokeTransparency
local strokeJoins = RichTextUtilities.strokeJoins
local bold = RichTextUtilities.bold
local italic = RichTextUtilities.italic
local underline = RichTextUtilities.underline
local strikethrough = RichTextUtilities.strikethrough
local uppercase = RichTextUtilities.uppercase
local smallcaps = RichTextUtilities.smallcaps
local comment = RichTextUtilities.comment
local linebreak = RichTextUtilities.linebreak
--[=[ tag(text: string, tag: string, attributes: {[string]: string | number}?): string ]=]
print(tag(`Hello, World!`, `stroke`, {
color = colorToRgbFormat(Color3.fromRGB(85, 255, 0)),
thickness = 1,
transparency = 0.5,
joins = string.lower(Enum.LineJoinMode.Round.Name)
}))
-- <stroke thickness="1" transparency="0.5" joins="round">Hello, World!</stroke>
--[=[ fontToFaceFormat(font: Enum.Font): string ]=]
print(fontToFaceFormat(Enum.Font.Fantasy))
-- Fantasy
--[=[ fontToFaceFormat(font: Enum.Font): string ]=]
print(fontToFamilyFormat(Enum.Font.GothamBlack))
-- rbxasset://fonts/families/GothamSSm.json
--[=[ colorToRgbFormat(color: Color3): string ]=]
print(colorToRgbFormat(Color3.fromRGB(85, 255, 0)))
-- rgb(85, 255, 0)
--[=[ font(text: string, font: Enum.Font?, weight: Enum.FontWeight?, color: Color3?, size: number?, transparency: number?, fontUsesFamily: boolean?, colorUsesHex: boolean?): string ]=]
print(font(`Welcome traveller. Would you like to view my wares?`, Enum.Font.Fantasy, Enum.FontWeight.Thin, nil, nil, nil, true, true))
-- <font family="rbxasset://fonts/families/Balthazar.json" weight="100">Welcome traveller. Would you like to view my wares?</font>
--[=[ fontFunction(font: Enum.Font?, weight: Enum.FontWeight?, color: Color3?, size: number?, transparency: number?, fontUsesFamily: boolean?, colorUsesHex: boolean?): (text: string) -> string ]=]
local shoutFormat: (text: string) -> string = fontFunction(nil, Enum.FontWeight.Heavy, Color3.new(1, 0, 0))
print(shoutFormat(`You dare stumble upon my territory!?`))
-- <font color="rgb(255, 0, 0)" weight="900">You dare stumble upon my territory!?</font>
--[=[ fontFace(text: string, font: Enum.Font): string ]=]
print(fontFace(`Hello, World!`, Enum.Font.Code))
-- <font face="Code">Hello, World!</font>
--[=[ fontFamily(text: string, font: Enum.Font): string ]=]
print(fontFamily(`Hello, World!`, Enum.Font.Code))
-- <font family="rbxasset://fonts/families/Inconsolata.json">Hello, World!</font>
--[=[ fontWeight(text: string, weight: Enum.FontWeight): string ]=]
print(fontWeight(`Hello, World!`, Enum.FontWeight.Regular))
-- <font weight="400">Hello, World!</font>
--[=[ fontColor(text: string, color: Color3, colorUsesHex: boolean?): string ]=]
print(fontColor(`Hello, World!`, Color3.new(1, 0, 1), true))
-- <font color="#ff00ff">Hello, World!</font>
--[=[ fontSize(text: string, size: number): string ]=]
print(fontSize(`Hello, World!`, 24))
-- <font size="24">Hello, World!</font>
--[=[ fontTransparency(text: string, transparency: number): string ]=]
print(fontTransparency(`Hello, World!`, 0.2))
-- <font transparency="0.2">Hello, World!</font>
--[=[ stroke(text: string, color: Color3?, thickness: number?, transparency: number?, joins: Enum.LineJoinMode?, colorUsesHex: boolean?): string ]=]
print(stroke(`This sentence is purple outlined!`, Color3.fromRGB(170, 85, 255), 2, nil, Enum.LineJoinMode.Round))
-- <stroke thickness="2" joins="round" color="rgb(170, 85, 255)">This sentence is purple outlined!</stroke>
--[=[ strokeFunction(color: Color3?, thickness: number?, transparency: number?, joins: Enum.LineJoinMode?, colorUsesHex: boolean?): (text: string) -> string ]=]
local currencyStrokeFormat: (text: string) -> string = strokeFunction(Color3.fromRGB(255, 255, 0), 2, 0.5)
print(currencyStrokeFormat(`$900,000,000`))
-- <stroke color="rgb(255, 255, 0)" thickness="2">$900,000,000</stroke>
--[=[ strokeColor(text: string, color: Color3, colorUsesHex: boolean?): string ]=]
print(strokeColor(`Hello, World!`, Color3.new(0, 0, 0), true))
-- <stroke color="#000000">Hello, World!</stroke>
--[=[ strokeThickness(text: string, thickness: number): string ]=]
print(strokeThickness(`Hello, World!`, 1.5))
-- <stroke thickness="1.5">Hello, World!</stroke>
--[=[ strokeTransparency(text: string, transparency: number): string ]=]
print(strokeThickness(`Hello, World!`, 0.2))
-- <stroke transparency="0.2">Hello, World!</stroke>
--[=[ strokeJoins(text: string, joins: Enum.LineJoinMode): string ]=]
print(strokeJoins(`Hello, World!`, Enum.LineJoinMode.Bevel))
-- <stroke joins="bevel">Hello, World!</stroke>
--[=[ bold(text: string): string ]=]
print(bold(`Hello, World!`))
-- <b>Hello, World!</b>
--[=[ italic(text: string): string ]=]
print(italic(`Hello, World!`))
-- <i>Hello, World!</i>
--[=[ underline(text: string): string ]=]
print(underline(`Hello, World!`))
-- <u>Hello, World!</u>
--[=[ strikethrough(text: string): string ]=]
print(strikethrough(`Hello, World!`))
-- <s>Hello, World!</s>
--[=[ uppercase(text: string, useLongFormat: boolean?): string ]=]
print(uppercase(`Hello, World!`))
-- <uc>Hello, World!</uc>
--[=[ smallcaps(text: string, useLongFormat: boolean?): string ]=]
print(smallcaps(`Hello, World!`, true))
-- <smallcaps>Hello, World!</smallcaps>
--[=[ comment(text: string): string ]=]
print(comment(`This will not be visible in a TextLabel with RichText enabled.`))
-- <!--This will not be visible in a TextLabel with RichText enabled.-->
--[=[ linebreak(): string ]=]
print(linebreak())
-- <br />