💾 Archived View for auragem.letz.dev › devlog › terminal_emphasis_strong.go captured on 2024-05-26 at 14:47:45.
⬅️ Previous capture (2024-05-10)
-=-=-=-=-=-=-
// 2024 - Christian Lee Seibold // License: MIT package main import ( "bufio" "fmt" "strings" "unicode" ) func main() { reader := strings.NewReader("This is **some text** to show _how_ italics ** and bold __ could _**work.**_ along with `monospace.`") printWithEmphasisAndStrong(bufio.NewReader(reader)) } // Emphasis - one underscore // Strong - two asterisks // Monospace - one backtick (`) func printWithEmphasisAndStrong(reader *bufio.Reader) { previousRune := '\n' inStrong := false inEmphasis := false inMonospace := false for { r, _, err := reader.ReadRune() if err != nil { // EOF - reset everything, since this should be the end of the paragraph fmt.Printf("\x1B[m") return } if r == '`' || (!inMonospace && (r == '*' || r == '_')) { toggleRune := r toggle := string(r) unread := true // Get the next rune r, _, err = reader.ReadRune() if err != nil { // Set rune to new line, so it registers as a whitespace. r = '\n' unread = false } // If r is an asterisk, we require two for the toggle, so read the next rune. Otherwise, if just one asterisk, // print the runes and continue if toggleRune == '*' && r == '*' { toggle = "**" r, _, err = reader.ReadRune() if err != nil { // Set rune to new line, so it registers as a whitespace. r = '\n' unread = false } } else if toggleRune == '*' { fmt.Printf("*") _ = reader.UnreadRune() previousRune = '*' continue } if (!unicode.IsSpace(r) && r != toggleRune) || (!unicode.IsSpace(previousRune) && previousRune != toggleRune) { switch toggleRune { case '`': if inMonospace { // Reset inMonospace = false fmt.Printf("\x1B[22m") // Since 22m disables bold *and* dim, set bold again if necessary if inStrong { fmt.Printf("\x1B[1m") } } else { // Set inMonospace = true fmt.Printf("\x1B[2m") } case '*': if inStrong { // Reset inStrong = false // 22m disables bold *and* dim. However, we cannot use strong inside monospace toggles, so this doesn't matter. fmt.Printf("\x1B[22m") } else { // Set inStrong = true fmt.Printf("\x1B[1m") } case '_': if inEmphasis { // Reset inEmphasis = false fmt.Printf("\x1B[23m") } else { // Set inEmphasis = true fmt.Printf("\x1B[3m") // Replace this with 4m for underline in terminals that don't support emphasis. } } _ = reader.UnreadRune() if unread { previousRune = toggleRune } } else { // Not a toggle, print the toggle and unread the rune fmt.Printf("%s", toggle) _ = reader.UnreadRune() previousRune = toggleRune } } else { fmt.Printf("%c", r) previousRune = r } } }