ledger_web 1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/.gitignore +10 -0
  2. data/LICENSE +7 -0
  3. data/README.md +140 -0
  4. data/Rakefile +11 -0
  5. data/bin/ledger_web +14 -0
  6. data/ledger_web.gemspec +26 -0
  7. data/lib/ledger_web/app.rb +69 -0
  8. data/lib/ledger_web/config.rb +87 -0
  9. data/lib/ledger_web/db/migrate/20111226180900_initial_schema.rb +38 -0
  10. data/lib/ledger_web/db/migrate/20111231132900_add_views.rb +37 -0
  11. data/lib/ledger_web/db.rb +54 -0
  12. data/lib/ledger_web/helpers.rb +62 -0
  13. data/lib/ledger_web/public/bootstrap-dropdown.js +55 -0
  14. data/lib/ledger_web/public/bootstrap.min.css +356 -0
  15. data/lib/ledger_web/public/codemirror/keymap/emacs.js +29 -0
  16. data/lib/ledger_web/public/codemirror/keymap/vim.js +76 -0
  17. data/lib/ledger_web/public/codemirror/lib/codemirror.css +104 -0
  18. data/lib/ledger_web/public/codemirror/lib/codemirror.js +2761 -0
  19. data/lib/ledger_web/public/codemirror/lib/util/dialog.css +23 -0
  20. data/lib/ledger_web/public/codemirror/lib/util/dialog.js +63 -0
  21. data/lib/ledger_web/public/codemirror/lib/util/foldcode.js +66 -0
  22. data/lib/ledger_web/public/codemirror/lib/util/formatting.js +291 -0
  23. data/lib/ledger_web/public/codemirror/lib/util/javascript-hint.js +83 -0
  24. data/lib/ledger_web/public/codemirror/lib/util/overlay.js +51 -0
  25. data/lib/ledger_web/public/codemirror/lib/util/runmode.js +27 -0
  26. data/lib/ledger_web/public/codemirror/lib/util/search.js +114 -0
  27. data/lib/ledger_web/public/codemirror/lib/util/searchcursor.js +117 -0
  28. data/lib/ledger_web/public/codemirror/lib/util/simple-hint.css +16 -0
  29. data/lib/ledger_web/public/codemirror/lib/util/simple-hint.js +66 -0
  30. data/lib/ledger_web/public/codemirror/mode/clike/clike.js +249 -0
  31. data/lib/ledger_web/public/codemirror/mode/clike/index.html +101 -0
  32. data/lib/ledger_web/public/codemirror/mode/clojure/clojure.js +207 -0
  33. data/lib/ledger_web/public/codemirror/mode/clojure/index.html +66 -0
  34. data/lib/ledger_web/public/codemirror/mode/coffeescript/LICENSE +22 -0
  35. data/lib/ledger_web/public/codemirror/mode/coffeescript/coffeescript.js +325 -0
  36. data/lib/ledger_web/public/codemirror/mode/coffeescript/index.html +721 -0
  37. data/lib/ledger_web/public/codemirror/mode/css/css.js +124 -0
  38. data/lib/ledger_web/public/codemirror/mode/css/index.html +55 -0
  39. data/lib/ledger_web/public/codemirror/mode/diff/diff.css +3 -0
  40. data/lib/ledger_web/public/codemirror/mode/diff/diff.js +13 -0
  41. data/lib/ledger_web/public/codemirror/mode/diff/index.html +99 -0
  42. data/lib/ledger_web/public/codemirror/mode/gfm/gfm.js +108 -0
  43. data/lib/ledger_web/public/codemirror/mode/gfm/index.html +47 -0
  44. data/lib/ledger_web/public/codemirror/mode/groovy/groovy.js +210 -0
  45. data/lib/ledger_web/public/codemirror/mode/groovy/index.html +71 -0
  46. data/lib/ledger_web/public/codemirror/mode/haskell/haskell.js +242 -0
  47. data/lib/ledger_web/public/codemirror/mode/haskell/index.html +60 -0
  48. data/lib/ledger_web/public/codemirror/mode/htmlembedded/htmlembedded.js +68 -0
  49. data/lib/ledger_web/public/codemirror/mode/htmlembedded/index.html +49 -0
  50. data/lib/ledger_web/public/codemirror/mode/htmlmixed/htmlmixed.js +83 -0
  51. data/lib/ledger_web/public/codemirror/mode/htmlmixed/index.html +51 -0
  52. data/lib/ledger_web/public/codemirror/mode/javascript/index.html +77 -0
  53. data/lib/ledger_web/public/codemirror/mode/javascript/javascript.js +360 -0
  54. data/lib/ledger_web/public/codemirror/mode/jinja2/index.html +37 -0
  55. data/lib/ledger_web/public/codemirror/mode/jinja2/jinja2.js +42 -0
  56. data/lib/ledger_web/public/codemirror/mode/lua/index.html +72 -0
  57. data/lib/ledger_web/public/codemirror/mode/lua/lua.js +140 -0
  58. data/lib/ledger_web/public/codemirror/mode/markdown/index.html +339 -0
  59. data/lib/ledger_web/public/codemirror/mode/markdown/markdown.js +242 -0
  60. data/lib/ledger_web/public/codemirror/mode/ntriples/index.html +32 -0
  61. data/lib/ledger_web/public/codemirror/mode/ntriples/ntriples.js +172 -0
  62. data/lib/ledger_web/public/codemirror/mode/pascal/LICENSE +7 -0
  63. data/lib/ledger_web/public/codemirror/mode/pascal/index.html +48 -0
  64. data/lib/ledger_web/public/codemirror/mode/pascal/pascal.js +138 -0
  65. data/lib/ledger_web/public/codemirror/mode/perl/LICENSE +19 -0
  66. data/lib/ledger_web/public/codemirror/mode/perl/index.html +62 -0
  67. data/lib/ledger_web/public/codemirror/mode/perl/perl.js +816 -0
  68. data/lib/ledger_web/public/codemirror/mode/php/index.html +48 -0
  69. data/lib/ledger_web/public/codemirror/mode/php/php.js +120 -0
  70. data/lib/ledger_web/public/codemirror/mode/plsql/index.html +62 -0
  71. data/lib/ledger_web/public/codemirror/mode/plsql/plsql.js +217 -0
  72. data/lib/ledger_web/public/codemirror/mode/python/LICENSE.txt +21 -0
  73. data/lib/ledger_web/public/codemirror/mode/python/index.html +122 -0
  74. data/lib/ledger_web/public/codemirror/mode/python/python.js +333 -0
  75. data/lib/ledger_web/public/codemirror/mode/r/LICENSE +24 -0
  76. data/lib/ledger_web/public/codemirror/mode/r/index.html +73 -0
  77. data/lib/ledger_web/public/codemirror/mode/r/r.js +141 -0
  78. data/lib/ledger_web/public/codemirror/mode/rpm/changes/changes.js +19 -0
  79. data/lib/ledger_web/public/codemirror/mode/rpm/changes/index.html +53 -0
  80. data/lib/ledger_web/public/codemirror/mode/rpm/spec/index.html +99 -0
  81. data/lib/ledger_web/public/codemirror/mode/rpm/spec/spec.css +5 -0
  82. data/lib/ledger_web/public/codemirror/mode/rpm/spec/spec.js +66 -0
  83. data/lib/ledger_web/public/codemirror/mode/rst/index.html +525 -0
  84. data/lib/ledger_web/public/codemirror/mode/rst/rst.js +326 -0
  85. data/lib/ledger_web/public/codemirror/mode/ruby/LICENSE +24 -0
  86. data/lib/ledger_web/public/codemirror/mode/ruby/index.html +171 -0
  87. data/lib/ledger_web/public/codemirror/mode/ruby/ruby.js +195 -0
  88. data/lib/ledger_web/public/codemirror/mode/rust/index.html +48 -0
  89. data/lib/ledger_web/public/codemirror/mode/rust/rust.js +411 -0
  90. data/lib/ledger_web/public/codemirror/mode/scheme/index.html +64 -0
  91. data/lib/ledger_web/public/codemirror/mode/scheme/scheme.js +202 -0
  92. data/lib/ledger_web/public/codemirror/mode/smalltalk/index.html +55 -0
  93. data/lib/ledger_web/public/codemirror/mode/smalltalk/smalltalk.js +139 -0
  94. data/lib/ledger_web/public/codemirror/mode/sparql/index.html +40 -0
  95. data/lib/ledger_web/public/codemirror/mode/sparql/sparql.js +143 -0
  96. data/lib/ledger_web/public/codemirror/mode/stex/index.html +95 -0
  97. data/lib/ledger_web/public/codemirror/mode/stex/stex.js +167 -0
  98. data/lib/ledger_web/public/codemirror/mode/tiddlywiki/index.html +183 -0
  99. data/lib/ledger_web/public/codemirror/mode/tiddlywiki/tiddlywiki.css +21 -0
  100. data/lib/ledger_web/public/codemirror/mode/tiddlywiki/tiddlywiki.js +374 -0
  101. data/lib/ledger_web/public/codemirror/mode/velocity/index.html +103 -0
  102. data/lib/ledger_web/public/codemirror/mode/velocity/velocity.js +146 -0
  103. data/lib/ledger_web/public/codemirror/mode/xml/index.html +44 -0
  104. data/lib/ledger_web/public/codemirror/mode/xml/xml.js +252 -0
  105. data/lib/ledger_web/public/codemirror/mode/xmlpure/index.html +59 -0
  106. data/lib/ledger_web/public/codemirror/mode/xmlpure/xmlpure.js +485 -0
  107. data/lib/ledger_web/public/codemirror/mode/yaml/index.html +67 -0
  108. data/lib/ledger_web/public/codemirror/mode/yaml/yaml.js +95 -0
  109. data/lib/ledger_web/public/codemirror/theme/cobalt.css +18 -0
  110. data/lib/ledger_web/public/codemirror/theme/eclipse.css +25 -0
  111. data/lib/ledger_web/public/codemirror/theme/elegant.css +10 -0
  112. data/lib/ledger_web/public/codemirror/theme/monokai.css +28 -0
  113. data/lib/ledger_web/public/codemirror/theme/neat.css +9 -0
  114. data/lib/ledger_web/public/codemirror/theme/night.css +21 -0
  115. data/lib/ledger_web/public/codemirror/theme/rubyblue.css +21 -0
  116. data/lib/ledger_web/public/jquery-1.7.1.min.js +4 -0
  117. data/lib/ledger_web/public/jquery.tablesorter.min.js +4 -0
  118. data/lib/ledger_web/public/ledger.css +14 -0
  119. data/lib/ledger_web/report.rb +187 -0
  120. data/lib/ledger_web/reports/savings_rate.erb +49 -0
  121. data/lib/ledger_web/version.rb +3 -0
  122. data/lib/ledger_web/views/error.erb +5 -0
  123. data/lib/ledger_web/views/help.erb +6 -0
  124. data/lib/ledger_web/views/layout.erb +44 -0
  125. data/lib/ledger_web/views/table.erb +31 -0
  126. data/lib/ledger_web/watcher.rb +37 -0
  127. data/lib/ledger_web.rb +20 -0
  128. metadata +229 -0
