summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/exception.rb
blob: 200d7272bfc57f439b84578e2ad3c8a3ca8e07a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# frozen_string_literal: true

module Sass
  # An exception thrown because a Sass compilation failed.
  class CompileError < StandardError
    # @return [String, nil]
    attr_reader :sass_stack

    # @return [Logger::SourceSpan, nil]
    attr_reader :span

    # @return [Array<String>]
    attr_reader :loaded_urls

    if Exception.public_method_defined?(:detailed_message, false)
      # @!visibility private
      def initialize(message, detailed_message, sass_stack, span, loaded_urls)
        super(message)

        @detailed_message = detailed_message
        @sass_stack = sass_stack
        @span = span
        @loaded_urls = loaded_urls
      end

      # @!visibility private
      def detailed_message(highlight: nil, **)
        return super if @detailed_message.nil?

        highlight = Exception.to_tty? if highlight.nil?

        detailed_message = @detailed_message.sub(message, super)
        detailed_message.gsub!(/\e\[[0-9;]*m/, '') unless highlight
        detailed_message
      end
    else # TODO: remove once ruby 3.1 support is dropped
      # @!visibility private
      def initialize(message, detailed_message, sass_stack, span, loaded_urls)
        super(detailed_message.nil? ? message : detailed_message)

        @message = message
        @detailed_message = detailed_message
        @sass_stack = sass_stack
        @span = span
        @loaded_urls = loaded_urls
      end

      # @!visibility private
      def message
        return @message if @detailed_message.nil? || @full_message.nil?

        @detailed_message
      end

      # @!visibility private
      def detailed_message(highlight: nil, **)
        highlight = Exception.to_tty? if highlight.nil?

        super_ = if highlight
                   lines = message.split("\n")
                   lines[0] += " (\e[1;4m#{self.class.name}\e[m\e[1m)" unless lines.empty?
                   lines.map { |line| "\e[1m#{line}\e[m" }.join("\n")
                 else
                   lines = message.split("\n", 2)
                   lines[0] += " (#{self.class.name})" unless lines.empty?
                   lines.join("\n")
                 end

        return super_ if @detailed_message.nil?

        detailed_message = @detailed_message.sub(message, super_)
        detailed_message.gsub!(/\e\[[0-9;]*m/, '') unless highlight
        detailed_message
      end

      # @!visibility private
      def full_message(highlight: nil, order: :top, **)
        highlight = Exception.to_tty? if highlight.nil?

        @full_message = true
        full_message = super.force_encoding(message.encoding)
        full_message.gsub!(/\e\[[0-9;]*m/, '') unless highlight
        full_message
      ensure
        @full_message = nil
      end
    end

    # @return [String]
    def to_css
      content = full_message(highlight: false, order: :top)

      <<~CSS.freeze
        /* #{content.gsub('*/', "*\u2060/").gsub("\r\n", "\n").split("\n").join("\n * ")} */

        body::before {
          position: static;
          display: block;
          padding: 1em;
          margin: 0 0 1em;
          border-width: 0 0 2px;
          border-bottom-style: solid;
          font-family: monospace, monospace;
          white-space: pre;
          content: #{Serializer.serialize_quoted_string(content).gsub(/[^[:ascii:]][\h\t ]?/) do |match|
            ordinal = match.ord
            replacement = "\\#{ordinal.to_s(16)}"
            if match.length > 1
              replacement << ' ' if ordinal < 0x100000
              replacement << match[1]
            end
            replacement
          end};
        }
      CSS
    end
  end

  # An exception thrown by Sass Script.
  class ScriptError < StandardError
    # @!visibility private
    def initialize(message, name = nil)
      super(name.nil? ? message : "$#{name}: #{message}")
    end
  end
end