html-renderer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gemspec +20 -0
- data/LICENSE +13 -0
- data/README.md +12 -0
- data/Rakefile +20 -0
- data/VERSION +1 -0
- data/examples/ansi_renderer.rb +168 -0
- data/examples/debug_renderer.rb +14 -0
- data/examples/plain_text_renderer.rb +72 -0
- data/examples/test.html +113 -0
- data/lib/html-renderer.rb +1 -0
- data/lib/html-renderer/base.rb +171 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ec832ffacb22bbaa8114f23fc302ceda89ba7b6622945587d54d2c3dc0cbe25d
|
4
|
+
data.tar.gz: '0813e1a9e2185e7f656934ddffc2cde7eb9ecc92e3b028ef0646272742d7c2fb'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2412e685c804211d8f9d4c9101a1287d3a97e55f3d60f65bce810559cc9499081e0f343bcd7c353e3ba3eb8abddb9eea2454149966b29f22bf1e54579d3bfa31
|
7
|
+
data.tar.gz: a3ecf047cd4c5e2dd99d5f9ef79ee9d8b8855e9732fabcf59a94121102bea0ee7d07d08cf5899491c93ce156bd3f6edae48353913b7c84e4e37bb12dab30018c
|
data/.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "html-renderer"
|
6
|
+
s.version = File.read "VERSION"
|
7
|
+
s.date = File.mtime("VERSION").strftime("%Y-%m-%d")
|
8
|
+
s.summary = "HTML Renderer"
|
9
|
+
s.description = "Easily implement an HTML renderer by creating a subclass and adding some methods, similar to RedCarpet. (Examples are included for rendering HTML to ANSI and plain text.)"
|
10
|
+
s.homepage = "http://github.com/epitron/html-renderer/"
|
11
|
+
s.licenses = ["WTFPL"]
|
12
|
+
s.email = "chris@ill-logic.com"
|
13
|
+
s.authors = ["epitron"]
|
14
|
+
|
15
|
+
s.files = `git ls`.lines.map(&:strip)
|
16
|
+
s.extra_rdoc_files = ["README.md", "LICENSE"]
|
17
|
+
|
18
|
+
s.add_dependency "oga", "~> 2"
|
19
|
+
s.add_development_dependency "ansi", "~> 1"
|
20
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
2
|
+
Version 2, December 2004
|
3
|
+
|
4
|
+
Copyright (C) 2004 Sam Hocevar
|
5
|
+
14 rue de Plaisance, 75014 Paris, France
|
6
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
7
|
+
copies of this license document, and changing it is allowed as long
|
8
|
+
as the name is changed.
|
9
|
+
|
10
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
11
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
12
|
+
|
13
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
data/README.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# HTML Renderer
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
Allows you to subclass `HTMLRenderer::Base`, add some methods, and then parse HTML to generate custom output.
|
6
|
+
|
7
|
+
(Uses a similar API to the [RedCarpet](https://github.com/vmg/redcarpet) gem.)
|
8
|
+
|
9
|
+
## Examples
|
10
|
+
|
11
|
+
* [HTML to Plain Text Renderer](https://github.com/epitron/html-renderer/blob/master/examples/plain_text_renderer.rb)
|
12
|
+
* [HTML to ANSI Renderer](https://github.com/epitron/html-renderer/blob/master/examples/ansi_renderer.rb)
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
gem_version = File.read("VERSION").strip
|
2
|
+
gem_name = "html-renderer"
|
3
|
+
|
4
|
+
task :build do
|
5
|
+
system "gem build .gemspec"
|
6
|
+
end
|
7
|
+
|
8
|
+
task :release => :build do
|
9
|
+
system "gem push #{gem_name}-#{gem_version}.gem"
|
10
|
+
end
|
11
|
+
|
12
|
+
task :install => :build do
|
13
|
+
system "gem install --local #{gem_name}-#{gem_version}.gem"
|
14
|
+
end
|
15
|
+
|
16
|
+
task :pry do
|
17
|
+
system "pry --gem"
|
18
|
+
end
|
19
|
+
|
20
|
+
task :default => :spec
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'html-renderer'
|
2
|
+
require 'ansi/mixin'
|
3
|
+
require 'terminal-table'
|
4
|
+
require 'coderay'
|
5
|
+
|
6
|
+
class String
|
7
|
+
include ANSI::Mixin
|
8
|
+
|
9
|
+
def grey; self.black.bold; end
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
class ANSIRenderer < HTMLRenderer::Base
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def indented?(text)
|
18
|
+
indent_sizes = text.lines.map{ |line| if line =~ /^(\s+)/ then $1 else '' end }.map(&:size)
|
19
|
+
indent_sizes.all? {|dent| dent > 0 }
|
20
|
+
end
|
21
|
+
|
22
|
+
def unwrap(text)
|
23
|
+
return text unless indented? text
|
24
|
+
text.lines.to_a.map(&:strip).join ' '
|
25
|
+
end
|
26
|
+
|
27
|
+
def indent(text,amount=2)
|
28
|
+
text.lines.map{|line| " "*amount + line }.join
|
29
|
+
end
|
30
|
+
|
31
|
+
def smash(s)
|
32
|
+
s&.downcase&.scan(/\w+/)&.join
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
public
|
37
|
+
|
38
|
+
def normal_text(text)
|
39
|
+
text
|
40
|
+
end
|
41
|
+
|
42
|
+
def raw_html(html)
|
43
|
+
''
|
44
|
+
end
|
45
|
+
|
46
|
+
def underline(content)
|
47
|
+
content.magenta.bold
|
48
|
+
end
|
49
|
+
|
50
|
+
def superscript(content)
|
51
|
+
"^(#{content})"
|
52
|
+
end
|
53
|
+
|
54
|
+
def link(link, title, content)
|
55
|
+
unless content&.[] /^Back /
|
56
|
+
str = ""
|
57
|
+
# str += "<15>#{content}</15>" if content
|
58
|
+
str += content.white.bold if content
|
59
|
+
if smash(link) != smash(content)
|
60
|
+
# str += " <8>(</8><11>#{link}</11><8>)</8>"
|
61
|
+
str += " #{"(".grey}#{link.cyan.bold}#{")".grey}"
|
62
|
+
end
|
63
|
+
|
64
|
+
str
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def image(link, title, content)
|
69
|
+
link(link, nil, title)
|
70
|
+
end
|
71
|
+
|
72
|
+
def italic(text)
|
73
|
+
text.light_yellow
|
74
|
+
end
|
75
|
+
|
76
|
+
def block_code(code, language)
|
77
|
+
language ||= :ruby
|
78
|
+
|
79
|
+
language = language[1..-1] if language[0] == "." # strip leading "."
|
80
|
+
language = :cpp if language == "C++"
|
81
|
+
|
82
|
+
require 'coderay'
|
83
|
+
"#{indent CodeRay.scan(code, language).term, 4}\n"
|
84
|
+
end
|
85
|
+
|
86
|
+
def block_quote(text)
|
87
|
+
indent paragraph(text)
|
88
|
+
end
|
89
|
+
|
90
|
+
def codespan(code)
|
91
|
+
code.cyan
|
92
|
+
end
|
93
|
+
|
94
|
+
def header(title, level, anchor=nil)
|
95
|
+
bar = ("-"*(title.size+4)).grey
|
96
|
+
|
97
|
+
title = case level
|
98
|
+
when 1 then title.bold.yellow
|
99
|
+
when 2 then title.bold.cyan
|
100
|
+
when 3 then title.bold.blue
|
101
|
+
else title.purple
|
102
|
+
end
|
103
|
+
|
104
|
+
"#{bar}\n #{title}\n#{bar}\n\n"
|
105
|
+
end
|
106
|
+
|
107
|
+
def double_emphasis(text)
|
108
|
+
text.bold.green
|
109
|
+
end
|
110
|
+
|
111
|
+
def emphasis(text)
|
112
|
+
text.green
|
113
|
+
end
|
114
|
+
|
115
|
+
def linebreak
|
116
|
+
"\n"
|
117
|
+
end
|
118
|
+
|
119
|
+
def paragraph(text)
|
120
|
+
div(text) + "\n"
|
121
|
+
end
|
122
|
+
|
123
|
+
def div(text)
|
124
|
+
"#{indented?(text) ? text : unwrap(text)}\n"
|
125
|
+
end
|
126
|
+
|
127
|
+
def list(content, list_type)
|
128
|
+
case list_type
|
129
|
+
when :ordered
|
130
|
+
@counter = 0
|
131
|
+
"#{content}\n"
|
132
|
+
when :unordered
|
133
|
+
"#{content}\n"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def list_item(content, list_type)
|
138
|
+
case list_type
|
139
|
+
when :ordered
|
140
|
+
@counter ||= 0
|
141
|
+
@counter += 1
|
142
|
+
# " <8>#{@counter}.</8> #{content.strip}\n".colorize
|
143
|
+
" #{@counter.to_s.grey}. #{content.strip}\n"
|
144
|
+
when :unordered
|
145
|
+
# " <8>*</8> #{content.strip}\n".colorize
|
146
|
+
" #{"*".grey} #{content.strip}\n"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def table(header, rows)
|
151
|
+
if header
|
152
|
+
table = Terminal::Table.new(headings: header, rows: rows)
|
153
|
+
else
|
154
|
+
table = Terminal::Table.new(rows: rows)
|
155
|
+
end
|
156
|
+
"#{table}\n\n"
|
157
|
+
end
|
158
|
+
|
159
|
+
def separator
|
160
|
+
"_____________________________\n\n"
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
if __FILE__ == $0
|
167
|
+
puts ANSIRenderer.render(open("test.html"))
|
168
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'html-renderer'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Everything-stripping renderer.
|
5
|
+
#
|
6
|
+
class PlainTextRenderer < HTMLRenderer::Base
|
7
|
+
# Methods where the first argument is the text content
|
8
|
+
[
|
9
|
+
# block-level calls
|
10
|
+
:block_code, :block_quote,
|
11
|
+
:block_html, :list, :list_item,
|
12
|
+
|
13
|
+
# span-level calls
|
14
|
+
:autolink, :codespan, :double_emphasis,
|
15
|
+
:emphasis, :underline, :raw_html,
|
16
|
+
:triple_emphasis, :strikethrough,
|
17
|
+
:superscript, :highlight,
|
18
|
+
|
19
|
+
# footnotes
|
20
|
+
:footnotes, :footnote_def, :footnote_ref,
|
21
|
+
|
22
|
+
# low level rendering
|
23
|
+
:entity, :normal_text
|
24
|
+
].each do |method|
|
25
|
+
define_method method do |*args|
|
26
|
+
args.first
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Other methods where we don't return only a specific argument
|
31
|
+
def link(link, title, content)
|
32
|
+
"#{content} (#{link})"
|
33
|
+
end
|
34
|
+
|
35
|
+
def image(link, title, content)
|
36
|
+
content &&= content + " "
|
37
|
+
"#{content}#{link}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def div(text)
|
41
|
+
text + "\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
def paragraph(text)
|
45
|
+
div(text) + "\n"
|
46
|
+
end
|
47
|
+
|
48
|
+
def separator
|
49
|
+
"______________________\n\n"
|
50
|
+
end
|
51
|
+
|
52
|
+
def header(text, header_level)
|
53
|
+
text + "\n"
|
54
|
+
end
|
55
|
+
|
56
|
+
def table(header, body)
|
57
|
+
"#{header}#{body}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def table_row(content)
|
61
|
+
content + "\n"
|
62
|
+
end
|
63
|
+
|
64
|
+
def table_cell(content, alignment)
|
65
|
+
content + "\t"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
if __FILE__ == $0
|
71
|
+
puts PlainTextRenderer.render(open("test.html"))
|
72
|
+
end
|
data/examples/test.html
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
|
2
|
+
<!-- essay --> <p>Faced with an adversary who is doing something we do not like, or who is not doing something we wish to have done, persuasion can be an invaluable tool. Though "power" is generally considered to be coercion or force, persuasion can be powerful too, as is evidenced by the common saying, "the power of persuasion."</p>
|
3
|
+
|
4
|
+
<p>Social-interest theorists tend to define persuasion as a form of social influence:</p>
|
5
|
+
<p>Influence investigates the causes of human change -- whether that change is a behavior, an attitude, or a belief. Inducing a change in behavior is called compliance. Inducing a change in attitude is called persuasion. Inducing a change in belief is called either education or propaganda -- depending on your perspective.[1]</p>
|
6
|
+
<p>Rhodes is using the term "influence" in a way similar to my use of the word "power," "the capacity to bring about change." From his viewpoint, it is important to identify what is being changed, i.e., behavior, attitude, or belief. In this series of essays (<a href="http://www.beyondintractability.org/bi-essay/theories-of-change">Theories of Change</a>, <a href="http://www.beyondintractability.org/bi-essay/Power">Understanding Power</a>, <a href="http://www.beyondintractability.org/bi-essay/threats">Coercive Power</a>, <a href="http://www.beyondintractability.org/bi-essay/exchange">Exchange Power</a>, <a href="http://www.beyondintractability.org/bi-essay/integrative-power">Integrative Power</a>, and Persuasion), the important distinction is on the "how" of the change.</p>
|
7
|
+
<p>Sometimes, social-influence scholars include under the term "persuasion" the concept of <em>inducements</em>, which tend to better fit my definition of <a href="http://www.beyondintractability.org/bi-essay/exchange">exchange power</a> or even <a href="http://www.beyondintractability.org/bi-essay/threats">coercive power</a>, rather than persuasive power. At other times, efforts focused on behavioral change may be left out. In those cases, the writer is concerned only with efforts to change attitudes, not with efforts to change behaviors. Some of the most useful research on persuasion can be found in the social-influence literature, but the key term may be used somewhat differently in that literature from the way in which it is used here.</p>
|
8
|
+
<p>Here I use "persuasion" to mean the form of power that relies exclusively on symbols (such as words) to influence another to change. That change may affect beliefs, attitudes, or behaviors, but we are particularly interested here in changes in behavior brought about because beliefs or attitudes have been modified.</p>
|
9
|
+
<div class="essay-head2">
|
10
|
+
Principles of Persuasion</div>
|
11
|
+
<p>Social-influence scholars have developed a variety of ways of categorizing the mechanisms through which people persuade others to change their behavior. Robert B. Cialdini's <em>Influence: Science and Practice</em> is one such resource. In the book, Cialdini presents a number of principles of persuasion, citing and discussing a range of research and anecdotes. While most of his examples are drawn from the marketing field, the principles themselves apply much more broadly. They offer insight into ways in which we persuade people to do things. For example:</p>
|
12
|
+
<ul>
|
13
|
+
<li>
|
14
|
+
In all cultures, people tend to return favors. Cialdini refers to this as the "law of reciprocity," and, for the most part, this form of influence belongs in the essay on <a href="http://www.beyondintractability.org/bi-essay/exchange">exchange power</a>. One of Cialdini's examples, however, deserves mention here. He recounts the story of a German soldier who was very adept at crossing battle lines during World War I, and returning back to his superiors with an Allied soldier for questioning. On one such trip, the soldier he accosted was in the middle of eating a meal and offered his would-be captor a piece of bread. "So affected was the German by this gift that he could not complete his mission. He turned from his benefactor and recrossed no-man's-land empty-handed to face the wrath of his superiors."[2]</li>
|
15
|
+
<li>
|
16
|
+
People tend to?behave in ways that they feel they are expected to behave. The wise negotiator can use this to her or his advantage. Cialdini notes Anwar Sadat's mastery of this technique:</li>
|
17
|
+
</ul>
|
18
|
+
<p>Before international negotiations began, Sadat would assure his bargaining opponents that they and the citizens of their country were widely known for their cooperativeness and fairness. With this kind of flattery, he not only created positive feelings, he also connected his opponents' identities to a course of action that served his goals.[3]</p>
|
19
|
+
<ul>
|
20
|
+
<li>
|
21
|
+
Social proof, as manifested in the behavior of others, is likely to have an immediate and telling effect on the behavior of observers. Examples of the "monkey see, monkey do" principle abound, whether one is talking about action (e.g., copycat crimes) or inaction (e.g., the failure of 38 onlookers who had many chances to go help Kitty Genovese when she was mugged and killed on a New York street in 1964).</li>
|
22
|
+
<li>
|
23
|
+
People are more likely to be influenced by those they like than those they do not. Several factors are associated with liking: physical attractiveness, similarity, praise, familiarity (particularly through mutual and successful cooperation in the past), and association with positive things. This suggests that it is problematic for deep-rooted enemies to persuade each other. Two sides in a protracted conflict have likely emphasized their differences, cast aspersions on each other, avoided contact when possible, and been associated with causing pain and suffering to each other's group for years, decades, or even centuries. They are missing all the factors that lead to liking except, perhaps, physical attractiveness. This may be one of many reasons that <a href="http://www.beyondintractability.org/bi-essay/intermediary-roles">third-party intervention</a> is often more profitable than <a href="http://www.beyondintractability.org/bi-essay/negotiation">direct negotiation</a> between sworn adversaries.</li>
|
24
|
+
<li>
|
25
|
+
People are more likely to respond to the directives of a recognized authority figure, or to be influenced by the testimony of one with authority, than by someone who is not perceived to have authority. Advertisers use this tendency on a regular basis, arranging for well-known and respected people to endorse their products. For example, on the world stage, Jimmy Carter lends his good name to election-monitoring efforts of contested elections, and Desmond Tutu speaks against human-rights violations on behalf of oppressed groups. Such personages can also be particularly effective mediators, as Oscar Arias proved in Central America.</li>
|
26
|
+
<li>
|
27
|
+
Finally, scarcity can be a compelling factor in getting someone to do something that she or he otherwise would not do. It is easy to see this in sales pitches in the form of "last chance" or "one of a kind" strategies. "According to the scarcity principle, people assign more value to opportunities when they are less available."[4] As with the "norm of reciprocity," we are probably most likely to see this principle in operation when exchange power is at the fore.</li>
|
28
|
+
</ul>
|
29
|
+
<div class="essay-head2">
|
30
|
+
Strategies of Persuasion</div>
|
31
|
+
<p>While each of these principles is supported by both systematic and anecdotal evidence, it is not always clear how one might utilize the principles in a particular relationship or encounter. Louis Kriesberg[5] suggests five ways in which one party might influence another in moving toward resolution of a dispute:</p>
|
32
|
+
<ol>
|
33
|
+
<li>
|
34
|
+
Party A may ask Party B to look at the situation from Party A's point of view, to take on the role of Party A. This may serve not only to help Party B understand that Party A's intentions are, for example, defensive rather than aggressive, but it may lay a foundation for a more harmonious relationship between the two parties.</li>
|
35
|
+
<li>
|
36
|
+
"A second kind of argument points out complementary interests that would be enhanced by yielding what is sought."[6] Party B may benefit in a different way from the right or privilege that Party A seeks. One argument in pleas of the oppressed is that oppression hurts the oppressor as well as the oppressed. An enslaver, for example, is assured the grudging compliance of the slave, but at a cost of constant monitoring and loss of his or her own humanity. Freeing slaves affords a society the benefit of willing labor as well as a more humane environment for everyone.</li>
|
37
|
+
<li>
|
38
|
+
"A third kind of persuasive argument tries to turn a divisive issue into a problem that is shared and needs a mutually satisfactory solution."[7] In the conflict-resolution literature, this is an example of what is called "<a href="http://www.beyondintractability.org/bi-essay/framing">reframing</a>." Reframing allows the adversary to see the issue differently and to retreat from a previously stated singular position to a new, shared one; it may also serve as a <a href="http://www.beyondintractability.org/bi-essay/face">face-saving</a> mechanism. The more publicly I have committed myself to a position, the more embarrassing it is for me to back away from it. If, however, the issue is reframed, it is the situation rather than my stance that has changed.</li>
|
39
|
+
<li>
|
40
|
+
The interlocking nature of conflicts is the basis for the fourth type of influence. While Parties A and B may be locked in conflict over one set of issues, they may also share an antagonist against whom they can work together. This antagonist need not be another party; it may be a shared issue. If the concern is shared and its importance is higher than those issues which separate the parties, it becomes a <em>superordinate </em>or transcendent goal.[8] In his several experiments on superordinate goals, Sharif found them a particularly compelling way to reduce hostility.</li>
|
41
|
+
<li>
|
42
|
+
Persuasion may also occur through "appeals to common values and norms ... The appeal is made to abstract principles, shared identifications or previously neglected values."[9]</li>
|
43
|
+
</ol>
|
44
|
+
<p>In the case of intractable conflicts, these strategies often work best when a <a href="http://www.beyondintractability.org/bi-essay/intermediary-roles">third-party intervener</a> is involved. Party B may be reluctant, or even unable, to accept the reframing done by Party A. Party A, after all, has a self-interest in Party B's reassessing the situation. A third party is more likely to be trusted not to act out of self-interest, and her or his attempts to reframe are therefore likely to be more credible than Party A's attempts to communicate exactly the same ideas.</p>
|
45
|
+
<p>It should be noted that each of these forms of persuasion can lead to a warming and <a href="http://www.beyondintractability.org/bi-essay/personal-relationships">strengthening of a relationship</a> between current or former adversaries, as well as to a cementing of an already good relationship. In the optimal case, in resolving a subsequent disagreement, Party A will not need to rely so much on persuasion as on the existing collaboration. Effective persuasion may thus lay the base for other forms of <a href="http://www.beyondintractability.org/bi-essay/integrative-power">integrative power</a> (i.e., the power of relationships).</p>
|
46
|
+
<div class="essay-head2">
|
47
|
+
Types of Appeals</div>
|
48
|
+
<p>Kriesberg refers to appeals to common values and norms. Such appeals are often referred to as <em>appeals to conscience</em>. Appeals may also be made to the other's emotions or to data and logic.</p>
|
49
|
+
<div class="essay-head3">
|
50
|
+
Appeals to Conscience</div>
|
51
|
+
<p>In an <em>appeal to conscience</em>, the speaker is relying on shared values, but pointing out that current behavior is not in accord with these values. While none of us act in accord with our values at all times and in all places, "we nonetheless feel uncomfortable when made aware of inconsistencies. When these inconsistencies become obvious, we feel a strain to change."[10] For the speaker to have the higher ground, however, it is crucial that she or he is seen as acting in accord with these values.</p>
|
52
|
+
<div class="essay-head3">
|
53
|
+
Appeals to Data and Logic</div>
|
54
|
+
<p><em>Appeals to data and logic</em> typically rely on new information or on the reorganization of existing information. The landmark U.S. Supreme Court decision Brown v. Board of Education, which de-segregated American schools, provides a good case in point. Court decisions are usually justified in terms of case precedent. To overturn Plessy v. Ferguson and do away with the principle of "separate but equal" in public education, however, the Court relied largely on the social sciences, stating that:</p>
|
55
|
+
<p>Whatever may have been the extent of psychological knowledge at the time of Plessy v. Ferguson, [our] finding is amply supported by modern authority.[11]</p>
|
56
|
+
<p>The modern authorities to whom the Court was referring included noted psychologist Kenneth B. Clark and sociologist Gunnar Myrdal, both of whom had researched the impact of racial segregation. Clark had used dolls to determine that black children's self-esteem was damaged by segregation.[12] Myrdal's monumental <em>American Dilemma</em> documented the persistence of the discrepancy between the American creed and treatment of African Americans in all areas of life.[13] The Court not only based its decision on such data, but avowedly chose to utilize these data as opposed to other legal arguments.</p>
|
57
|
+
<p>Thurgood Marshall and the other NAACP (National Association for the Advancement of Colored People) attorneys (the plaintiffs) were not the only ones using persuasive power effectively in the case. The Supreme Court justices did too, in an effort to convince each other. Some of the justices were inclined to vote to maintain the separate but equal policy. In fact, had the vote been taken after initial arguments, it is highly likely that Brown v. Board would have been just one more in a long line of failed attempts to overturn segregation. However, Justice Frankfurter convinced his colleagues to delay the decision and call for rehearing the case. Then, newly appointed Chief Justice Earl Warren used his adroit negotiation skills and succeeded in getting a unanimous decision in favor of the plaintiffs.[14]</p>
|
58
|
+
<div class="essay-head3">
|
59
|
+
Emotional Appeals</div>
|
60
|
+
<p>Aristotle identifies an effective <em>emotional appeal</em>, "excit(ing) the required state of emotion in your hearer," as an integral aspect of the final stage in an argument.[15] At the outset of <em>Rhetoric,</em> however, he points out that "the arousing of prejudice, pity, anger, and similar emotions has nothing to do with the essential facts, but is merely a personal appeal to the man who is judging the case." Later, he states more strongly: "It is not right to pervert the judge by moving him to anger or envy or pity -- one might as well warp a carpenter's rule before using it."[16] This identifies the dilemma of emotional appeals. A strong argument needs facts at its base, and even the strongest may not "move" the other to change behavior without an appropriate emotional appeal.</p>
|
61
|
+
<div class="essay-head3">
|
62
|
+
Example: Martin Luther King's "Letter from a Birmingham Jail"</div>
|
63
|
+
<p>Martin Luther King Jr.'s "Letter from a Birmingham Jail," while primarily an appeal to conscience, is masterful in its combination of types of appeals. It weaves them together for greatest impact, and utilizes many of the principles of influence identified above.</p>
|
64
|
+
<p>King opens the letter "MY DEAR FELLOW CLERGYMEN." He thus establishes kinship with his audience from the outset with the word "fellow"; later on he deepens the connection, calling them "my Christian and Jewish brothers." He provides data to counter perceptions of himself as an "outside agitator," providing information on his "organizational ties" and claiming his insider role as an American citizen. Maintaining his connection with the clergy while moving to an appeal to conscience, he connects his journey to Birmingham to the role of Biblical prophets. Prophecy was a ministry with which his addressees were not only familiar, but which they preached from their own pulpits:</p>
|
65
|
+
<p>Just as the prophets of the eighth century B.C. left their villages and carried their "thus saith the Lord" far beyond the boundaries of their home towns, and just as the Apostle Paul left his village of Tarsus and carried the gospel of Jesus Christ to the far corners of the Greco-Roman world, so am I compelled to carry the gospel of freedom beyond my own home town.[17]</p>
|
66
|
+
<p>Much of the letter provides information. King presents his reasons for being in Birmingham and lays out the horrible impacts of prejudice in what was "probably the most thoroughly segregated city in the United States." He also provides a brief explanation of the principles of <a href="http://www.beyondintractability.org/bi-essay/nonviolent-direct-action">nonviolent action</a>. King points out that he and the other protestors had followed the rubric of seeking solution prior to protest. He provides information on how the organizers undertook the first three stages -- collection of facts, negotiation, and self-purification -- before embarking on direct action.</p>
|
67
|
+
<p>King's appeals to emotion, particularly guilt, stand out in the letter. The entirety of the letter is written in calm tones, expressing disappointment rather than anger. King conveys his recurrent hope that the white churches will see the injustice of racism and rally to the cause of the civil-rights movement. He acknowledges those who have done so, but the reader can almost see the tears behind his cataloguing of the many times and ways in which those hopes have been dashed. The penultimate paragraph is a particularly well-stated summary of his guilt-provoking stance:</p>
|
68
|
+
<p>If I have said anything in this letter that overstates the truth and indicates an unreasonable impatience, I beg you to forgive me. If I have said anything that understates the truth and indicates my having a patience that allows me to settle for anything less than brotherhood, I beg God to forgive me.[18]</p>
|
69
|
+
<p>While most of the letter is calm and reflective in tone, begging reconsideration rather than fostering defensiveness, its most-often-quoted sentences are a rousing call to the struggle for justice:</p>
|
70
|
+
<p>"Injustice anywhere is a threat to justice everywhere. We are caught in an inescapable network of mutuality, tied in a single garment of destiny. Whatever affects one directly, affects all indirectly."[19]</p>
|
71
|
+
<p>I have chosen to draw my references to the "Letter from a Birmingham Jail" from a current peace-studies reader rather than from its original source or from King's collected writings and speeches. Doing so underscores something else about the persuasive power of carefully expressed appeals. Although the letter was written to eight clergymen who had questioned his presence in Birmingham and the tactics his followers were using, it was broadcast well beyond the original addressees in both space and time. Whatever the impact it had on them, it has stirred countless others to action and served as an inspiration to those involved in nonviolent struggles for justice.</p>
|
72
|
+
<div class="essay-head3">
|
73
|
+
Example: Morton Deutsch</div>
|
74
|
+
<p>To extend our discussion of effective appeals, we examine Morton Deutsch's strategy for persuading the United States and the Soviets to change their hostile orientation during the Cold War. Though now ended, the Cold War was at the time (early 1960s) a conflict that not only seemed to be intractable, but which threatened the survival of everyone on the planet, regardless of whether they were citizens or allies of one of the principals or not. Drawing on his experience as a psychotherapist, he suggested "four critical tasks" in persuading an enemy to change its hostile stance:</p>
|
75
|
+
<p>First of all, there must be some motivation to change -- the gains (the adversaries) derive from a hostile orientation must not be so great as to outweigh the anxieties and difficulties of the present situation.</p>
|
76
|
+
<p>Second, they must be made aware that the experiences anxieties and difficulties are causally connected with their competitive, hostile orientation.</p>
|
77
|
+
<p>Third, the current environment must not provide substantial justification and support for the continued maintenance of the defensive, hostile orientation appropriate in the past: new experiences, convincingly different from their past experiences, must indicate a genuine interest in their well-being.</p>
|
78
|
+
<p>Fourth, they must perceive that they will gain rather than suffer, have less anxiety rather than more, if they adopt a new orientation.[20]</p>
|
79
|
+
<p>Deutsch's third task suggests that, in order to persuade an enemy, a party must be willing to reassess its own behavior and make changes. Without real behavioral changes on the part of the persuader, persuasive efforts are likely to fall flat. Words alone, no matter how impassioned or logically cogent, are likely to be insufficient.</p>
|
80
|
+
<div class="essay-head2">
|
81
|
+
Limitations of Persuasion</div>
|
82
|
+
<p>Persuasion is a cost-effective way of approaching many conflicts. It does not require weapons or high-tech (and high-cost) research. When it works, therefore, it is a great boon. The protagonist has gotten his counterpart to change her or his behavior in a desired direction at little cost. But, persuasion is not likely to be effective in getting others to do one's will in all conflicts.</p>
|
83
|
+
<p>Carol S. Lilly's provocative <em>Power and Persuasion: Ideology and Rhetoric in Communist </em><em>Yugoslavia</em><em>: 1944-1953 </em>is a testament to the limits of persuasion. In her careful study, she documents how the Communist Party chose persuasion over coercion because they believed that coercion "could help realize the party's political and economic policies but it could not effect the long-term cultural transformation of society."[21] In looking at the variety of persuasive techniques used by the party in its crucial foundational phase, Lilly concludes that:</p>
|
84
|
+
<p>[Per]suasive efforts are effective only or mainly when they seek to build upon already existing values and beliefs and are much less so when they try to change people's values or create new ones for them. In other words, party rhetoric could confirm and sometimes manipulate the existing culture, but was generally unable to transform it.[22]</p>
|
85
|
+
<p>Keeping in mind that primary means of persuasion such as newspapers, radio, television, educational curricula, and the arts were largely under the control of the Party, the implications of these findings suggest even greater limitations for those who do not enjoy such resources. This particular failure takes on additional significance when one looks at the violent disintegration of Yugoslavia in the recent past.</p>
|
86
|
+
<p>[I]n seeking to paper over Yugoslavia's national question, the Communist regime refused fully to confront the atrocities committed during the war, treating them only as additional signs of the prewar bourgeois government's moral and political bankruptcy.[23]</p>
|
87
|
+
<p>The bloodbath that erupted after the fall of Communism may have been even worse than what might have transpired had these inter-group conflicts been played out, even violently, in the immediate post-war period.</p>
|
88
|
+
<p>In addressing intractable conflicts, persuasion can be a key ingredient in landmark events, such as Brown v. Board of Education. By itself, however, it cannot achieve the level of community building necessary for transformation. For this, a fuller and deeper array of integrative approaches (suggested in fact by Deutsch's list) needs to be employed. In winning the hearts and minds of the targeted group, techniques that target minds only are likely to be inadequate for the task.</p>
|
89
|
+
<hr />
|
90
|
+
<p>[1] Rhodes, Kelton. "Introduction to Influence," <a href="http://www.workingpsychology.com/evryinfl.html">http://www.workingpsychology.com/evryinfl.html</a>, downloaded March 27, 2003.</p>
|
91
|
+
<p>[2] Cialdini, Robert B. <em>Influence: Science and Practice</em>. 4<sup>th</sup> Ed. Boston: Allyn & Bacon, 2001, p. 30.</p>
|
92
|
+
<p>[3] Cialdini, p. 70.</p>
|
93
|
+
<p>[4] Cialdini, p. 231.</p>
|
94
|
+
<p>[5] Kriesberg, Louis. <em>Social Conflicts</em>. 2<sup>nd</sup> Ed. Englewood Cliffs, N.J.: Prentice-Hall, Inc., 1982, p.115-117.</p>
|
95
|
+
<p>[6] Kriesberg, p. 116.</p>
|
96
|
+
<p>[7] Kriesberg, p. 116.</p>
|
97
|
+
<p>[8] Sharif, 1966 **??this is not complete</p>
|
98
|
+
<p>[9] Kriesberg, p. 116.</p>
|
99
|
+
<p>[10] Trenholm, Sarah. <em>Persuasion and Social Influence</em>. Englewood Cliffs, N.J.: Prentice-Hall, Inc., 1989, p. 111.</p>
|
100
|
+
<p>[11] <a href="http://caselaw.lp.findlaw.com/cgi-bin/getcase.pl?court=US&vol=347&invol=483">http://caselaw.lp.findlaw.com/cgi-bin/getcase.pl?court=US&vol=347&invol=483</a>.</p>
|
101
|
+
<p>[12] "Kenneth B. Clark, activist, psychologist, and author," <u>The African American Registry</u>. Available online <a href="http://www.aaregistry.com/african-american-history/283/Kennth-B_Clark-activist-psychologist-and-author">here</a>.</p>
|
102
|
+
<p>[13] Zhang, Junfu. "Black-White Relations: The American Dilemma," <u>Perspectives</u>, I (4). Online: http://www.oycf.org/Perspectives/4-022900/black-white.htm</p>
|
103
|
+
<p>[14] Roberts, Paul Craig and Lawrence M. Stratton, "The Brown Decision," from <em>The New Color Line: How Quotas and Privileges Destroy Democracy</em>. 1995. <a href="http://www.lewrockwell.com/orig/brown.html">http://www.lewrockwell.com/orig/brown.html</a>.</p>
|
104
|
+
<p>[15] Aristotle. <em>Rhetoric</em>. Based on 1954 translation by W. Rhys Roberts. Hypertext editor: Lee Honeycutt. Online: Part I: http://www.public.iastate.edu/~honeyl/Rhetoric/rhet1-1.html. Part 3: <a href="http://www.public.iastate.edu/~honeyl/Rhetoric/rhet3-19.html">http://www.public.iastate.edu/~honeyl/Rhetoric/rhet3-19.html</a>.</p>
|
105
|
+
<p>[16] Aristotle, Part I</p>
|
106
|
+
<p>[17] King, Martin Luther Jr. "Letter from a Birmingham Jail, in <em>A Peace Reader: Essential </em><em>Readings</em> <em>on War, Justice, Non-violence and World Order</em>. New York: Paulist Press, 1992, p. 115.</p>
|
107
|
+
<p>[18] King, p.128.</p>
|
108
|
+
<p>[19] King, p.115.</p>
|
109
|
+
<p>[20] Deutsch, Morton, "Producing Change in an Adversary," in <em>International Conflict and Behavioral Science: The Craigville Papers</em>. ed. Roger Fisher. New York: Basic Books, Inc., 1964, p. 151.</p>
|
110
|
+
<p>[21] Lilly, Carol S. <em>Power and Persuasion: Ideology and Rhetoric in Communist </em><em>Yugoslavia</em><em>: 1944-1953</em>. Boulder, CO: Westview Press, 2001, p. 7.</p>
|
111
|
+
<p>[22] Lilly, p. 8.</p>
|
112
|
+
<p>[23] Lilly, p. 30.</p>
|
113
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'html-renderer/base'
|
@@ -0,0 +1,171 @@
|
|
1
|
+
######################################################################################
|
2
|
+
require 'oga'
|
3
|
+
######################################################################################
|
4
|
+
#
|
5
|
+
# TODOs:
|
6
|
+
# - Streaming output (yield every paragraph/div/header)
|
7
|
+
# - Embed into 'c' tool (for rendering raw HTML blocks)
|
8
|
+
#
|
9
|
+
######################################################################################
|
10
|
+
|
11
|
+
class String
|
12
|
+
|
13
|
+
def tighten
|
14
|
+
gsub(/\s+/, ' ').strip
|
15
|
+
end
|
16
|
+
|
17
|
+
def blank?; !!self[/[^\s]/]; end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
class NilClass
|
22
|
+
def blank?; true; end
|
23
|
+
end
|
24
|
+
|
25
|
+
######################################################################################
|
26
|
+
|
27
|
+
module HTMLRenderer
|
28
|
+
|
29
|
+
class State
|
30
|
+
attr_accessor :list_order
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
@list_order = :unordered
|
34
|
+
end
|
35
|
+
|
36
|
+
def with(opts={})
|
37
|
+
newstate = dup
|
38
|
+
opts.each { |k,v| newstate.send("#{k}=", v) }
|
39
|
+
newstate
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Base
|
44
|
+
|
45
|
+
def self.render(input)
|
46
|
+
new.render(input)
|
47
|
+
end
|
48
|
+
|
49
|
+
def render(input)
|
50
|
+
doc = Oga.parse_html(input)
|
51
|
+
|
52
|
+
state = State.new
|
53
|
+
render_children(doc, state)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def render_children(node, state)
|
58
|
+
|
59
|
+
results = node.children.map do |node|
|
60
|
+
|
61
|
+
case node
|
62
|
+
|
63
|
+
when Oga::XML::Text
|
64
|
+
content = node.text
|
65
|
+
content.blank? ? normal_text(content) : nil
|
66
|
+
|
67
|
+
when Oga::XML::Element
|
68
|
+
case node.name
|
69
|
+
when "a"
|
70
|
+
url = node["href"]
|
71
|
+
title = node["title"]
|
72
|
+
content = render_children(node, state)
|
73
|
+
|
74
|
+
link(url, title, content)
|
75
|
+
|
76
|
+
when "img"
|
77
|
+
link = node["src"]
|
78
|
+
title = node["title"]
|
79
|
+
content = nil
|
80
|
+
|
81
|
+
image(link, title, content)
|
82
|
+
|
83
|
+
when /^h(\d)$/
|
84
|
+
level = $1.to_i
|
85
|
+
title = render_children(node, state)
|
86
|
+
header(title, level)
|
87
|
+
|
88
|
+
when "i", "strong"
|
89
|
+
italic(render_children(node, state))
|
90
|
+
when "em", "b"
|
91
|
+
emphasis(render_children(node, state))
|
92
|
+
when "sup"
|
93
|
+
superscript(render_children(node, state))
|
94
|
+
when "u"
|
95
|
+
underline(render_children(node, state))
|
96
|
+
when "br"
|
97
|
+
linebreak
|
98
|
+
when "hr"
|
99
|
+
separator
|
100
|
+
|
101
|
+
when "p"
|
102
|
+
paragraph(render_children(node, state).strip)
|
103
|
+
when "div"
|
104
|
+
div(render_children(node, state))
|
105
|
+
|
106
|
+
when "ul"
|
107
|
+
list(render_children(node, state), state.list_order)
|
108
|
+
when "ol"
|
109
|
+
content = render_children(node, state.with(:list_order => :ordered))
|
110
|
+
list(content, state.list_order)
|
111
|
+
when "li"
|
112
|
+
list_item(render_children(node, state), state.list_order)
|
113
|
+
|
114
|
+
when "code"
|
115
|
+
block_code(render_children(node, state))
|
116
|
+
when "blockquote"
|
117
|
+
block_quote(render_children(node, state))
|
118
|
+
|
119
|
+
when "table"
|
120
|
+
header = nil
|
121
|
+
rows = []
|
122
|
+
|
123
|
+
node.css("tr").each do |row|
|
124
|
+
if (cells = row.css("th")).any?
|
125
|
+
header = cells
|
126
|
+
elsif (cells = row.css("td")).any?
|
127
|
+
rows << cells
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
rows = rows.map do |row|
|
132
|
+
row.map do |cell|
|
133
|
+
render_children(cell, state)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
if header
|
138
|
+
header = header.map do |cell|
|
139
|
+
render_children(cell, state)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
table(header, rows)
|
144
|
+
|
145
|
+
when "html", "body", "nav", "span", "form", "label", "input", "button", "section", "fieldset",
|
146
|
+
"menu", "article", "header", "time", "aside", "footer", "nobr", "wbr",
|
147
|
+
"table", "tr", "td", "th", "thead", "tbody", "noscript"
|
148
|
+
render_children(node, state)
|
149
|
+
|
150
|
+
when "head", "script", "link", "style"
|
151
|
+
# skip it
|
152
|
+
|
153
|
+
else
|
154
|
+
raise "Unrecognized HTML tag: #{node.name} -> #{node.inspect}"
|
155
|
+
end
|
156
|
+
|
157
|
+
when Oga::XML::Comment
|
158
|
+
# skip it
|
159
|
+
|
160
|
+
else
|
161
|
+
raise "Unhandled Oga node type: #{node.class}"
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
results.join.strip
|
167
|
+
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: html-renderer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- epitron
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-05-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: oga
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ansi
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1'
|
41
|
+
description: Easily implement an HTML renderer by creating a subclass and adding some
|
42
|
+
methods, similar to RedCarpet. (Examples are included for rendering HTML to ANSI
|
43
|
+
and plain text.)
|
44
|
+
email: chris@ill-logic.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files:
|
48
|
+
- README.md
|
49
|
+
- LICENSE
|
50
|
+
files:
|
51
|
+
- ".gemspec"
|
52
|
+
- LICENSE
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- VERSION
|
56
|
+
- examples/ansi_renderer.rb
|
57
|
+
- examples/debug_renderer.rb
|
58
|
+
- examples/plain_text_renderer.rb
|
59
|
+
- examples/test.html
|
60
|
+
- lib/html-renderer.rb
|
61
|
+
- lib/html-renderer/base.rb
|
62
|
+
homepage: http://github.com/epitron/html-renderer/
|
63
|
+
licenses:
|
64
|
+
- WTFPL
|
65
|
+
metadata: {}
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 2.7.6
|
83
|
+
signing_key:
|
84
|
+
specification_version: 4
|
85
|
+
summary: HTML Renderer
|
86
|
+
test_files: []
|