casetdown 0.9.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.
@@ -0,0 +1,180 @@
1
+ #coding:utf-8
2
+
3
+ module TextAbstract
4
+
5
+ module Type
6
+ def int radix=10
7
+ self.to_i(radix)
8
+ end
9
+
10
+ def float tail=2
11
+ self.to_f.round(tail)
12
+ end
13
+
14
+ def precent tail=2
15
+ (self.to_f*100).round(tail).to_s+"%"
16
+ end
17
+
18
+ def text format=:raw
19
+ return self if format==:raw
20
+ return self.to_json if format==:meta
21
+ end
22
+
23
+ def bool
24
+ return true if self.downcase=='true'
25
+ return false if self.downcase=='false'
26
+ return self.empty?
27
+ end
28
+ end
29
+
30
+ module TextOperator
31
+ def head? prefix, strip=false #=> bool
32
+ left = strip ? self.strip : self
33
+ left[0..(prefix.length-1)]==prefix
34
+ end
35
+
36
+ def tail? postfix, strip=false #=> bool
37
+ left = strip ? self.strip : self
38
+ left[(-1*postfix.length)..-1]==postfix
39
+ end
40
+
41
+ # def include? text #=> bool
42
+
43
+ # def empty? #=> bool
44
+
45
+ def matches pattern, mode=:one #=> match
46
+ return self.match(Regexp.new pattern) if mode==:one
47
+ return self.scan(Regexp.new pattern) if mode==:all
48
+ return self.scan(Regexp.union *pattern.map{|pat|Regexp.new(pat)}) if mode==:union
49
+ end
50
+
51
+ def draw_lines preflag, postflag #=> text, list
52
+ restext, contexts = TextAbstract.draw_fragments self, preflag, postflag
53
+ end
54
+
55
+ def match_paragraph start, finish #=> list
56
+ paragraphs = TextAbstract.match_paragraph self, start, finish
57
+ end
58
+
59
+ def match_cascade start, finish #=> list
60
+ paragraphs = TextAbstract.match_cascade self, start, finish
61
+ end
62
+
63
+ def match_xml tag #=> tree
64
+ document = TextAbstract.match_html_tag self,tag
65
+ end
66
+
67
+ # def length #=> int
68
+ # def size #=> int
69
+
70
+ # def strip #=> text
71
+ # def lstrip #=> text
72
+ # def rstrip #=> text
73
+
74
+ def join *texts #=> text
75
+ self+texts.map{|t|t}.join
76
+ end
77
+
78
+ def cut index1, index2=0 #=> text
79
+ self[(index1-1)..(index2-1)]
80
+ end
81
+
82
+ # def + text #=> concat text
83
+
84
+ # def * text #=> repeat text
85
+
86
+ def - text #=> text
87
+ self.include?(text) ? self.split(text).first : self
88
+ end
89
+
90
+ def / text #=> list
91
+ self.split(text)
92
+ end
93
+
94
+ def exchange text, newtext, num=:all #=> text
95
+ num = 65535 if num==:all
96
+ count = 0
97
+ self.gsub(Regexp.new(text)) do |match|
98
+ count += 1
99
+ count <= num ? newtext : text
100
+ end
101
+ end
102
+ end
103
+
104
+ module ListOperator
105
+ # def pop #=> item
106
+ # def push text #=> list
107
+ # def shift #=> item
108
+ # def unshift text #=> list
109
+
110
+ # def + list #=> list
111
+ # def - list #=> list
112
+
113
+ def catch *list #=> list(list)
114
+ list.unshift(self)
115
+ end
116
+
117
+ # def find &block #=> item
118
+ # def select &block #=> list
119
+ # def filter &block #=> list
120
+ def match num=1, &block #=> bool | item | list
121
+ return self.find(&block).nil? if num ==0
122
+ return self.find(&block) if num ==1
123
+ return self.select(&block) if num ==:all
124
+ return self.select(&block)[0..(num-1)] if num > 1
125
+ end
126
+
127
+ def sub index1, index2=0 #=> list
128
+ self[(index1-1)..(index2-1)]
129
+ end
130
+
131
+ # def map &block #=> list
132
+ # def collect &block #=> list
133
+
134
+ # def reduce(c) &block #=> item
135
+ # def inject(c) &block #=> item
136
+ # def join text #=> concat item ※ join(c) == reduce{|a,b|a+c+b}
137
+ end
138
+
139
+ module TreeOperator
140
+ # def keys #=> list
141
+ # def values #=> list
142
+
143
+ # def [] key #=> item
144
+ def get key #=> item
145
+ self[key]
146
+ end
147
+
148
+ # def []= key, value #=> item
149
+ def set key, value #=> item
150
+ self[key] = value
151
+ end
152
+
153
+ def + oprand #=> tree
154
+ index = self.keys.filter{|k|k.instance_of?(Integer)}.max
155
+ index = index ? index+1 : 0
156
+ if oprand.instance_of?(Hash)
157
+ self.merge(oprand)
158
+ elsif oprand.instance_of?(Array)
159
+ self.merge oprand.reduce({}){|tr,op|index+=1;tr.merge({(index-1)=>op})}
160
+ else
161
+ self.merge({index=>oprand})
162
+ end
163
+ end
164
+ end
165
+
166
+ end
167
+
168
+ class String
169
+ include TextAbstract::Type
170
+ include TextAbstract::TextOperator
171
+ end
172
+
173
+ class Array
174
+ include TextAbstract::ListOperator
175
+ end
176
+
177
+ class Hash
178
+ include TextAbstract::TreeOperator
179
+ end
180
+
data/TinText/cache.rb ADDED
@@ -0,0 +1,24 @@
1
+ #coding:utf-8
2
+
3
+ # a light cache
4
+ module Replacement
5
+ def self.init
6
+ @dictionary = {}
7
+ end
8
+
9
+ def self.reset
10
+ init
11
+ end
12
+
13
+ def self.[] index
14
+ @dictionary[index]
15
+ end
16
+
17
+ def self.[]= index,replacement
18
+ @dictionary[index]= replacement
19
+ end
20
+
21
+ def self.merge hash
22
+ @dictionary.merge! hash
23
+ end
24
+ end
@@ -0,0 +1,44 @@
1
+ #coding:utf-8
2
+ require 'erb'
3
+
4
+ module TinText
5
+ def self.translate word
6
+ unless Replacement[word]==nil
7
+ return Replacement[word]
8
+ else
9
+ return "((#{word}))"
10
+ end
11
+ end
12
+
13
+ def self.unfolder raw
14
+ # <<..>> => <%=..%>
15
+ # {{..}} => <%..%>
16
+ # [[..\n....]] => <%..%>..<%..%>
17
+ raw.gsub(/\<\<\s*(.+?)\s*\>\>/,"<%=\\1%>")
18
+ .gsub(/\{\{\s*(.+?)\s*\}\}/,"<%\\1%>")
19
+ .gsub(/\{\{\s*(.+?)\s*/,"<%\\1").gsub(/\s*\}\}/,"\\1%>")
20
+ .gsub(/\[\[\s*(.+?)\s*\n/,"<%\\1%>").gsub(/\]\]/,"<%end%>")
21
+ end
22
+
23
+ def self.template raw
24
+ # ${..} ((...)) => <%=...%>
25
+ raw.gsub(/\(\(\s*(.+?)\s*\)\)/,"<%=TinText::translate('\\1')%>").gsub(/\$\{\s*(.+?)\s*\}/,"<%=TinText::translate('\\1')%>")
26
+ end
27
+
28
+ def self.instance raw,tag=:pre
29
+ if tag==:pre
30
+ a = self.template raw
31
+ b = ERB.new(a).result
32
+ c = self.unfolder b
33
+ ERB.new(c).result
34
+ else # :post
35
+ a = self.unfolder raw
36
+ b = ERB.new(a).result
37
+ c = self.template b
38
+ ERB.new(c).result
39
+ end
40
+ end
41
+
42
+ def self.tt raw;self.template raw;end
43
+ def self.ti fla;self.instance fla;end
44
+ end
@@ -0,0 +1,4 @@
1
+ #coding:utf-8
2
+ [
3
+ 'TinText/tum', 'TinText/cache', 'TinText/tin_text'
4
+ ].each{|lib|require lib}
data/TinText/tum.rb ADDED
@@ -0,0 +1,13 @@
1
+ #coding:utf-8
2
+
3
+ # Tum = Text Unfold Method
4
+ module Tum
5
+ def self.repeat statement, times
6
+ Array.new(times,statement).join("\n")
7
+ end
8
+
9
+ # statement = '... @var ...', var in range
10
+ def self.iterate statement, range
11
+ range.collect{|item| statement.gsub("@var",item.to_s) }.join("\n")
12
+ end
13
+ end
@@ -0,0 +1,207 @@
1
+ #coding:utf-8
2
+ # REPLICA FROM IMDOC/XMLUTILS
3
+ %w{rexml/parsers/sax2parser rexml/sax2listener rexml/document json yaml}.each{|mod|require mod}
4
+
5
+ class XmlNode
6
+ attr_accessor :name, :attributes, :elements, :parent, :next, :prev
7
+
8
+ def initialize(option = {})
9
+ args = {parent: nil, attributes: {}, elements: [], prev: [], next: []}.merge(option)
10
+ @name = args[:name] || "OID:#{self.object_id}"
11
+ @attributes = args[:attributes]
12
+ @parent, @elements, @prev, @next = args[:parent], args[:elements], args[:prev], args[:next]
13
+
14
+ if @parent
15
+ @prev << @parent unless @prev.include?(@parent)
16
+ @parent.elements << self unless @parent.elements.include?(self)
17
+ @parent.next << self unless @parent.next.include?(self)
18
+ end
19
+ end
20
+
21
+ #####################################################################################################
22
+ # format #
23
+ #####################################################################################################
24
+
25
+ # 三元组 ([name, attributes, [name, attributes, ...]])
26
+ def to_triad
27
+ attrs,elems = {},[]
28
+ @attributes.each do|k,v|
29
+ unless k == :text
30
+ attrs[k] = v
31
+ else
32
+ elems += [v].flatten
33
+ end
34
+ end
35
+ elems += @elements.map{|c|c.to_triad}
36
+ [@name, attrs, elems]
37
+ end
38
+ alias :to_a :to_triad
39
+
40
+ # 文档化 ({name: [attributes, {name: [...]}]})
41
+ def to_doc
42
+ doc = {}
43
+ doc[@name] = []
44
+ doc[@name] << @attributes #@attributes.each{|k,v|doc[@name] << {k=> v}}
45
+ @elements.each{|e|doc[@name] << e.to_doc}
46
+ return doc
47
+ end
48
+
49
+ # 对象化 (like js: {obj: {'-attr': val, '#text': text, obj: {...}}})
50
+ def to_obj
51
+ doc = {}
52
+ @attributes.each do|k,v|
53
+ h = k==:text ? '#' : '-'
54
+ doc["#{h}#{k}"] = v
55
+ end
56
+ @elements.each do|elem|
57
+ doc.merge! elem.to_obj
58
+ end
59
+ return {@name => doc}
60
+ end
61
+
62
+ # XML
63
+ def to_xml
64
+ attrs, content = '', ''
65
+ @attributes.each do |k,v|
66
+ if k == :text
67
+ content += "#{[v].flatten.join("\n")}"
68
+ elsif k == :namespace && !v
69
+ next
70
+ else
71
+ attrs += " #{k}=\"#{v}\""
72
+ end
73
+ end
74
+ return "<#{@name}#{attrs}/>" if @elements.size==0 && !@attributes[:text]
75
+ @elements.each do|e|
76
+ content += if e.is_a?(XmlNode)
77
+ e.to_xml
78
+ elsif e.instance_of?(String)
79
+ "#{e}"
80
+ end
81
+ end
82
+ return "<#{@name}#{attrs}>#{content}</#{@name}>"
83
+ end
84
+
85
+ def pretty format, method, indent=2
86
+ case method
87
+ when :xml
88
+ pretty_xml = ""
89
+ REXML::Document.new(self.send(format), { :raw => :all }).write(pretty_xml, indent)
90
+ return pretty_xml
91
+ when :json
92
+ return JSON.pretty_generate(self.send(format))
93
+ end
94
+ end
95
+
96
+ def self.make_str_from xml
97
+ text = xml
98
+ ['&lt;','&gt;','&amp;','&apos;','&quot;'].zip(["<",">","&",%{'},%{"}]) do|xstr,str| text.gsub!(xstr,str) end
99
+ return text
100
+ end
101
+
102
+ def self.make_xml_from string
103
+ xml = string
104
+ # 注意:'&'要最先被替换
105
+ ['&','<','>',%{'},%{"}].zip(['&amp;','&lt;','&gt;','&apos;','&quot;']) do|str,xstr| xml.gsub!(str,xstr) end
106
+ return xml
107
+ end
108
+
109
+ #####################################################################################################
110
+ # attributes operation #
111
+ #####################################################################################################
112
+
113
+ def add_attributes hash
114
+ (@attributes[:text] ||= []) << hash[:text] if hash[:text]# 文本的特殊处理
115
+ hash.delete(:text)
116
+ @attributes.merge!(hash)
117
+ end
118
+
119
+ def modify_attributes hash
120
+ add_attributes hash
121
+ end
122
+
123
+ def delete_attribute key
124
+ @attributes.delete(key) unless key==:text # 元素的内容不删除
125
+ end
126
+
127
+ #####################################################################################################
128
+ # content operation #
129
+ #####################################################################################################
130
+
131
+ def add_content content
132
+ #@attributes[:text] += content
133
+ @elements << content
134
+ end
135
+
136
+ def modify_content content
137
+ @attributes[:text] = []
138
+ @elements.delete_if{|e|e.is_a?(String)}
139
+ @elements << content
140
+ end
141
+
142
+ def delete_content
143
+ #@attributes.delete(:text)
144
+ @elements = @elements.find_all{|c|!c.instance_of?(XmlNode)}
145
+ end
146
+
147
+ def add_element elem
148
+ if elem.is_a?(XmlNode)
149
+ @elements << elem unless @elements.include?(elem)
150
+ @next << elem unless @next.include?(elem)
151
+ elem.parent = self
152
+ elem.prev << self unless elem.prev.include?(self)
153
+ end
154
+ end
155
+
156
+ def search_elements &block
157
+ return ( block ? @elements.find_all(&block) : [] )
158
+ end
159
+
160
+ def delete_elements &block
161
+ elems = search_elements(&block) if block
162
+ elems.each{|elem|@elements.delete(elem)}
163
+ return elems
164
+ end
165
+
166
+ # [???] I dont know what happen
167
+ def self.copy node
168
+ duplicate=XmlNode.new(name: node.name, parent: nil, attributes: node.attributes)
169
+ node.elements.map{|subnode|self.copy(subnode)}.each do|subnode|
170
+ duplicate.add_element subnode
171
+ end
172
+ return duplicate
173
+ end
174
+ end
175
+
176
+
177
+ module XmlParser
178
+ def self.load(filepath)
179
+ return File.exist?(filepath) ? XmlParser.parse(open(filepath){|f| f.read}) : nil
180
+ end
181
+
182
+ def self.parse(s)
183
+ parser = REXML::Parsers::SAX2Parser.new(s)
184
+ root,current = nil,nil
185
+
186
+ parser.listen(:start_element) do |url, local, qname, attributes|
187
+ current = XmlNode.new(parent: current, name: local, attributes: attributes)
188
+ current.attributes[:namespace]=url
189
+ root ||= current
190
+ end
191
+
192
+ parser.listen(:end_element) do |url, local, qname, attributes|
193
+ current = current.parent
194
+ end
195
+
196
+ parser.listen(:characters) do |text|
197
+ t = text.strip
198
+ if t.size > 0
199
+ current.attributes[:text] ||=""
200
+ current.attributes[:text] += t
201
+ end
202
+ end
203
+
204
+ parser.parse
205
+ return root
206
+ end
207
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: casetdown
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ platform: ruby
6
+ authors:
7
+ - Matt
8
+ bindir: CasetDown/bin
9
+ cert_chain: []
10
+ date: 2025-03-13 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: casetdown is a test tool of markdown document
13
+ email:
14
+ - matthrewchains@gmail.com
15
+ executables:
16
+ - cm
17
+ - cml
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - CasetDown/bin/cm
22
+ - CasetDown/bin/cml
23
+ - CasetDown/casetable.rb
24
+ - CasetDown/casetcode.rb
25
+ - CasetDown/casetdoc.rb
26
+ - CasetDown/casetdown.rb
27
+ - CasetDown/casetter.rb
28
+ - EnData/api-app.rb
29
+ - EnData/endata-app.rb
30
+ - EnData/endata.rb
31
+ - Tabot/newtab.rb
32
+ - Tabot/simtab.rb
33
+ - TextUtils/text_absparser.rb
34
+ - TextUtils/text_abstract.rb
35
+ - TextUtils/text_mind.rb
36
+ - TinText/cache.rb
37
+ - TinText/tin_text.rb
38
+ - TinText/tintext.rb
39
+ - TinText/tum.rb
40
+ - XMLUtils/XmlUtils.rb
41
+ homepage: http://127.0.0.1
42
+ licenses: []
43
+ metadata: {}
44
+ rdoc_options: []
45
+ require_paths:
46
+ - "."
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubygems_version: 3.6.5
59
+ specification_version: 4
60
+ summary: test-tool
61
+ test_files: []