plain_text 0.7 → 0.8
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/ChangeLog +16 -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 +15 -11
- data/plain_text.gemspec +2 -2
- data/test/test_plain_text.rb +29 -4
- data/test/test_plain_text_parse_rule.rb +17 -3
- data/test/test_plain_text_part.rb +196 -14
- data/test/test_plain_text_split.rb +17 -2
- data/test/test_plain_text_util.rb +17 -2
- metadata +5 -2
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,19 @@
|
|
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
|
+
|
12
|
+
-----
|
13
|
+
(Version: 0.7.1)
|
14
|
+
2022-09-09 Masa Sakano
|
15
|
+
* Skips some tests that break in Ruby 3.
|
16
|
+
|
1
17
|
-----
|
2
18
|
(Version: 0.7)
|
3
19
|
2022-08-25 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
|
+
|