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 +4 -4
- data/.gitignore +1 -0
- data/ChangeLog +11 -0
- data/Makefile +2 -1
- data/README.en.rdoc +67 -61
- data/lib/plain_text/builtin_type.rb +64 -0
- data/lib/plain_text/error.rb +6 -0
- data/lib/plain_text/part/boundary.rb +38 -28
- data/lib/plain_text/part/paragraph.rb +41 -18
- data/lib/plain_text/part/string_type.rb +90 -0
- data/lib/plain_text/part.rb +316 -275
- data/lib/plain_text/util.rb +13 -12
- data/lib/plain_text.rb +14 -10
- data/plain_text.gemspec +3 -3
- data/test/test_plain_text.rb +17 -2
- data/test/test_plain_text_parse_rule.rb +17 -3
- data/test/test_plain_text_part.rb +207 -39
- data/test/test_plain_text_split.rb +17 -2
- data/test/test_plain_text_util.rb +17 -2
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a03c794c7f63a55e51e3f57aeb9345dbb2e60c416525f1649037429539f33697
|
4
|
+
data.tar.gz: b7c80770207ca932edbf9af2fce56586b56271aad5813f2a8c63761a070257f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '080c21444032d57f10d5c62b75be779c915ec110f8902033c5abc46d6b4f668deee9da6f857ea0b75a0a8742be246830af16fc49cbe9045d610434f75d6993d5'
|
7
|
+
data.tar.gz: 75ad795005fcb38417130e4e06948eea36fa68525b50c623efda994d081085b0b70623d6812f81dc5c54d35b86e75647ae63818335edbeae28a576e6134889c6
|
data/.gitignore
CHANGED
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
|
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
|
11
|
-
of characters (especially useful for
|
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
|
-
|
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
|
23
|
+
The original plain text should be String in Ruby.
|
24
24
|
|
25
|
-
The module {PlainText}
|
26
|
-
{PlainText#head} and {PlainText#tail}
|
27
|
-
in String.
|
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
|
-
|
33
|
-
|
34
|
-
It is basically a container class and
|
35
|
-
|
36
|
-
components of
|
37
|
-
{PlainText::Part::
|
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
|
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
|
-
|
74
|
-
{PlainText::Part::
|
75
|
-
|
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
|
-
|
87
|
-
String instance
|
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
|
95
|
-
|
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
|
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
|
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
|
-
|
225
|
-
|
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
|
-
|
236
|
+
Then all you need to do is
|
228
237
|
|
229
238
|
require "plain_text"
|
230
239
|
|
231
|
-
|
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
|
-
|
236
|
-
|
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
|
-
|
245
|
+
If you +include PlainText+ from String, it would be handy, though
|
246
|
+
not mandatory to use this library.
|
240
247
|
|
241
|
-
|
242
|
-
|
243
|
-
|
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
|
-
|
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
|
+
|
@@ -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
|
7
|
+
class Part
|
5
8
|
|
6
|
-
# Class to express a Boundary
|
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
|
13
|
+
class Boundary
|
14
|
+
include PlainText::BuiltinType
|
15
|
+
include StringType
|
9
16
|
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
# Constructor
|
18
|
+
#
|
19
|
+
# @param str [String]
|
20
|
+
def initialize(str)
|
21
|
+
@string = str
|
15
22
|
end
|
16
23
|
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
#
|
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
|
-
# @
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
42
|
-
end # class Part
|
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
|
7
|
+
class Part
|
5
8
|
|
6
9
|
# Class to express a Paragraph as String
|
7
10
|
#
|
8
|
-
class Paragraph
|
11
|
+
class Paragraph
|
12
|
+
include PlainText::BuiltinType
|
13
|
+
include StringType
|
9
14
|
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
+
# Constructor
|
16
|
+
#
|
17
|
+
# @param str [String]
|
18
|
+
def initialize(str)
|
19
|
+
@string = str
|
15
20
|
end
|
16
21
|
|
17
|
-
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
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
|
-
# @
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
33
|
-
end # class Part
|
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
|
+
|