jtag 0.1.22 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/jtag/string.rb CHANGED
@@ -1,244 +1,48 @@
1
- # frozen_string_literal: true
2
-
3
- module JekyllTag
4
- ## String helpers
5
- class ::String
6
- ##
7
- ## normalize bool string to symbo
8
- ##
9
- ## @return [Symbol] :and :or :not
10
- ##
11
- def to_bool
12
- case self.downcase
13
- when /^a/i
14
- :and
15
- when /^o/i
16
- :or
17
- when /^n/i
18
- :not
19
- else
20
- raise ArgumentError, "Invalid boolean string: #{self}"
21
- end
22
- end
23
-
24
- ##
25
- ## Convert a string to a format symbol (:csv, :complete, :json, :plist, :yaml)
26
- ##
27
- ## @return [Symbol] format symbol
28
- ##
29
- def to_format
30
- case self.downcase
31
- when /^j/i
32
- :json
33
- when /^p/i
34
- :plist
35
- when /^y/i
36
- :yaml
37
- when /^cs/i
38
- :csv
39
- when /^c/i
40
- :complete
41
- else
42
- raise ArgumentError, "Invalid format string: #{self}"
43
- end
44
- end
45
-
46
- ## Check if a string is a list of files
47
- ##
48
- ## @param null [Boolean] check for null-delimited list
49
- ##
50
- ## @example Check if a string is a list of files
51
- ## "file1\nfile2\nfile3".file_list?
52
- ## # => true
53
- ##
54
- ## @return [Boolean]
55
- def file_list?(null = false)
56
- self.strip.split(null ? "\x00" : "\n").each do |line|
57
- return false unless File.exist?(line)
58
- end
59
- true
60
- end
61
-
62
- ##
63
- ## Check if string is YAML
64
- ##
65
- ## @example Check if a string is YAML
66
- ## "tags:\n - tag1\n - tag2".yaml?
67
- ## # => true
68
- ##
69
- ## @example Check if a string is not YAML
70
- ## "test string".yaml?
71
- ## # => false
72
- ##
73
- ## @return [Boolean]
74
- ##
75
- def yaml?
76
- begin
77
- YAML.load(self)
78
- rescue
79
- return false
80
- end
81
- true
82
- end
83
-
84
- ##
85
- ## Matches the string against a given keyword based on various options.
86
- ##
87
- ## @param keyword [String] the keyword to match against the string.
88
- ## @param options [Hash] a hash of options to customize the matching behavior.
89
- ## @option options [Boolean] :case_sensitive (false) whether the match should be case-sensitive.
90
- ## @option options [Boolean] :starts_with (false) whether the match should check if the string starts with the keyword.
91
- ## @option options [Boolean] :exact (false) whether the match should be exact.
92
- ## @option options [Boolean] :fuzzy (true) whether the match should be fuzzy.
93
- ## @option options [Integer] :distance (2) the maximum distance between characters for a fuzzy match.
94
- ##
95
- ## @return [Boolean] true if the string matches the keyword based on the given options, false otherwise.
96
- ##
97
- def match_keyword(keyword, options = {})
98
- options = {
99
- case_sensitive: false,
100
- starts_with: false,
101
- exact: false,
102
- fuzzy: false,
103
- contains: false,
104
- distance: 2,
105
- }.merge(options)
106
-
107
- keyword = Regexp.escape(keyword)
108
-
109
- if options[:exact]
110
- re = "^#{keyword}$"
111
- elsif options[:starts_with]
112
- re = "^#{keyword}"
113
- elsif options[:fuzzy]
114
- re = ".*#{keyword.split(//).join(".{,#{options[:distance] - 1}}")}.*"
115
- else
116
- re = ".*#{keyword}.*"
117
- end
118
-
119
- if options[:case_sensitive]
120
- self.match?(/#{re}/)
121
- else
122
- self.match?(/#{re}/i)
123
- end
124
- end
125
-
126
- ##
127
- ## Check if a string is JSON
128
- ##
129
- ## @example Check if a string is JSON
130
- ## '{"tags": ["tag1", "tag2"]}'.json?
131
- ## # => true
132
- ##
133
- ## @example Check if a string is not JSON
134
- ## "test string".json?
135
- ## # => false
136
- ##
137
- ## @return [Boolean]
138
- ##
139
- ## @note JSON must be a hash or array
140
- ##
141
- def json?
142
- begin
143
- JSON.parse(self).is_a?(Hash) || JSON.parse(self).is_a?(Array)
144
- rescue
145
- return false
146
- end
147
- true
148
- end
149
-
150
- ##
151
- ## Convert parenthetical count to hash
152
- ##
153
- ## @example Convert a string to a hash
154
- ## "tag (5)".to_count
155
- ## # => { "name" => "tag", "count" => 5 }
156
- ##
157
- ## @example Convert a string to a hash with no count
158
- ## "tag".to_count
159
- ## # => { "name" => "tag", "count" => 0 }
160
- ##
161
- ## @return [Hash] hash with name and count
162
- ##
163
- def to_count
164
- tag = dup.strip.sub(/^[[:punct:]] /, "")
165
- if tag =~ /(.*) \((\d+)\)/
166
- { "name" => $1, "count" => $2.to_i }
167
- else
168
- { "name" => tag, "count" => 0 }
169
- end
170
- end
171
-
172
- ##
173
- ## Check if a string is a list of tags
174
- ##
175
- ## @example Check if a string is a list of tags
176
- ## "tag1\ntag2".tag_list?
177
- ## # => true
178
- ##
179
- ## @return [Boolean]
180
- ##
181
- ## @note One tag per line
182
- ## Tags are assumed to be alphanumeric and lowercase
183
- ## (spaces, underscores, and dashes allowed) with no
184
- ## leading or preceding or trailing punctuation
185
- ##
186
- def tag_list?
187
- self.strip.split("\n").each do |tag|
188
- return false unless tag.match?(/^(?![[:punct:]] )[a-z0-9 -_]+(?<![[:punct:]]) *$/)
189
- end
190
- true
191
- end
192
-
193
- def root_words
194
- words = break_camel.split("[\s-]")
195
- words.delete_if { |word| word =~ /^[^a-z]+$/i || word.length < 4 }
196
- words.map { |word| word = Text::PorterStemming.stem(word).downcase }.join(" ")
197
- end
198
-
199
- # convert "WikiLink" to "Wiki link"
200
- def break_camel
201
- return downcase if match(/\A[A-Z]+\z/)
202
- gsub(/([A-Z]+)([A-Z][a-z])/, '\1 \2').
203
- gsub(/([a-z])([A-Z])/, '\1 \2').
204
- downcase
205
- end
1
+ # encoding: utf-8
2
+ class String
3
+ # convert "WikiLink" to "Wiki link"
4
+ def break_camel
5
+ return downcase if match(/\A[A-Z]+\z/)
6
+ gsub(/([A-Z]+)([A-Z][a-z])/, '\1 \2').
7
+ gsub(/([a-z])([A-Z])/, '\1 \2').
8
+ downcase
9
+ end
206
10
 
207
- def strip_markdown
208
- # strip all Markdown and Liquid tags
209
- gsub(/\{%.*?%\}/, "").
210
- gsub(/\[\^.+?\](\: .*?$)?/, "").
211
- gsub(/\s{0,2}\[.*?\]: .*?$/, "").
212
- gsub(/\!\[.*?\][\[\(].*?[\]\)]/, "").
213
- gsub(/\[(.*?)\][\[\(].*?[\]\)]/, "\\1").
214
- gsub(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/, "").
215
- gsub(/^\#{1,6}\s*/, "").
216
- gsub(/(\*{1,2})(\S.*?\S)\1/, "\\2").
217
- gsub(/(`{3,})(.*?)\1/m, "\\2").
218
- gsub(/^-{3,}\s*$/, "").
219
- gsub(/`(.+)`/, "\\1").
220
- gsub(/\n{2,}/, "\n\n")
221
- end
11
+ def strip_markdown
12
+ # strip all Markdown and Liquid tags
13
+ gsub(/\{%.*?%\}/,'').
14
+ gsub(/\[\^.+?\](\: .*?$)?/,'').
15
+ gsub(/\s{0,2}\[.*?\]: .*?$/,'').
16
+ gsub(/\!\[.*?\][\[\(].*?[\]\)]/,"").
17
+ gsub(/\[(.*?)\][\[\(].*?[\]\)]/,"\\1").
18
+ gsub(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/,'').
19
+ gsub(/^\#{1,6}\s*/,'').
20
+ gsub(/(\*{1,2})(\S.*?\S)\1/,"\\2").
21
+ gsub(/(`{3,})(.*?)\1/m,"\\2").
22
+ gsub(/^-{3,}\s*$/,"").
23
+ gsub(/`(.+)`/,"\\1").
24
+ gsub(/\n{2,}/,"\n\n")
25
+ end
222
26
 
223
- def strip_tags
224
- return CGI.unescapeHTML(
225
- gsub(/<(script|style|pre|code|figure).*?>.*?<\/\1>/im, "").
226
- gsub(/<!--.*?-->/m, "").
227
- gsub(/<(img|hr|br).*?>/i, " ").
228
- gsub(/<(dd|a|h\d|p|small|b|i|blockquote|li)( [^>]*?)?>(.*?)<\/\1>/i, " \\3 ").
229
- gsub(/<\/?(dt|a|ul|ol)( [^>]+)?>/i, " ").
230
- gsub(/<[^>]+?>/, "").
231
- gsub(/\[\d+\]/, "").
232
- gsub(/&#8217;/, "'").gsub(/&.*?;/, " ").gsub(/;/, " ")
233
- ).lstrip.gsub("\xE2\x80\x98", "'").gsub("\xE2\x80\x99", "'").gsub("\xCA\xBC", "'").gsub("\xE2\x80\x9C", '"').gsub("\xE2\x80\x9D", '"').gsub("\xCB\xAE", '"').squeeze(" ")
234
- end
27
+ def strip_tags
28
+ return CGI.unescapeHTML(
29
+ gsub(/<(script|style|pre|code|figure).*?>.*?<\/\1>/im, '').
30
+ gsub(/<!--.*?-->/m, '').
31
+ gsub(/<(img|hr|br).*?>/i, " ").
32
+ gsub(/<(dd|a|h\d|p|small|b|i|blockquote|li)( [^>]*?)?>(.*?)<\/\1>/i, " \\3 ").
33
+ gsub(/<\/?(dt|a|ul|ol)( [^>]+)?>/i, " ").
34
+ gsub(/<[^>]+?>/, '').
35
+ gsub(/\[\d+\]/, '').
36
+ gsub(/&#8217;/,"'").gsub(/&.*?;/,' ').gsub(/;/,' ')
37
+ ).lstrip.gsub("\xE2\x80\x98","'").gsub("\xE2\x80\x99","'").gsub("\xCA\xBC","'").gsub("\xE2\x80\x9C",'"').gsub("\xE2\x80\x9D",'"').gsub("\xCB\xAE",'"').squeeze(" ")
38
+ end
235
39
 
236
- def strip_urls
237
- gsub(/(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?/i, "")
238
- end
40
+ def strip_urls
41
+ gsub(/(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?/i,"")
42
+ end
239
43
 
240
- def strip_all
241
- strip_tags.strip_markdown.strip
242
- end
44
+ def strip_all
45
+ strip_tags.strip_markdown.strip
243
46
  end
47
+
244
48
  end
data/lib/jtag/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Jtag
2
- VERSION = "0.1.22"
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/jtag.rb CHANGED
@@ -1,19 +1,13 @@
1
- # frozen_string_literal: true
2
-
3
- require "net/http"
4
- require "cgi"
5
- require "fileutils"
6
- require "yaml"
7
- require "csv"
8
- require "json"
9
- require "plist"
10
- require "tmpdir"
11
- require "logger"
12
- require_relative "jtag/errors.rb"
13
- require_relative "jtag/array.rb"
14
- require_relative "jtag/hash.rb"
15
- require_relative "jtag/version.rb"
16
- require_relative "jtag/string.rb"
17
- require_relative "jtag/porter_stemming.rb"
18
- require_relative "jtag/jekylltag.rb"
19
- require_relative "jtag/util.rb"
1
+ require 'net/http'
2
+ require 'cgi'
3
+ require 'fileutils'
4
+ require 'yaml'
5
+ require 'csv'
6
+ require 'json'
7
+ require 'plist'
8
+ require 'jtag/version.rb'
9
+ require 'jtag/string.rb'
10
+ require 'jtag/porter_stemming.rb'
11
+ require 'jtag/jekylltag.rb'
12
+ require 'tmpdir'
13
+ require 'logger'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jtag
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.22
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-02-24 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake
@@ -55,14 +55,14 @@ dependencies:
55
55
  name: gli
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - '='
58
+ - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: 2.20.0
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - '='
65
+ - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: 2.20.0
68
68
  - !ruby/object:Gem::Dependency
@@ -93,6 +93,20 @@ dependencies:
93
93
  - - ">="
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: ostruct
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
96
110
  email: me@brettterpstra.com
97
111
  executables:
98
112
  - jtag
@@ -101,33 +115,18 @@ extra_rdoc_files:
101
115
  - README.rdoc
102
116
  - jtag.rdoc
103
117
  files:
104
- - ".irbrc"
105
- - CHANGELOG.md
106
- - Gemfile
107
- - Jekyll/plugins/autotag_gen.rb
108
- - Jekyll/source/_layouts/tags_json.html
109
- - README.md
110
118
  - README.rdoc
111
- - Rakefile
112
119
  - bin/jtag
113
- - jtag.completion.bash
114
- - jtag.gemspec
115
120
  - jtag.rdoc
116
121
  - lib/jtag.rb
117
- - lib/jtag/array.rb
118
122
  - lib/jtag/config_files/blacklist.txt
119
123
  - lib/jtag/config_files/config.yml
120
124
  - lib/jtag/config_files/stopwords.txt
121
125
  - lib/jtag/config_files/synonyms.yml
122
- - lib/jtag/errors.rb
123
- - lib/jtag/hash.rb
124
126
  - lib/jtag/jekylltag.rb
125
127
  - lib/jtag/porter_stemming.rb
126
128
  - lib/jtag/string.rb
127
- - lib/jtag/stupid_json.rb
128
- - lib/jtag/util.rb
129
129
  - lib/jtag/version.rb
130
- - mise.toml
131
130
  homepage: http://brettterpstra.com
132
131
  licenses: []
133
132
  metadata: {}
@@ -150,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
149
  - !ruby/object:Gem::Version
151
150
  version: '0'
152
151
  requirements: []
153
- rubygems_version: 3.6.4
152
+ rubygems_version: 3.6.7
154
153
  specification_version: 4
155
154
  summary: Auto-tagging and tagging tools for Jekyll
156
155
  test_files: []
data/.irbrc DELETED
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
- `gem rdoc binbundle --ri`
3
-
4
- # rubocop:disable Style/MixinUsage
5
- include JekyllTag # standard:disable all
6
- # rubocop:enable Style/MixinUsage
data/CHANGELOG.md DELETED
@@ -1,15 +0,0 @@
1
- ### 0.1.19
2
-
3
- 2024-09-16 13:15
4
-
5
- #### NEW
6
-
7
- - Allows piping of file lists. For actions to which it applies, you can pipe a file list, either from a previous jtag command or from another source (newline separated) to act on only those files, e.g. `jtag posts_tagged keyboard | jtag tags`
8
-
9
- #### FIXED
10
-
11
- - File.exists? => File.exist? for Ruby 3
12
-
13
- ### 1.0
14
-
15
- Initial release
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source 'https://rubygems.org'
2
- gemspec
3
-
@@ -1,58 +0,0 @@
1
- #
2
- # Author: Brett Terpstra
3
- # Page generator for /data/tags.json, a list of all the tags on your blog and a list of the top 50 tags.
4
- # Part of the AutoTag tool for Jekyll, but usable in other applications
5
- #
6
- # Looks for a tags_json.html template in your _layouts folder, see the example provided.
7
- # Provides page.json_tags and page.json_tags_count as arrays for looping
8
- #
9
- # Config options for _config.yml
10
- # tag_excludes: array of tags to exclude from all listings
11
- # tags_json_dir: alternate of folder for the data.json file. Set to blank for root, defaults to 'data'
12
- #
13
- # If using tags.json with a javascript application, be sure you have the proper headers defined in .htaccess:
14
- # AddType application/json json
15
- # ExpiresByType application/json "access plus 0 seconds"
16
-
17
- require 'json'
18
-
19
- module Jekyll
20
-
21
- class AutoTag < Page
22
- def initialize(site, base, dir)
23
- @site = site
24
- @base = base
25
- @dir = dir
26
- @name = 'tags.json'
27
- self.process(@name)
28
- self.read_yaml(File.join(base, '_layouts'), 'tags_json.html')
29
- tags_with_counts = site.tags.delete_if {|k,v|
30
- site.config['tag_excludes'].include?(k) unless site.config['tag_excludes'].nil?
31
- }.sort_by { |k,v| v.count }.reverse
32
-
33
- self.data['json_tags'] = tags_with_counts.sort {|a,b| a[0].downcase <=> b[0].downcase }.map {|k,v| k }
34
- self.data['json_tags_count'] = []
35
- tags_with_counts.each { |k,v|
36
- self.data['json_tags_count'] << {
37
- "name" => k,
38
- "count" => v.count
39
- }
40
- }
41
- end
42
- end
43
- class AutoTagGenerator < Generator
44
- safe true
45
- def generate(site)
46
- if site.layouts.key? 'tags_json'
47
- dir = site.config['tag_json_dir'] || 'data'
48
- write_tag_json(site, dir)
49
- end
50
- end
51
- def write_tag_json(site, dir)
52
- index = AutoTag.new(site, site.source, dir)
53
- index.render(site.layouts, site.site_payload)
54
- index.write(site.dest)
55
- site.pages << index
56
- end
57
- end
58
- end
@@ -1,11 +0,0 @@
1
- ---
2
- layout: nil
3
- ---
4
- {
5
- "tags_count": [{% for tag in page.json_tags_count %}
6
- {"name":"{{tag.name}}","count":{{tag.count}}},{% endfor %}
7
- false],
8
- "tags": [{% for tag in page.json_tags %}
9
- "{{tag}}",{% endfor %}
10
- false]
11
- }