@@ -0,0 +1,326 @@
1
+ CodeMirror.defineMode('rst', function(config, options) {
2
+ function setState(state, fn, ctx) {
3
+ state.fn = fn;
4
+ setCtx(state, ctx);
5
+ }
6
+
7
+ function setCtx(state, ctx) {
8
+ state.ctx = ctx || {};
9
+ }
10
+
11
+ function setNormal(state, ch) {
12
+ if (ch && (typeof ch !== 'string')) {
13
+ var str = ch.current();
14
+ ch = str[str.length-1];
15
+ }
16
+
17
+ setState(state, normal, {back: ch});
18
+ }
19
+
20
+ function hasMode(mode) {
21
+ if (mode) {
22
+ var modes = CodeMirror.listModes();
23
+
24
+ for (var i in modes) {
25
+ if (modes[i] == mode) {
26
+ return true;
27
+ }
28
+ }
29
+ }
30
+
31
+ return false;
32
+ }
33
+
34
+ function getMode(mode) {
35
+ if (hasMode(mode)) {
36
+ return CodeMirror.getMode(config, mode);
37
+ } else {
38
+ return null;
39
+ }
40
+ }
41
+
42
+ var verbatimMode = getMode(options.verbatim);
43
+ var pythonMode = getMode('python');
44
+
45
+ var reSection = /^[!"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]/;
46
+ var reDirective = /^\s*\w([-:.\w]*\w)?::(\s|$)/;
47
+ var reHyperlink = /^\s*_[\w-]+:(\s|$)/;
48
+ var reFootnote = /^\s*\[(\d+|#)\](\s|$)/;
49
+ var reCitation = /^\s*\[[A-Za-z][\w-]*\](\s|$)/;
50
+ var reFootnoteRef = /^\[(\d+|#)\]_/;
51
+ var reCitationRef = /^\[[A-Za-z][\w-]*\]_/;
52
+ var reDirectiveMarker = /^\.\.(\s|$)/;
53
+ var reVerbatimMarker = /^::\s*$/;
54
+ var rePreInline = /^[-\s"([{</:]/;
55
+ var rePostInline = /^[-\s`'")\]}>/:.,;!?\\_]/;
56
+ var reEnumeratedList = /^\s*((\d+|[A-Za-z#])[.)]|\((\d+|[A-Z-a-z#])\))\s/;
57
+ var reBulletedList = /^\s*[-\+\*]\s/;
58
+ var reExamples = /^\s+(>>>|In \[\d+\]:)\s/;
59
+
60
+ function normal(stream, state) {
61
+ var ch, sol, i;
62
+
63
+ if (stream.eat(/\\/)) {
64
+ ch = stream.next();
65
+ setNormal(state, ch);
66
+ return null;
67
+ }
68
+
69
+ sol = stream.sol();
70
+
71
+ if (sol && (ch = stream.eat(reSection))) {
72
+ for (i = 0; stream.eat(ch); i++);
73
+
74
+ if (i >= 3 && stream.match(/^\s*$/)) {
75
+ setNormal(state, null);
76
+ return 'header';
77
+ } else {
78
+ stream.backUp(i + 1);
79
+ }
80
+ }
81
+
82
+ if (sol && stream.match(reDirectiveMarker)) {
83
+ if (!stream.eol()) {
84
+ setState(state, directive);
85
+ }
86
+ return 'meta';
87
+ }
88
+
89
+ if (stream.match(reVerbatimMarker)) {
90
+ if (!verbatimMode) {
91
+ setState(state, verbatim);
92
+ } else {
93
+ var mode = verbatimMode;
94
+
95
+ setState(state, verbatim, {
96
+ mode: mode,
97
+ local: mode.startState()
98
+ });
99
+ }
100
+ return 'meta';
101
+ }
102
+
103
+ if (sol && stream.match(reExamples, false)) {
104
+ if (!pythonMode) {
105
+ setState(state, verbatim);
106
+ return 'meta';
107
+ } else {
108
+ var mode = pythonMode;
109
+
110
+ setState(state, verbatim, {
111
+ mode: mode,
112
+ local: mode.startState()
113
+ });
114
+
115
+ return null;
116
+ }
117
+ }
118
+
119
+ function testBackward(re) {
120
+ return sol || !state.ctx.back || re.test(state.ctx.back);
121
+ }
122
+
123
+ function testForward(re) {
124
+ return stream.eol() || stream.match(re, false);
125
+ }
126
+
127
+ function testInline(re) {
128
+ return stream.match(re) && testBackward(/\W/) && testForward(/\W/);
129
+ }
130
+
131
+ if (testInline(reFootnoteRef)) {
132
+ setNormal(state, stream);
133
+ return 'footnote';
134
+ }
135
+
136
+ if (testInline(reCitationRef)) {
137
+ setNormal(state, stream);
138
+ return 'citation';
139
+ }
140
+
141
+ ch = stream.next();
142
+
143
+ if (testBackward(rePreInline)) {
144
+ if ((ch === ':' || ch === '|') && stream.eat(/\S/)) {
145
+ var token;
146
+
147
+ if (ch === ':') {
148
+ token = 'builtin';
149
+ } else {
150
+ token = 'atom';
151
+ }
152
+
153
+ setState(state, inline, {
154
+ ch: ch,
155
+ wide: false,
156
+ prev: null,
157
+ token: token
158
+ });
159
+
160
+ return token;
161
+ }
162
+
163
+ if (ch === '*' || ch === '`') {
164
+ var orig = ch,
165
+ wide = false;
166
+
167
+ ch = stream.next();
168
+
169
+ if (ch == orig) {
170
+ wide = true;
171
+ ch = stream.next();
172
+ }
173
+
174
+ if (ch && !/\s/.test(ch)) {
175
+ var token;
176
+
177
+ if (orig === '*') {
178
+ token = wide ? 'strong' : 'em';
179
+ } else {
180
+ token = wide ? 'string' : 'string-2';
181
+ }
182
+
183
+ setState(state, inline, {
184
+ ch: orig, // inline() has to know what to search for
185
+ wide: wide, // are we looking for `ch` or `chch`
186
+ prev: null, // terminator must not be preceeded with whitespace
187
+ token: token // I don't want to recompute this all the time
188
+ });
189
+
190
+ return token;
191
+ }
192
+ }
193
+ }
194
+
195
+ setNormal(state, ch);
196
+ return null;
197
+ }
198
+
199
+ function inline(stream, state) {
200
+ var ch = stream.next(),
201
+ token = state.ctx.token;
202
+
203
+ function finish(ch) {
204
+ state.ctx.prev = ch;
205
+ return token;
206
+ }
207
+
208
+ if (ch != state.ctx.ch) {
209
+ return finish(ch);
210
+ }
211
+
212
+ if (/\s/.test(state.ctx.prev)) {
213
+ return finish(ch);
214
+ }
215
+
216
+ if (state.ctx.wide) {
217
+ ch = stream.next();
218
+
219
+ if (ch != state.ctx.ch) {
220
+ return finish(ch);
221
+ }
222
+ }
223
+
224
+ if (!stream.eol() && !rePostInline.test(stream.peek())) {
225
+ if (state.ctx.wide) {
226
+ stream.backUp(1);
227
+ }
228
+
229
+ return finish(ch);
230
+ }
231
+
232
+ setState(state, normal);
233
+ setNormal(state, ch);
234
+
235
+ return token;
236
+ }
237
+
238
+ function directive(stream, state) {
239
+ var token = null;
240
+
241
+ if (stream.match(reDirective)) {
242
+ token = 'attribute';
243
+ } else if (stream.match(reHyperlink)) {
244
+ token = 'link';
245
+ } else if (stream.match(reFootnote)) {
246
+ token = 'quote';
247
+ } else if (stream.match(reCitation)) {
248
+ token = 'quote';
249
+ } else {
250
+ stream.eatSpace();
251
+
252
+ if (stream.eol()) {
253
+ setNormal(state, stream);
254
+ return null;
255
+ } else {
256
+ stream.skipToEnd();
257
+ setState(state, comment);
258
+ return 'comment';
259
+ }
260
+ }
261
+
262
+ // FIXME this is unreachable
263
+ setState(state, body, {start: true});
264
+ return token;
265
+ }
266
+
267
+ function body(stream, state) {
268
+ var token = 'body';
269
+
270
+ if (!state.ctx.start || stream.sol()) {
271
+ return block(stream, state, token);
272
+ }
273
+
274
+ stream.skipToEnd();
275
+ setCtx(state);
276
+
277
+ return token;
278
+ }
279
+
280
+ function comment(stream, state) {
281
+ return block(stream, state, 'comment');
282
+ }
283
+
284
+ function verbatim(stream, state) {
285
+ if (!verbatimMode) {
286
+ return block(stream, state, 'meta');
287
+ } else {
288
+ if (stream.sol()) {
289
+ if (!stream.eatSpace()) {
290
+ setNormal(state, stream);
291
+ }
292
+
293
+ return null;
294
+ }
295
+
296
+ return verbatimMode.token(stream, state.ctx.local);
297
+ }
298
+ }
299
+
300
+ function block(stream, state, token) {
301
+ if (stream.eol() || stream.eatSpace()) {
302
+ stream.skipToEnd();
303
+ return token;
304
+ } else {
305
+ setNormal(state, stream);
306
+ return null;
307
+ }
308
+ }
309
+
310
+ return {
311
+ startState: function() {
312
+ return {fn: normal, ctx: {}};
313
+ },
314
+
315
+ copyState: function(state) {
316
+ return {fn: state.fn, ctx: state.ctx};
317
+ },
318
+
319
+ token: function(stream, state) {
320
+ var token = state.fn(stream, state);
321
+ return token;
322
+ }
323
+ };
324
+ });
325
+
326
+ CodeMirror.defineMIME("text/x-rst", "rst");
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2011, Ubalo, Inc.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of the Ubalo, Inc. nor the names of its
12
+ contributors may be used to endorse or promote products derived
13
+ from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL UBALO, INC BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,171 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>CodeMirror: Ruby mode</title>
5
+ <link rel="stylesheet" href="../../lib/codemirror.css">
6
+ <script src="../../lib/codemirror.js"></script>
7
+ <script src="ruby.js"></script>
8
+ <style>
9
+ .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
10
+ .cm-s-default span.cm-arrow { color: red; }
11
+ </style>
12
+ <link rel="stylesheet" href="../../doc/docs.css">
13
+ </head>
14
+ <body>
15
+ <h1>CodeMirror: Ruby mode</h1>
16
+ <form><textarea id="code" name="code">
17
+ # Code from http://sandbox.mc.edu/~bennet/ruby/code/poly_rb.html
18
+ #
19
+ # This program evaluates polynomials. It first asks for the coefficients
20
+ # of a polynomial, which must be entered on one line, highest-order first.
21
+ # It then requests values of x and will compute the value of the poly for
22
+ # each x. It will repeatly ask for x values, unless you the user enters
23
+ # a blank line. It that case, it will ask for another polynomial. If the
24
+ # user types quit for either input, the program immediately exits.
25
+ #
26
+
27
+ #
28
+ # Function to evaluate a polynomial at x. The polynomial is given
29
+ # as a list of coefficients, from the greatest to the least.
30
+ def polyval(x, coef)
31
+ sum = 0
32
+ coef = coef.clone # Don't want to destroy the original
33
+ while true
34
+ sum += coef.shift # Add and remove the next coef
35
+ break if coef.empty? # If no more, done entirely.
36
+ sum *= x # This happens the right number of times.
37
+ end
38
+ return sum
39
+ end
40
+
41
+ #
42
+ # Function to read a line containing a list of integers and return
43
+ # them as an array of integers. If the string conversion fails, it
44
+ # throws TypeError. If the input line is the word 'quit', then it
45
+ # converts it to an end-of-file exception
46
+ def readints(prompt)
47
+ # Read a line
48
+ print prompt
49
+ line = readline.chomp
50
+ raise EOFError.new if line == 'quit' # You can also use a real EOF.
51
+
52
+ # Go through each item on the line, converting each one and adding it
53
+ # to retval.
54
+ retval = [ ]
55
+ for str in line.split(/\s+/)
56
+ if str =~ /^\-?\d+$/
57
+ retval.push(str.to_i)
58
+ else
59
+ raise TypeError.new
60
+ end
61
+ end
62
+
63
+ return retval
64
+ end
65
+
66
+ #
67
+ # Take a coeff and an exponent and return the string representation, ignoring
68
+ # the sign of the coefficient.
69
+ def term_to_str(coef, exp)
70
+ ret = ""
71
+
72
+ # Show coeff, unless it's 1 or at the right
73
+ coef = coef.abs
74
+ ret = coef.to_s unless coef == 1 && exp > 0
75
+ ret += "x" if exp > 0 # x if exponent not 0
76
+ ret += "^" + exp.to_s if exp > 1 # ^exponent, if > 1.
77
+
78
+ return ret
79
+ end
80
+
81
+ #
82
+ # Create a string of the polynomial in sort-of-readable form.
83
+ def polystr(p)
84
+ # Get the exponent of first coefficient, plus 1.
85
+ exp = p.length
86
+
87
+ # Assign exponents to each term, making pairs of coeff and exponent,
88
+ # Then get rid of the zero terms.
89
+ p = (p.map { |c| exp -= 1; [ c, exp ] }).select { |p| p[0] != 0 }
90
+
91
+ # If there's nothing left, it's a zero
92
+ return "0" if p.empty?
93
+
94
+ # *** Now p is a non-empty list of [ coef, exponent ] pairs. ***
95
+
96
+ # Convert the first term, preceded by a "-" if it's negative.
97
+ result = (if p[0][0] < 0 then "-" else "" end) + term_to_str(*p[0])
98
+
99
+ # Convert the rest of the terms, in each case adding the appropriate
100
+ # + or - separating them.
101
+ for term in p[1...p.length]
102
+ # Add the separator then the rep. of the term.
103
+ result += (if term[0] < 0 then " - " else " + " end) +
104
+ term_to_str(*term)
105
+ end
106
+
107
+ return result
108
+ end
109
+
110
+ #
111
+ # Run until some kind of endfile.
112
+ begin
113
+ # Repeat until an exception or quit gets us out.
114
+ while true
115
+ # Read a poly until it works. An EOF will except out of the
116
+ # program.
117
+ print "\n"
118
+ begin
119
+ poly = readints("Enter a polynomial coefficients: ")
120
+ rescue TypeError
121
+ print "Try again.\n"
122
+ retry
123
+ end
124
+ break if poly.empty?
125
+
126
+ # Read and evaluate x values until the user types a blank line.
127
+ # Again, an EOF will except out of the pgm.
128
+ while true
129
+ # Request an integer.
130
+ print "Enter x value or blank line: "
131
+ x = readline.chomp
132
+ break if x == ''
133
+ raise EOFError.new if x == 'quit'
134
+
135
+ # If it looks bad, let's try again.
136
+ if x !~ /^\-?\d+$/
137
+ print "That doesn't look like an integer. Please try again.\n"
138
+ next
139
+ end
140
+
141
+ # Convert to an integer and print the result.
142
+ x = x.to_i
143
+ print "p(x) = ", polystr(poly), "\n"
144
+ print "p(", x, ") = ", polyval(x, poly), "\n"
145
+ end
146
+ end
147
+ rescue EOFError
148
+ print "\n=== EOF ===\n"
149
+ rescue Interrupt, SignalException
150
+ print "\n=== Interrupted ===\n"
151
+ else
152
+ print "--- Bye ---\n"
153
+ end
154
+ </textarea></form>
155
+ <script>
156
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
157
+ mode: "text/x-ruby",
158
+ tabMode: "indent",
159
+ matchBrackets: true,
160
+ indentUnit: 4
161
+ });
162
+ </script>
163
+
164
+ <p><strong>MIME types defined:</strong> <code>text/x-ruby</code>.</p>
165
+
166
+ <p>Development of the CodeMirror Ruby mode was kindly sponsored
167
+ by <a href="http://ubalo.com/">Ubalo</a>, who hold
168
+ the <a href="LICENSE">license</a>.</p>
169
+
170
+ </body>
171
+ </html>