Class: Howzit::Topic

Inherits:
Object
  • Object
show all
Defined in:
lib/howzit/topic.rb

Overview

Topic Class

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(title, content) ⇒ Topic

Initialize a topic object



18
19
20
21
22
23
24
# File 'lib/howzit/topic.rb', line 18

def initialize(title, content)
  @title = title
  @content = content
  @parent = nil
  @nest_level = 0
  @tasks = gather_tasks
end

Instance Attribute Details

#contentObject

Returns the value of attribute content.



8
9
10
# File 'lib/howzit/topic.rb', line 8

def content
  @content
end

#parent=(value) ⇒ Object (writeonly)

Sets the attribute parent



6
7
8
# File 'lib/howzit/topic.rb', line 6

def parent=(value)
  @parent = value
end

#postreqsObject (readonly)

Returns the value of attribute postreqs.



10
11
12
# File 'lib/howzit/topic.rb', line 10

def postreqs
  @postreqs
end

#prereqsObject (readonly)

Returns the value of attribute prereqs.



10
11
12
# File 'lib/howzit/topic.rb', line 10

def prereqs
  @prereqs
end

#tasksObject (readonly)

Returns the value of attribute tasks.



10
11
12
# File 'lib/howzit/topic.rb', line 10

def tasks
  @tasks
end

#titleObject (readonly)

Returns the value of attribute title.



10
11
12
# File 'lib/howzit/topic.rb', line 10

def title
  @title
end

Instance Method Details

#grep(term) ⇒ Object

Search title and contents for a pattern



31
32
33
# File 'lib/howzit/topic.rb', line 31

def grep(term)
  @title =~ /#{term}/i || @content =~ /#{term}/i
end

Output a topic with fancy title and bright white text.



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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/howzit/topic.rb', line 86

