View Javadoc
1   /*
2    * Copyright (C) 2016-2017 Ronald Jack Jenkins Jr., SLF4Bukkit contributors.
3    *
4    * This program is free software: you can redistribute it and/or modify
5    * it under the terms of the GNU General Public License as published by
6    * the Free Software Foundation, either version 3 of the License, or
7    * (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16   */
17  package info.ronjenkins.slf4bukkit;
18  
19  import com.google.common.collect.ImmutableMap;
20  
21  import org.bukkit.ChatColor;
22  import org.fusesource.jansi.Ansi;
23  import org.fusesource.jansi.Ansi.Attribute;
24  
25  import java.util.Map;
26  
27  /**
28   * Maps {@link ChatColor} values to their JAnsi equivalents.
29   *
30   * @author Ronald Jack Jenkins Jr.
31   */
32  final class AnsiColorMapper implements ColorMapper {
33  
34    /**
35     * No-op constructor. Callers must catch {@code Throwable} and handle the
36     * scenario in which JAnsi is not available by substituting another
37     * {@link ColorMapper} implementation.
38     *
39     * @throws Throwable if JAnsi is not present at runtime.
40     */
41    AnsiColorMapper() throws Throwable {}
42  
43    // @formatter:off
44    private final Map<ChatColor, String> MAP = ImmutableMap.<ChatColor, String>builder()
45      .put(ChatColor.BLACK, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).boldOff().toString())
46      .put(ChatColor.DARK_BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).boldOff().toString())
47      .put(ChatColor.DARK_GREEN, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.GREEN).boldOff().toString())
48      .put(ChatColor.DARK_AQUA, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.CYAN).boldOff().toString())
49      .put(ChatColor.DARK_RED, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.RED).boldOff().toString())
50      .put(ChatColor.DARK_PURPLE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.MAGENTA).boldOff().toString())
51      .put(ChatColor.GOLD, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.YELLOW).boldOff().toString())
52      .put(ChatColor.GRAY, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.WHITE).boldOff().toString())
53      .put(ChatColor.DARK_GRAY, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).bold().toString())
54      .put(ChatColor.BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).bold().toString())
55      .put(ChatColor.GREEN, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.GREEN).bold().toString())
56      .put(ChatColor.AQUA, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.CYAN).bold().toString())
57      .put(ChatColor.RED, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.RED).bold().toString())
58      .put(ChatColor.LIGHT_PURPLE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.MAGENTA).bold().toString())
59      .put(ChatColor.YELLOW, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.YELLOW).bold().toString())
60      .put(ChatColor.WHITE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.WHITE).bold().toString())
61      .put(ChatColor.MAGIC, Ansi.ansi().a(Attribute.BLINK_SLOW).toString())
62      .put(ChatColor.BOLD, Ansi.ansi().a(Attribute.UNDERLINE_DOUBLE).toString())
63      .put(ChatColor.STRIKETHROUGH, Ansi.ansi().a(Attribute.STRIKETHROUGH_ON).toString())
64      .put(ChatColor.UNDERLINE, Ansi.ansi().a(Attribute.UNDERLINE).toString())
65      .put(ChatColor.ITALIC, Ansi.ansi().a(Attribute.ITALIC).toString())
66      .put(ChatColor.RESET, Ansi.ansi().a(Attribute.RESET).toString())
67    .build();
68    // @formatter:on
69  
70    @Override
71    public String map(final String input) {
72      if (input == null) {
73        return "";
74      }
75      String output = input;
76      for (final Map.Entry<ChatColor, String> mapping : MAP.entrySet()) {
77        output = output.replace(mapping.getKey().toString(), mapping.getValue());
78      }
79      return output;
80    }
81  
82  }