plain_text 0.7.1 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 45fae90fbac6ba53a5f7c21d6a21b3f858d3db734d770eec82fdbb9838755b11
4
- data.tar.gz: 2817d7be2e4e7a3029d00922177c881ae4cdad2c940bb764f8f49cd6c1b08e00
3
+ metadata.gz: a03c794c7f63a55e51e3f57aeb9345dbb2e60c416525f1649037429539f33697
4
+ data.tar.gz: b7c80770207ca932edbf9af2fce56586b56271aad5813f2a8c63761a070257f0
5
5
  SHA512:
6
- metadata.gz: 5443ef391054d08a06f3cef5a67316b0f13ddbf2f60f7689eb51f027aa73804e09418d0e021446cc32f90111047f36a862278a62b92017000055658756fb4759
7
- data.tar.gz: 0b158d573ba75b957a0c063aace1bad6c378a23e3e8cd97afe2af6cbd71e79bf26cdd32cce748c0fefd24f61cd6d9053380178889c3c30673219d1bcb13b8809
6
+ metadata.gz: '080c21444032d57f10d5c62b75be779c915ec110f8902033c5abc46d6b4f668deee9da6f857ea0b75a0a8742be246830af16fc49cbe9045d610434f75d6993d5'
7
+ data.tar.gz: 75ad795005fcb38417130e4e06948eea36fa68525b50c623efda994d081085b0b70623d6812f81dc5c54d35b86e75647ae63818335edbeae28a576e6134889c6
data/.gitignore CHANGED
@@ -36,6 +36,7 @@
36
36
  *.elc
37
37
  *.pyc
38
38
  \#*\#
39
+ .#*[a-zA-Z]*
39
40
 
40
41
  # Elastic Beanstalk Files