def print_out(options = {})
  defaults = { single: false, header: true }
  opt = defaults.merge(options)

  output = []
  if opt[:header]
    output.push(@title.format_header)
    output.push('')
  end
  topic = @content.dup
  topic.gsub!(/(?mi)^(`{3,})run([?!]*) *([^\n]*)[\s\S]*?\n\1\s*$/, '@@@run\2 \3') unless Howzit.options[:show_all_code]
  topic.split(/\n/).each do |l|
    case l
    when /@(before|after|prereq|end)/
      next
    when /@include(?<optional>[!?]{1,2})?\((?<action>.*?)\)/
      m = Regexp.last_match.named_captures.symbolize_keys
      matches = Howzit.buildnote.find_topic(m[:action])
      unless matches.empty?
        i_topic = matches[0]
        rule = '{kKd}'
        color = '{Kyd}'
        option = if i_topic.tasks.empty?
                   ''
                 else
                   optional = m[:optional] =~ /[?!]+/ ? true : false
                   default = m[:optional] =~ /!/ ? false : true
                   if optional
                     default ? " {xKk}[{gbK}Y{xKk}/{dbwK}n{xKk}]{x}#{color}".c : " {xKk}[{dbwK}y{xKk}/{bgK}N{xKk}]{x}#{color}".c
                   else
                     ''
                   end
                 end
        title = "#{opt[:single] ? 'From' : 'Include'} #{i_topic.title}#{option}:"
        options = { color: color, hr: '.', border: rule }
        unless Howzit.inclusions.include?(i_topic)
          output.push("#{'> ' * @nest_level}#{title}".format_header(options))
        end

        if opt[:single] && Howzit.inclusions.include?(i_topic)
          output.push("#{'> ' * @nest_level}#{title} included above".format_header(options))
        elsif opt[:single]
          @nest_level += 1
          output.concat(i_topic.print_out({ single: true, header: false }))
          output.push("#{'> ' * @nest_level}...".format_header(options))
          @nest_level -= 1
        end
        Howzit.inclusions.push(i_topic)
      end
    when /@(?<cmd>run|copy|open|url|include)(?<optional>[?!]{1,2})?\((?<action>.*?)\) *(?<title>.*?)$/
      m = Regexp.last_match.named_captures.symbolize_keys
      cmd = m[:cmd]
      obj = m[:action]
      title = m[:title].empty? ? obj : m[:title].strip
      title = Howzit.options[:show_all_code] ? obj : title
      optional = m[:optional] =~ /[?!]+/ ? true : false
      default = m[:optional] =~ /!/ ? false : true
      option = if optional
                 default ? ' {xk}[{g}Y{xk}/{dbw}n{xk}]{x}'.c : ' {xk}[{dbw}y{xk}/{g}N{xk}]{x}'.c
               else
                 ''
               end
      icon = case cmd
             when 'run'
               "\u{25B6}"
             when 'copy'
               "\u{271A}"
             when /open|url/
               "\u{279A}"
             end

      output.push("{bmK}#{icon} {bwK}#{title.preserve_escapes}{x}#{option}".c)
    when /(?<fence>`{3,})run(?<optional>[!?]{1,2})? *(?<title>.*?)$/i
      m = Regexp.last_match.named_captures.symbolize_keys
      optional = m[:optional] =~ /[?!]+/ ? true : false
      default = m[:optional] =~ /!/ ? false : true
      option = if optional
                 default ? ' {xk}[{g}Y{xk}/{dbw}n{xk}]{x}'.c : ' {xk}[{dbw}y{xk}/{g}N{xk}]{x}'.c
               else
                 ''
               end
      desc = m[:title].length.positive? ? "Block: #{m[:title]}#{option}" : "Code Block#{option}"
      output.push("{bmK}\u{25B6} {bwK}#{desc}{x}\n```".c)
    when /@@@run(?<optional>[!?]{1,2})? *(?<title>.*?)$/i
      m = Regexp.last_match.named_captures.symbolize_keys
      optional = m[:optional] =~ /[?!]+/ ? true : false
      default = m[:optional] =~ /!/ ? false : true
      option = if optional
                 default ? ' {xk}[{g}Y{xk}/{dbw}n{xk}]{x}'.c : ' {xk}[{dbw}y{xk}/{g}N{xk}]{x}'.c
               else
                 ''
               end
      desc = m[:title].length.positive? ? "Block: #{m[:title]}#{option}" : "Code Block#{option}"
      output.push("{bmK}\u{25B6} {bwK}#{desc}{x}".c)
    else
      l.wrap!(Howzit.options[:wrap]) if Howzit.options[:wrap].positive?
      output.push(l)
    end
  end
  output.push('')
end

#run(nested: false) ⇒ Object

Handle run command, execute directives in topic



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
# File 'lib/howzit/topic.rb', line 36

def run(nested: false)
  output = []
  tasks = 0
  cols = begin
    TTY::Screen.columns > 60 ? 60 : TTY::Screen.columns
  rescue StandardError
    60
  end

  if @tasks.count.positive?
    unless @prereqs.empty?
      puts TTY::Box.frame("{by}#{@prereqs.join("\n\n").wrap(cols - 4)}{x}".c, width: cols)
      res = Prompt.yn('Have the above prerequisites been met?', default: true)
      Process.exit 1 unless res

    end

    @tasks.each do |task|
      if task.optional
        note = if task.type == :include
                 task_count = Howzit.buildnote.find_topic(task.action)[0].tasks.count
                 " (#{task_count} tasks)"
               else
                 ''
               end
        q = %({bg}#{task.type.to_s.capitalize} {xw}"{bw}#{task.title}{xw}"#{note}{x}).c
        res = Prompt.yn(q, default: task.default)
        next unless res

      end
      run_output, total = task.run
      output.concat(run_output)
      tasks += total
    end
  else
    Howzit.console.warn "{r}--run: No {br}@directive{xr} found in {bw}#{@title}{x}".c
  end
  output.push("{bm}Ran #{tasks} #{tasks == 1 ? 'task' : 'tasks'}{x}".c) if Howzit.options[:log_level] < 2 && !nested

  puts TTY::Box.frame("{bw}#{@postreqs.join("\n\n").wrap(cols - 4)}{x}".c, width: cols) unless @postreqs.empty?

  output
end