Vecs
Vecs

Reputation: 3

Error displaying apostrophes in ASCII

I'm making a custom zsh theme for when you open up your terminal. I'm not that new to using oh-my-zsh but I am new to zsh documentation.

Here's what I'm having problems with:

wolf='               
           .-'''''-.
         .'         `.
        :             :
       :               :
       :      _/|      :
        :   =/_/      :
         `._/ |     .'
      (   /  ,|...-'
       \_/^\/||__
    _/~  `""~`"` \_
 __/  -'/  `-._ `\_\__
/     /-'`  `\   \  \-.\\

'


print -P $wolf

When I try it in terminal I get two errors:

  1. /Users/User/.oh-my-zsh/themes/wolf.zsh-theme:4: no such file or directory: . .\n : :\n : :\n : _/| :\n : =/_/ :\n._/ |

  2. /Users/User/.oh-my-zsh/themes/wolf.zsh-theme:31: parse error near `\n

I'm guessing that these errors have to do with the apostrophes in the ASCII art.

Upvotes: 0

Views: 443

Answers (1)

Adaephon
Adaephon

Reputation: 18399

The issue here (as jdv noted in his comment) is quoting.

In zsh:

  • it is not possible to use single-quotes (') withing single-quoted text. Any text within two single-quotes is taken verbatim, no additional quoting is possible. Single quotes can only be quoted with a preceding backslash or inside double quotes.
  • Within double-quotes (") backticks (`), dollar signs ($) and backslashes (\) are treated specially, and need to be quoted with a preceding backslash.

As quite a lot of these characters appear in your ASCII-art, you have to make sure, that they are all quoted properly.

Additionally, you use the builtin print, which by default also interprets \ as escape character.

There are two basic solutions:

  • Fully quote the string and use print -r or echo -E to print the text. In both cases the parameter disables escape sequence handling.

    The easiest way to achieve full quoting is probably to keep the surrounding single-quotes and replace any ' within with '\''. At every occurrence this closes the previous single-quoted text, adds a quoted single-quote and starts a new single-quoted text. Any other special character is then quoted within single quotes.

    wolf='               
               .-'\'''\'''\'''\'''\''-.
             .'\''         `.
            :             :
           :               :
           :      _/|      :
            :   =/_/      :
             `._/ |     .'\''
          (   /  ,|...-'\''
           \_/^\/||__
        _/~  `""~`"` \_
     __/  -'\''/  `-._ `\_\__
    /     /-'\''`  `\   \  \-.\\
    
    '
    print -r $wolf
    
  • Use a here-document with cat to avoid the whole quoting issue:

    cat <<'END'
               .-'''''-.
             .'         `.
            :             :
           :               :
           :      _/|      :
            :   =/_/      :
             `._/ |     .'
          (   /  ,|...-'
           \_/^\/||__
        _/~  `""~`"` \_
     __/  -'/  `-._ `\_\__
    /     /-'`  `\   \  \-.\\
    
    END
    

    Note the single quotes around 'END'. This needs to be done in order to disable parameter substitution ($FOO) and command substitution ($(command) or `command`) inside the here-document.

Upvotes: 1

Related Questions