41
42
  .elasticbeanstalk/*
data/ChangeLog CHANGED
@@ -1,3 +1,14 @@
1
+ -----
2
+ (Version: 0.8)
3
+ 2022-09-14 Masa Sakano
4
+ * Major upgrade where parent classes changed from Array/String to Object.
5
+
6
+ * Changed the parent classes for Part/Paragraph/Boundary from Array/String to Object.
7
+ * `PlainText::BuiltinType` introduced to contain common methods.
8
+ * `PlainText::Part::StringType` introduced for Paragraph/Boundary, to which many methods in the classes were transferred.
9
+ * Custom Exception is added: `lib/plain_text/error.rb`
10
+ * Some changes in detailed (minor) specifications.
11
+
1
12
  -----
2
13
  (Version: 0.7.1)
3
14
  2022-09-09 Masa Sakano
data/Makefile CHANGED
@@ -20,5 +20,6 @@ test:
20
20
 
21
21
  ## yard2md_afterclean in Gem plain_text https://rubygems.org/gems/plain_text
22
22
  doc:
23
- yard doc; [[ -x ".github" && ( "README.en.rdoc" -nt ".github/README.md" ) ]] && ( ruby -r rdoc -e 'puts RDoc::Markup::ToMarkdown.new.convert ARGF.read' < README.en.rdoc | yard2md_afterclean | ruby -e 'puts ARGF.read.sub(/(```)ruby(\nPart )/){$$1+"text"+$$2}' > .github/.README.md && mv .github/.README.md .github/README.md && echo ".github/README.md is updated." ) || exit 0
23
+ yard doc; [[ -x ".github" && ( "README.en.rdoc" -nt ".github/README.md" ) ]] && ( ruby -r rdoc -e 'puts RDoc::Markup::ToMarkdown.new.convert ARGF.read' < README.en.rdoc | yard2md_afterclean > .github/README.md.$$ && ( mv -f .github/README.md.$$ .github/README.md && echo ".github/README.md and .github/README.html are updated." && pandoc --from=gfm .github/README.md -o .github/README.html ) || ( echo "ERROR: failed to create .github/README.md" >&2 ) ) || exit 0
24
+ ## --privat does not show private methods??
24
25
 
data/README.en.rdoc CHANGED
@@ -5,99 +5,99 @@
5
5
 
6
6
  This module provides utility functions and methods to handle plain
7
7
  text. In the namespace, classes Part/Paragraph/Boundary are defined,
8
- which represent the logical structure of a document and another class
8
+ which represent the logical structure of a document, and another class
9
9
  ParseRule, which describes the rules to parse plain text to produce a Part-type Ruby instance.
10
- This package also provides a few command-line programs, such as counting the number
11
- of characters (especially useful for documents in Asian (CJK)
10
+ This package also contains a few command-line programs, such as counting the number
11
+ of characters (which is especially useful for text in Asian (CJK)
12
12
  characters) and advanced head/tail commands.
13
13
 
14
14
  The master of this README file, as well as the document for all the methods, is found in
15
- {RubyGems/plain_text}[https://rubygems.org/gems/plain_text]
16
- and in {Github}[https://github.com/masasakano/plain_text]
15
+ {RubyGems/plain_text}[https://rubygems.org/gems/plain_text],
16
+ as well as in {Github}[https://github.com/masasakano/plain_text],
17
17
  where all the hyperlinks are active.
18
18
 
19
19
  == Design concept
20
20
 
21
21
  === PlainText - Module and root Namespace
22
22
 
23
- The original plain text should be in String in Ruby.
23
+ The original plain text should be String in Ruby.
24
24
 
25
- The module {PlainText} offers some useful methods, such as,
26
- {PlainText#head} and {PlainText#tail}. They are meant to be included
27
- in String. However, it also contains some useful module functions,
25
+ The module {PlainText} provides some useful methods, such as,
26
+ {PlainText#head} and {PlainText#tail}, which are meant to be included
27
+ in String. The module also contains some useful module functions,
28
28
  such as, {PlainText.clean_text} and {PlainText.count_char}.
29
29
 
30
30
  === PlainText::Part - Core class to describe the logical structure
31
31
 
32
- In the namespace of this module, it contains {PlainText::Part} class,
33
- which is the heart to describe the logical structure of a document.
34
- It is basically a container class and indeed a sub-class of Array. It
35
- can contain either of other (multiple) {PlainText::Part} or more basic
36
- components of either of {PlainText::Part::Paragraph} and
37
- {PlainText::Part::Boundary}, both of which are sub-classes of String.
32
+ The {PlainText::Part} class in the namespace of this module
33
+ is the core class to describe the logical structure of a plain-text document.
34
+ It is basically a container class and behaves like Array (it has been a
35
+ subclass of Array up to Version 0.7). It
36
+ contains one or more components of other {PlainText::Part} and
37
+ {PlainText::Part::Paragraph}, each of which is always followed by
38
+ a single {PlainText::Part::Boundary}.
39
+ Both {PlainText::Part::Paragraph} and {PlainText::Part::Boundary}
40
+ behave like String (they used to be subclasses of String up to Version 0.7).
38
41
 
39
42
  An example instance looks like this:
40
43
 
41
44
  Part (
42
- (0) Paragraph::Empty,
43
- (1) Boundary::General,
45
+ (0) Part::Paragraph::Empty,
46
+ (1) Part::Boundary::General,
44
47
  (2) Part::ArticleHeader(
45
- (0) Paragraph::Title,
46
- (1) Boundary::Empty
48
+ (0) Part::Paragraph::Title,
49
+ (1) Part::Boundary::Empty
47
50
  ),
48
- (3) Boundary::TitleMain,
51
+ (3) Part::Boundary::TitleMain,
49
52
  (4) Part::ArticleMain(
50
53
  (0) Part::ArticleSection(
51
- (0) Paragraph::Title,
52
- (1) Boundary::General,
53
- (2) Paragraph::General,
54
- (3) Boundary::General,
54
+ (0) Part::Paragraph::Title,
55
+ (1) Part::Boundary::General,
56
+ (2) Part::Paragraph::General,
57
+ (3) Part::Boundary::General,
55
58
  (4) Part::ArticleSubSection(...),
56
- (5) Boundary::General,
57
- (6) Paragraph::General,
58
- (7) Boundary::Empty
59
+ (5) Part::Boundary::General,
60
+ (6) Part::Paragraph::General,
61
+ (7) Part::Boundary::Empty
59
62
  ),
60
- (1) Boundary::General,
61
- (2) Paragraph::General,
62
- (3) Boundary::Empty
63
+ (1) Part::Boundary::General,
64
+ (2) Part::Paragraph::General,
65
+ (3) Part::Boundary::Empty
63
66
  ),
64
- (5) Boundary::General
67
+ (5) Part::Boundary::General
65
68
  )
66
69
 
67
- where the names of the subclasses (or constants) here are arbitrary, except for
70
+ where the names of the subclasses are arbitrary, except for
68
71
  {PlainText::Part::Paragraph::Empty} and
69
72
  {PlainText::Part::Boundary::Empty}, which are pre-defined. Users can
70
73
  define their own subclasses to help organize the logical structure at
71
74
  their will.
72
75
 
73
- Basically, at every layer, every {PlainText::Part} or
74
- {PlainText::Part::Paragraph} is sandwiched by
75
- {PlainText::Part::Boundary}, except for the very first one.
76
- The former contains something significant on its own, whereas the
77
- latter (Boundary) contains nothing significant on its own, except they
78
- may indicate the type of the following (or preceding) entity, such as
79
- a title or section.
76
+ {PlainText::Part} and {PlainText::Part::Paragraph} are supposed to contain something significant on its own, whereas
77
+ {PlainText::Part::Boundary} contains a kind of separators, such as
78
+ closing parentheses, spaces, newlines, and alike.
80
79
 
81
80
  In this library (document, classes and modules), the former and latter
82
81
  are collectively referred to as Para (or Paras) and Boundary (or
83
82
  Boundaries), respectively. Namely, a Para means either of
84
83
  {PlainText::Part} and {PlainText::Part::Paragraph}.
85
84
 
86
- By performing +Part#join+ method, one can retrieve the entire document as a
87
- String instance any time, just like +Array#join+.
85
+ +Part#join+ method returns the entire plain-text document as a
86
+ String instance, just like +Array#join+.
88
87
 
89
88
  === PlainText::ParseRule - Class to describe the rule of how to parse
90
89
 
91
90
  {PlainText::ParseRule} is the class to describe how to parse initially
92
91
  String, and subsequently {PlainText::Part}, which is basically an Array.
93
92
  {PlainText::ParseRule} is a container class and holds a set of ordered
94
- rules, each of which is either Proc or Regexp as a more simple rule.
95
- A rule, Proc, is defined by a user and is designed to receive either
93
+ rules, each of which is either Proc or Regexp.
94
+
95
+ A rule of Proc is defined by a user and is designed to receive either
96
96
  String (the first application only) or {PlainText::ParseRule} (Array)
97
97
  and to return a fully (or partially) parsed {PlainText::ParseRule}.
98
98
  In short, the rule descries how to determine from where to where a
99
99
  Paras and Boundaries are located — for example, what and where the
100
- sections and sub-sections are and so on are.
100
+ sections and sub-sections and so on are.
101
101
 
102
102
  For example, if a rule is Regexp, it describes how to split a String;
103
103
  it is applied to String in the first application, but if it is
@@ -106,7 +106,7 @@ it is applied to each Para separately to split them further.
106
106
 
107
107
  {PlainText::ParseRule#apply} and {PlainText::Part.parse} are the
108
108
  standard methods to apply the rules to an object (either String or
109
- {PlainText::Part}.
109
+ {PlainText::Part}).
110
110
 
111
111
  == Command-line tools
112
112
 
@@ -195,7 +195,7 @@ still not perfect but does some good automation job.
195
195
 
196
196
  Module {PlainText::Split} contains an instance method (and class
197
197
  method with the same name) {PlainText::Split#split_with_delimiter},
198
- which is included in String in default. The method realises a
198
+ which is included in String in default. The method realizes a
199
199
  reversible split of String with a delimiter of an arbitrary Regexp.
200
200
 
201
201
  In the standard String#split, the following is the result, when
@@ -221,27 +221,33 @@ Work in progress...
221
221
 
222
222
  == Install
223
223
 
224
- This script requires {Ruby}[http://www.ruby-lang.org] Version 2.0
225
- or above (possibly 2.2 or above?).
224
+ The easiest way to install this library is simply
225
+
226
+ gem install plain_text
227
+
228
+ The library files should be installed in one of your
229
+ <tt>$LOAD_PATH</tt> and also all the executables (commands) should be
230
+ installed in one of your command-line search paths.
231
+
232
+ Alternatively, get it from
233
+ {http://rubygems.org/gems/plain_text},
234
+ making sure the library path and command-line search path are set appropriately.
226
235
 
227
- For use of the library, if your Ruby script declares
236
+ Then all you need to do is
228
237
 
229
238
  require "plain_text"
230
239
 
231
- all the related libraries should be read.
232
- If you +include PlainText+ from String, it would be handy, though
233
- not mandatory to use this library.
240
+ in your Ruby script (or irb).
234
241
 
235
- As for the command-line script files, they can be put in any of your command-line search
236
- paths. Make sure the RUBYLIB environment
237
- variable contains the library directory to this gem, which is
242
+ This script requires {Ruby}[http://www.ruby-lang.org] Version 2.0
243
+ or above (possibly 2.2 or above?).
238
244
 
239
- /THIS/GEM/LIBRARY/PATH/plain_text/lib
245
+ If you +include PlainText+ from String, it would be handy, though
246
+ not mandatory to use this library.
240
247
 
241
- (which should be set automatically, as long as you use the standard Gem environment).
242
- You may need to modify the first line (Shebang line) of the script to suit your
243
- environment (it should be unnecessary for Linux and MacOS), or run it
244
- explicitly with your Ruby command as
248
+ As for the shell-executables, you might need to modify the first line (Shebang line) of the scripts to suit your
249
+ environment (it should be unnecessary for Linux and MacOS), or run them
250
+ explicitly with your Ruby command, such as
245
251
 
246
252
  % /YOUR/ENV/ruby /YOUR/INSTALLED/countchar
247
253
 
@@ -257,7 +263,7 @@ interface for annotation but with easily-browsable {ChangeLog}[https://github.co
257
263
 
258
264
  === Tests
259
265
 
260
- Ruby codes under the directory <tt>test/</tt> are the test scripts.
266
+ The test suite is located under the directory <tt>test/</tt>.
261
267
  You can run them from the top directory as <tt>ruby test/test_****.rb</tt>
262
268
  or simply run <tt>make test</tt>.
263
269
 
@@ -0,0 +1,64 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module PlainText
4
+
5
+ # Contains common methods for builtin-class emulating classes
6
+ #
7
+ # The class that includes this module should have a method +instance+
8
+ # that returns the main instance of the builtin-class instance;
9
+ # e.g., +instance+ may be equivalent to +to_s+, +to_a+, and alike.
10
+ #
11
+ # @author Masa Sakano (Wise Babel Ltd)
12
+ #
13
+ module BuiltinType
14
+ # Subclass name only
15
+ #
16
+ # Make sure your class is a child class of {PlainText::Part},
17
+ # {PlainText::Part::Paragraph}, or {PlainText::Part::Boundary}.
18
+ # Otherwise this method would not be inherited, obviously.
19
+ #
20
+ # @example For a child class of Part
21
+ # class PlainText::Part
22
+ # class Section < self
23
+ # class Subsection < self; end # It must be a child class!
24
+ # end
25
+ # end
26
+ # ss = PlainText::Part::Section::Subsection.new ["abc"]
27
+ # ss.subclass_name # => "Part::Section::Subsection"
28
+ # ss.subclass_name(index_ini: 1) # => "Section::Subsection"
29
+ #
30
+ # @example For a child class of Boundary
31
+ # class PlainText::Part::Boundary
32
+ # class SubBoundary < self
33
+ # class SubSubBoundary < self; end # Grandchild
34
+ # end
35
+ # end
36
+ # ss = PlainText::Part::Boundary::SubBoundary::SubSubBoundary.new ["abc"]
37
+ # ss.subclass_name # => "Part::Boundary::SubBoundary::SubSubBoundary"
38
+ # ss.subclass_name(index_ini: 2) # => "SubBoundary::SubSubBoundary"
39
+ #
40
+ # @param index_ini [Integer] Starting index after split, e.g., if 1, +"Part::"+ is removed and if 2, "Part::Boundary::" (for example) is removed.
41
+ # @return [String]
42
+ # @see PlainText::Part#subclass_name
43
+ def subclass_name(index_ini: 0)
44
+ self.class.name.split(/\A#{Regexp.quote method(__method__).owner.name.split("::")[0..-2].join("::")}::/)[1].split('::')[index_ini..-1].join('::') || '' # removing "::BuiltinType"
45
+ end
46
+
47
+ # core routine for dup/clone
48
+ #
49
+ # @param copied [PlainText::Part] super-ed object
50
+ # @param metho [Symbol] method name
51
+ # @param varname [String] instance-variable name, e.g., +"@array"+
52
+ # @return [Object] e.g., {PlainText::Part}, {PlainText::Part::Paragraph}
53
+ def dup_or_clone(copied, metho, varname)
54
+ val = (instance.send(metho) rescue instance) # rescue in case of immutable (though instance (e.g., @array) should never be so and in fact it would not raise an Exception in Ruby 3 seemingly).
55
+ copied.instance_variable_set(varname, val)
56
+ # NOTE: copied.to_a.replace(val) would not work because it does not change @array.object_id
57
+ # A setter like {#to_a=} or {#instance=} would work, though polimorphism would break.
58
+ copied
59
+ end
60
+ private :dup_or_clone
61
+
62
+ end # BuiltinType
63
+ end # module PlainText
64
+
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module PlainText
4
+ class PartNormalizeError < StandardError
5
+ end
6
+ end
@@ -1,44 +1,54 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
+ require_relative "../builtin_type"
4
+ require_relative "string_type"
5
+
3
6
  module PlainText
4
- class Part < Array
7
+ class Part
5
8
 
6
- # Class to express a Boundary as String
9
+ # Class to express a Boundary, which behaves like a String
10
+ #
11
+ # This used to be a sub-class of String up to Ver.0.7.1
7
12
  #
8
- class Boundary < String
13
+ class Boundary
14
+ include PlainText::BuiltinType
15
+ include StringType
9
16
 
10
- # @return [String]
11
- def inspect
12
- # 'Boundary("\n\n\n")'
13
- s = self.class.name
14
- sprintf "%s(%s)", (s.split('::')[2..-1].join('::') rescue s), super
17
+ # Constructor
18
+ #
19
+ # @param str [String]
20
+ def initialize(str)
21
+ @string = str
15
22
  end
16
23
 
17
- # Boundary sub-class name only
18
- #
19
- # Make sure your class is a child class of Boundary.
20
- # Otherwise this method would not be inherited, obviously.
21
- #
22
- # @example
23
- # class PlainText::Part::Boundary
24
- # class SubBoundary < self
25
- # class SubBoundary < self; end # It must be a child class!
26
- # end
27
- # end
28
- # ss = PlainText::Part::SubBoundary::SubSubBoundary.new ["abc"]
29
- # ss.subclass_name # => "SubBoundary::SubSubBoundary"
24
+ # @return [Integer, NilClass]
25
+ def <=>(other)
26
+ _equal_cmp(other, __method__){ super }
27
+ end
28
+
29
+ # +String#==+ refers to this.
30
30
  #
31
- # @return [String]
32
- # @see PlainText::Part#subclass_name
33
- def subclass_name
34
- printf "__method__=(%s)\n", __method__
35
- self.class.name.split(/\A#{Regexp.quote method(__method__).owner.name}::/)[1] || ''
31
+ # @see https://ruby-doc.org/core-3.1.2/String.html#method-i-3D-3D
32
+ def ==(other)
33
+ _equal_cmp(other, __method__){ super }
34
+ end
35
+
36
+ def boundary?
37
+ true
38
+ end
39
+
40
+ def paragraph?
41
+ false
42
+ end
43
+
44
+ def part?
45
+ false
36
46
  end
37
47
 
38
48
  # Empty Boundary instance
39
49
  Empty = self.new ""
40
50
  Empty.freeze
41
- end # class Boundary < String
42
- end # class Part < Array
51
+ end # class Boundary
52
+ end # class Part
43
53
  end # module PlainText
44
54
 
@@ -1,35 +1,58 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
+ require_relative "../builtin_type"
4
+ require_relative "string_type"
5
+
3
6
  module PlainText
4
- class Part < Array
7
+ class Part
5
8
 
6
9
  # Class to express a Paragraph as String
7
10
  #
8
- class Paragraph < String
11
+ class Paragraph
12
+ include PlainText::BuiltinType
13
+ include StringType
9
14
 
10
- # @return [String]
11
- def inspect
12
- # 'Paragraph("abc\ndef")' or like 'Paragraph::Title("My Title")'
13
- s = self.class.name
14
- sprintf "%s(%s)", (s.split('::')[2..-1].join('::') rescue s), super
15
+ # Constructor
16
+ #
17
+ # @param str [String]
18
+ def initialize(str)
19
+ @string = str
15
20
  end
16
21
 
17
- # Paragraph sub-class name
18
- #
19
- # Make sure your class is a child class of Paragraph.
20
- # Otherwise this method would not be inherited, obviously.
22
+ ## @return [String]
23
+ #def to_s
24
+ # @string
25
+ #end
26
+ #alias_method :to_str, :to_s
27
+
28
+ # @return [Integer, NilClass]
29
+ def <=>(other)
30
+ _equal_cmp(other, __method__){ super }
31
+ end
32
+
33
+ # +String#==+ refers to this.
21
34
  #
22
- # @return [String]
23
- # @see PlainText::Part#subclass_name
24
- def subclass_name
25
- printf "__method__=(%s)\n", __method__
26
- self.class.name.split(/\A#{Regexp.quote method(__method__).owner.name}::/)[1] || ''
35
+ # @see https://ruby-doc.org/core-3.1.2/String.html#method-i-3D-3D
36
+ def ==(other)
37
+ _equal_cmp(other, __method__){ super }
38
+ end
39
+
40
+ def boundary?
41
+ false
42
+ end
43
+
44
+ def paragraph?
45
+ true
46
+ end
47
+
48
+ def part?
49
+ false
27
50
  end
28
51
 
29
52
  # Empty Paragraph instance
30
53
  Empty = self.new ""
31
54
  Empty.freeze
32
- end # class Paragraph < String
33
- end # class Part < Array
55
+ end # class Paragraph
56
+ end # class Part
34
57
  end # module PlainText
35
58
 
@@ -0,0 +1,90 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require_relative "../builtin_type"
4
+
5
+ module PlainText
6
+ class Part
7
+
8
+ # Contains common methods for use in the String-type classes.
9
+ #
10
+ # @author Masa Sakano (Wise Babel Ltd)
11
+ #
12
+ module StringType
13
+
14
+ # @return [String]
15
+ def to_s
16
+ @string
17
+ end
18
+ alias_method :to_str, :to_s
19
+ alias_method :instance, :to_s if ! self.method_defined?(:instance)
20
+
21
+ # Basically delegates everything to String
22
+ def method_missing(method_name, *args, **kwds)
23
+ ret = to_s.public_send(method_name, *args, **kwds)
24
+ ret.respond_to?(:to_str) ? self.class.new(ret) : ret
25
+ end
26
+
27
+ # Redefines the behaviour of +respond_to?+ (essential when defining +method_missing+)
28
+ def respond_to_missing?(method_name, *rest) # include_all=false
29
+ to_s.respond_to?(method_name, *rest) || super
30
+ end
31
+
32
+ # +Para("ab\ncd")+ or +Boundary("\n\n\n")+
33
+ #
34
+ # @return [String]
35
+ def inspect
36
+ s = self.class.name
37
+ sprintf "%s(%s)", (s.split('::')[2..-1].join('::') rescue s), to_s.inspect
38
+ end
39
+
40
+ # Boundary sub-class name only
41
+ #
42
+ # Make sure your class is a child class of Boundary.
43
+ # Otherwise this method would not be inherited, obviously.
44
+ #
45
+ # @example
46
+ # class PlainText::Part::Boundary
47
+ # class SubBoundary < self
48
+ # class SubSubBoundary < self; end # Grandchild
49
+ # end
50
+ # end
51
+ # ss = PlainText::Part::Boundary::SubBoundary::SubSubBoundary.new ["abc"]
52
+ # ss.subclass_name # => "Boundary::SubBoundary::SubSubBoundary"
53
+ #
54
+ # @return [String]
55
+ # @see PlainText::Part#subclass_name
56
+ # def subclass_name
57
+ ##printf "DEBUG: __method__=(%s)\n", __method__
58
+ # self.class.name.split(/\A#{Regexp.quote method(__method__).owner.name.split("::")[0..-2].join("::")}::/)[1] || '' # removing "::StringType"
59
+ # end
60
+
61
+ # Work around because Object#dup does not dup the instance variable @string
62
+ #
63
+ # @return [PlainText::Part]
64
+ def dup
65
+ dup_or_clone(super, __method__, '@string') # defined in builtin_type.rb
66
+ end
67
+
68
+ # Work around because Object#clone does not clone the instance variable @string
69
+ #
70
+ # @return [PlainText::Part]
71
+ def clone
72
+ dup_or_clone(super, __method__, '@string') # defined in builtin_type.rb
73
+ end
74
+
75
+ # Core routine for comparison operators
76
+ #
77
+ # @example
78
+ # _equal_cmp(other, :==){ super }
79
+ # _equal_cmp(other, __method__){ super }
80
+ #
81
+ # @return [Boolean, Integer, NilClass]
82
+ def _equal_cmp(other, oper)
83
+ return yield if !other.respond_to? :to_str
84
+ to_s.send(oper, other.to_str) # e.g., @string == other.to_str
85
+ end
86
+ private :_equal_cmp
87
+ end # module StringType
88
+ end # class Part
89
+ end # module PlainText
90
+