html-renderer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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.
@@ -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)
@@ -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,14 @@
1
+ require 'html-renderer'
2
+
3
+ class DebugRenderer < HTMLRenderer::Base
4
+
5
+ def method_missing(meth, *args)
6
+ "#{meth}(#{args})"
7
+ end
8
+
9
+ end
10
+
11
+
12
+ if __FILE__ == $0
13
+ puts DebugRenderer.render(open("test.html"))
14
+ 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
@@ -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 &quot;power&quot; is generally considered to be coercion or force, persuasion can be powerful too, as is evidenced by the common saying, &quot;the power of persuasion.&quot;</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 &quot;influence&quot; in a way similar to my use of the word &quot;power,&quot; &quot;the capacity to bring about change.&quot; 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 &quot;how&quot; of the change.</p>
7
+ <p>Sometimes, social-influence scholars include under the term &quot;persuasion&quot; 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 &quot;persuasion&quot; 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&#39;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 &quot;law of reciprocity,&quot; 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&#39;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. &quot;So affected was the German by this gift that he could not complete his mission. He turned from his benefactor and recrossed no-man&#39;s-land empty-handed to face the wrath of his superiors.&quot;[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&#39;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&#39; 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 &quot;monkey see, monkey do&quot; 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&#39;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 &quot;last chance&quot; or &quot;one of a kind&quot; strategies. &quot;According to the scarcity principle, people assign more value to opportunities when they are less available.&quot;[4] As with the &quot;norm of reciprocity,&quot; 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&#39;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&#39;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
+ &quot;A second kind of argument points out complementary interests that would be enhanced by yielding what is sought.&quot;[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
+ &quot;A third kind of persuasive argument tries to turn a divisive issue into a problem that is shared and needs a mutually satisfactory solution.&quot;[7] In the conflict-resolution literature, this is an example of what is called &quot;<a href="http://www.beyondintractability.org/bi-essay/framing">reframing</a>.&quot; 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 &quot;appeals to common values and norms ... The appeal is made to abstract principles, shared identifications or previously neglected values.&quot;[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&#39;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&#39;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&#39;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, &quot;we nonetheless feel uncomfortable when made aware of inconsistencies. When these inconsistencies become obvious, we feel a strain to change.&quot;[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 &quot;separate but equal&quot; 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&#39;s self-esteem was damaged by segregation.[12] Myrdal&#39;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>, &quot;excit(ing) the required state of emotion in your hearer,&quot; as an integral aspect of the final stage in an argument.[15] At the outset of <em>Rhetoric,</em> however, he points out that &quot;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.&quot; Later, he states more strongly: &quot;It is not right to pervert the judge by moving him to anger or envy or pity -- one might as well warp a carpenter&#39;s rule before using it.&quot;[16] This identifies the dilemma of emotional appeals. A strong argument needs facts at its base, and even the strongest may not &quot;move&quot; the other to change behavior without an appropriate emotional appeal.</p>
61
+ <div class="essay-head3">
62
+ Example: Martin Luther King&#39;s &quot;Letter from a Birmingham Jail&quot;</div>
63
+ <p>Martin Luther King Jr.&#39;s &quot;Letter from a Birmingham Jail,&quot; 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 &quot;MY DEAR FELLOW CLERGYMEN.&quot; He thus establishes kinship with his audience from the outset with the word &quot;fellow&quot;; later on he deepens the connection, calling them &quot;my Christian and Jewish brothers.&quot; He provides data to counter perceptions of himself as an &quot;outside agitator,&quot; providing information on his &quot;organizational ties&quot; 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 &quot;thus saith the Lord&quot; 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 &quot;probably the most thoroughly segregated city in the United States.&quot; 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&#39;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>&quot;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.&quot;[19]</p>
71
+ <p>I have chosen to draw my references to the &quot;Letter from a Birmingham Jail&quot; from a current peace-studies reader rather than from its original source or from King&#39;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&#39;s strategy for persuading the United States&nbsp;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 &quot;four critical tasks&quot; 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&#39;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&#39;s will in all conflicts.</p>
83
+ <p>Carol S. Lilly&#39;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 &quot;could help realize the party&#39;s political and economic policies but it could not effect the long-term cultural transformation of society.&quot;[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&#39;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&#39;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&#39;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&#39;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. &quot;Introduction to Influence,&quot; <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 &amp; 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&amp;vol=347&amp;invol=483">http://caselaw.lp.findlaw.com/cgi-bin/getcase.pl?court=US&amp;vol=347&amp;invol=483</a>.</p>
101
+ <p>[12] &quot;Kenneth B. Clark, activist, psychologist, and author,&quot; <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. &quot;Black-White Relations: The American Dilemma,&quot; <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, &quot;The Brown Decision,&quot; 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. &quot;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, &quot;Producing Change in an Adversary,&quot; 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: []