lingo 1.8.3 → 1.8.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/lingo/error.rb CHANGED
@@ -26,7 +26,17 @@
26
26
 
27
27
  class Lingo
28
28
 
29
- class LingoError < StandardError; end
29
+ class LingoError < StandardError
30
+
31
+ def class_name
32
+ klass.name.split('::').last
33
+ end
34
+
35
+ def error(msg = 'An error occurred')
36
+ "#{msg}: #{err} (#{err.class})"
37
+ end
38
+
39
+ end
30
40
 
31
41
  class NoWritableStoreError < LingoError
32
42
 
@@ -79,7 +89,7 @@ class Lingo
79
89
  end
80
90
 
81
91
  def to_s
82
- "An error occured when trying to #{action} `#{file}': #{err} (#{err.class})"
92
+ error("An error occured when trying to #{action} `#{file}'")
83
93
  end
84
94
 
85
95
  end
@@ -103,7 +113,7 @@ class Lingo
103
113
  end
104
114
 
105
115
  def to_s
106
- "Error loading config: #{err}"
116
+ error("Error loading config")
107
117
  end
108
118
 
109
119
  end
@@ -170,7 +180,21 @@ class Lingo
170
180
  end
171
181
 
172
182
  def to_s
173
- "No such #{klass.name.split('::').last} type `#{name}'."
183
+ "No such #{class_name} type `#{name}'."
184
+ end
185
+
186
+ end
187
+
188
+ class LibraryLoadError < LingoError
189
+
190
+ attr_reader :klass, :lib, :err
191
+
192
+ def initialize(klass, lib, err)
193
+ @klass, @lib, @err = klass, lib, err
194
+ end
195
+
196
+ def to_s
197
+ error("#{class_name}: An error occured while trying to load '#{lib}'")
174
198
  end
175
199
 
176
200
  end
@@ -131,16 +131,16 @@ class Lingo
131
131
  def test_compound(fstr, infix, bstr, level = 1, tail = false)
132
132
  sta, seq, empty = [fstr.length, bstr.length], %w[? ?], [[], [], '']
133
133
 
134
- if !(blex = @dic.select_with_suffix(bstr)).sort!.empty?
134
+ if !Lingo.sort!(blex = @dic.select_with_suffix(bstr)).empty?
135
135
  # 1. Word w/ suffix
136
136
  bform, seq[1] = tail ? bstr : blex.first.form, blex.first.attr
137
- elsif tail && !(blex = @dic.select_with_infix(bstr)).sort!.empty?
137
+ elsif tail && !Lingo.sort!(blex = @dic.select_with_infix(bstr)).empty?
138
138
  # 2. Word w/ infix, unless tail part
139
139
  bform, seq[1] = bstr, blex.first.attr
140
140
  elsif infix == '-'
141
141
  blex, bsta, bseq = find_compound(bstr, level + 1, tail)
142
142
 
143
- if !blex.sort!.empty?
143
+ if !Lingo.sort!(blex).empty?
144
144
  # 3. Compound
145
145
  bform, seq[1], sta[1..-1] = blex.first.form, bseq, bsta
146
146
  else
@@ -151,13 +151,13 @@ class Lingo
151
151
  return empty
152
152
  end
153
153
 
154
- if !(flex = @dic.select_with_infix(fstr)).sort!.empty?
154
+ if !Lingo.sort!(flex = @dic.select_with_infix(fstr)).empty?
155
155
  # 1. Word w/ infix
156
156
  fform, seq[0] = fstr, flex.first.attr
157
157
  else
158
158
  flex, fsta, fseq = find_compound(fstr, level + 1, true)
159
159
 
160
- if !flex.sort!.empty?
160
+ if !Lingo.sort!(flex).empty?
161
161
  # 2. Compound
162
162
  fform, seq[0], sta[0..0] = flex.first.form, fseq, fsta
163
163
  elsif infix == '-'
@@ -173,9 +173,9 @@ class Lingo
173
173
  }
174
174
 
175
175
  flex.concat(blex).delete_if { |l| l.attr == LA_COMPOUND }.
176
- push(Lexical.new(fform + infix + bform, LA_COMPOUND)).sort!
176
+ push(Lexical.new(fform + infix + bform, LA_COMPOUND))
177
177
 
178
- [flex, sta, seq.join]
178
+ [Lingo.sort!(flex), sta, seq.join]
179
179
  end
180
180
 
181
181
  end
@@ -73,7 +73,7 @@ class Lingo
73
73
 
74
74
  def lexicals=(lex)
75
75
  if lex.is_a?(Array)
76
- @lexicals = lex.sort.uniq
76
+ @lexicals = Lingo.sort(lex).uniq
77
77
  else
78
78
  raise TypeError, "wrong argument type #{lex.class} (expected Array)"
79
79
  end
@@ -82,7 +82,7 @@ class Lingo
82
82
  def add_lexicals(lex)
83
83
  unless lex.empty?
84
84
  @lexicals.concat(lex).uniq!
85
- @lexicals.sort!
85
+ Lingo.sort!(@lexicals)
86
86
  end
87
87
  end
88
88
 
@@ -122,6 +122,10 @@ class Lingo
122
122
  attr == WA_COMPOUND && get_class('x+').empty?
123
123
  end
124
124
 
125
+ def multiword_size(wc_re = LA_MULTIWORD)
126
+ lex = get_class(wc_re).first and lex.form.count(' ') + 1
127
+ end
128
+
125
129
  def <<(*other)
126
130
  other.flatten!
127
131
  lexicals.concat(other)
@@ -38,7 +38,7 @@ class Lingo
38
38
 
39
39
  attr_accessor :form, :attr, :src
40
40
 
41
- def initialize(form, attr = '-', src = nil)
41
+ def initialize(form, attr = WA_UNSET, src = nil)
42
42
  @form, @attr, @src = form || '', attr || '', src
43
43
  end
44
44
 
@@ -28,7 +28,7 @@ class Lingo
28
28
 
29
29
  class ShowProgress
30
30
 
31
- def initialize(obj, max, name = nil, doit = true, text = 'progress')
31
+ def initialize(obj, max, name = nil, doit = true, text = 'progress', nl = true)
32
32
  return yield self unless max && doit
33
33
 
34
34
  @out = obj.instance_variable_get(:@lingo).config.stderr
@@ -53,7 +53,8 @@ class Lingo
53
53
 
54
54
  yield self
55
55
 
56
- print "#{@clr} done.\n"
56
+ print "#{@clr} done."
57
+ print "\n" if nl
57
58
  end
58
59
 
59
60
  def [](value)
data/lib/lingo/srv.rb CHANGED
@@ -24,7 +24,6 @@
24
24
  ###############################################################################
25
25
  #++
26
26
 
27
- require 'json'
28
27
  require_relative 'app'
29
28
 
30
29
  class Lingo
@@ -44,14 +43,24 @@ class Lingo
44
43
  post('/') { doit }
45
44
 
46
45
  def doit
47
- q = params[:q]
48
- r = LINGO.talk(q) if q && !q.empty?
46
+ to_json(q = params[:q], case q
47
+ when String then talk(q)
48
+ when Array then q.inject({}) { |h, k| h[k] = talk(k); h }
49
+ end)
50
+ end
51
+
52
+ def talk(q)
53
+ r = LINGO.talk(q) unless q.empty?
54
+ return r unless r && SRC_SEP
49
55
 
50
- r = r.inject(Hash.new { |h, k| h[k] = [] }) { |h, s|
56
+ r.inject(Hash.new { |h, k| h[k] = [] }) { |h, s|
51
57
  a, b = s.split(SRC_SEP, 2); h[b] << a; h
52
- } if r && SRC_SEP
58
+ }
59
+ end
53
60
 
54
- to_json(q, r)
61
+ if ENV['LINGO_NO_SORT']
62
+ alias_method :_talk, :talk
63
+ def talk(q) _talk(q).to_a end
55
64
  end
56
65
 
57
66
  end
@@ -7,7 +7,7 @@ meeting:
7
7
  - word_searcher: { source: sys-dic, mode: first }
8
8
  - decomposer: { source: sys-dic }
9
9
  - multi_worder: { source: sys-mul }
10
- - sequencer: { stopper: PUNC,OTHR }
10
+ - sequencer: { stopper: 'PUNC,OTHR' }
11
11
  - synonymer: { skip: '?,t', source: sys-syn }
12
12
 
13
13
  - vector_filter: { debug: 'true', prompt: '' }
data/lib/lingo/version.rb CHANGED
@@ -4,7 +4,7 @@ class Lingo
4
4
 
5
5
  MAJOR = 1
6
6
  MINOR = 8
7
- TINY = 3
7
+ TINY = 4
8
8
 
9
9
  class << self
10
10
 
data/lib/lingo/web.rb CHANGED
@@ -24,8 +24,8 @@
24
24
  ###############################################################################
25
25
  #++
26
26
 
27
- require 'json'
28
- require 'nuggets/util/ruby'
27
+ require 'strscan'
28
+ require 'nuggets/ruby'
29
29
 
30
30
  require_relative 'app'
31
31
 
@@ -35,7 +35,7 @@ class Lingo
35
35
 
36
36
  init_app(__FILE__)
37
37
 
38
- UILANGS, LANGS = %w[en de], Lingo.list(:lang).map! { |lang|
38
+ HL, L = %w[en de ru], Lingo.list(:lang).map! { |lang|
39
39
  lang[%r{.*/(\w+)\.}, 1]
40
40
  }.uniq.sort!
41
41
 
@@ -50,15 +50,45 @@ class Lingo
50
50
 
51
51
  LINGO = Hash.new { |h, k| h[k] = Lingo.call(cfg, ['-l', k]) }
52
52
 
53
+ CFG, s = '', StringScanner.new('')
54
+ c = lambda { |n| %Q{<span style="color:#{n}">#{s.matched}</span>} }
55
+
56
+ File.foreach(cfg) { |line|
57
+ s.string = line.chomp
58
+
59
+ until s.eos?
60
+ CFG << if s.scan(/\s+/) then c[:black]
61
+ elsif s.scan(/---|[{}:]/) then c[:purple]
62
+ elsif s.scan(/-/) then c[:olive]
63
+ elsif s.scan(/,/) then c[:black]
64
+ elsif s.scan(/[\w-]+/) then c[s.peek(1) == ':' ? :teal : :black]
65
+ elsif s.scan(/'.*?'/) then c[:maroon]
66
+ elsif s.scan(/"/)
67
+ buf = c[:maroon]
68
+
69
+ until s.scan(/"/)
70
+ buf << (s.scan(/\\\w/) ? c[:purple] : (s.scan(/./); c[:maroon]))
71
+ end
72
+
73
+ buf << c[:maroon]
74
+ else s.rest
75
+ end
76
+ end
77
+
78
+ CFG << "\n"
79
+ }
80
+
53
81
  before do
54
- @uilang = if hal = env['HTTP_ACCEPT_LANGUAGE']
55
- hals = hal.split(',').map { |l| l.split('-').first.strip }
56
- (hals & UILANGS).first
57
- end || UILANGS.first
82
+ @hl = if v = params[:hl] || cookies[:hl] || env['HTTP_ACCEPT_LANGUAGE']
83
+ v = v.split(',').map { |l| l.split('-').first.strip }
84
+ (v & HL).first
85
+ end || HL.first
86
+
87
+ cookies[:hl] = @hl unless cookies[:hl] == @hl
58
88
 
59
89
  @q = params[:q]
60
- @l = params[:l] || @uilang
61
- @l = LANGS.first unless LANGS.include?(@l)
90
+ @l = params[:l] || @hl
91
+ @l = L.first unless L.include?(@l)
62
92
  end
63
93
 
64
94
  get('') { redirect url_for('/') }
@@ -71,7 +101,7 @@ class Lingo
71
101
  end
72
102
 
73
103
  def t(*t)
74
- (i = UILANGS.index(@uilang)) && t[i] || t.first
104
+ (i = HL.index(@hl)) && t[i] || t.first
75
105
  end
76
106
  end
77
107
 
@@ -7,7 +7,7 @@ meeting:
7
7
  - word_searcher: { source: sys-dic, mode: first }
8
8
  - decomposer: { source: sys-dic }
9
9
  - multi_worder: { source: sys-mul }
10
- - sequencer: { stopper: PUNC,OTHR }
10
+ - sequencer: { stopper: 'PUNC,OTHR' }
11
11
  - synonymer: { skip: '?,t', source: sys-syn }
12
12
 
13
13
  - vector_filter: { debug: 'true', prompt: '' }
@@ -1,5 +1,6 @@
1
1
  html, body {
2
2
  margin-top: 0;
3
+ font-size: 90%;
3
4
  }
4
5
 
5
6
  a img {
@@ -22,16 +23,18 @@ textarea {
22
23
  }
23
24
 
24
25
  #welcome {
25
- font-size: 70%;
26
+ font-size: 85%;
26
27
  color: #333333;
27
28
  margin-bottom: 0.5em;
28
29
  text-align: center;
30
+ margin: 0 15%;
29
31
  }
30
32
 
31
- #legend {
32
- font-size: 75%;
33
+ #legend, #config {
33
34
  color: #333333;
34
35
  margin-bottom: 0.5em;
36
+ width: 50%;
37
+ float: left;
35
38
  }
36
39
 
37
40
  #legend table {
@@ -39,13 +42,13 @@ textarea {
39
42
  }
40
43
 
41
44
  #legend th {
42
- font-size: 110%;
43
45
  font-weight: normal;
44
46
  font-family: monospace;
45
47
  text-align: left;
46
48
  }
47
49
 
48
50
  #legend td {
51
+ font-size: 85%;
49
52
  padding-left: 1em;
50
53
  }
51
54
 
@@ -4,7 +4,7 @@
4
4
  <html xmlns="http://www.w3.org/1999/xhtml">
5
5
  <head>
6
6
  <meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
7
- <title>Lingo Web - <%= t 'Automatic indexing online', 'Automatische Indexierung Online' %></title>
7
+ <title>Lingo Web - <%= t 'Automatic indexing online', 'Automatische Indexierung Online', 'Автоматическая обработка текстов онлайн' %></title>
8
8
  <link rel="stylesheet" type="text/css" href="<%= url_for '/lingoweb.css' %>" />
9
9
  </head>
10
10
  <body>
@@ -13,34 +13,45 @@
13
13
  </div>
14
14
 
15
15
  <div id="welcome">
16
- <strong><%= t 'Welcome to Lingo Web!', 'Willkommen bei Lingo Web!' %></strong>
17
- <%= t %q{
18
- Lingo Web provides the opportunity to test the functionality of
19
- <a href="http://lex-lingo.de">Lingo</a>.<br />
20
- Lingo is an open source indexing system for research and teaching.
21
- }, %q{
22
- Lingo Web bietet die Möglichkeit, die Funktionsweise von
23
- <a href="http://lex-lingo.de">Lingo</a> zu testen.<br />
24
- Lingo ist ein frei verfügbares System zur linguistisch und statistisch
25
- basierten automatischen Indexierung des Deutschen und Englischen.
16
+ <strong><%= t 'Welcome to Lingo Web!', 'Willkommen bei Lingo Web!', 'Добро пожаловать в Lingo Web!' %></strong>
17
+ <%= t %Q{
18
+ <a href="http://lex-lingo.de">Lingo</a> is an open source indexing system
19
+ based on<br />linguistic and statistic analysis that currently offers
20
+ support for <a href="#{url_for '/?l=de'}">German</a>,
21
+ <a href="#{url_for '/?l=en'}">English</a>, and
22
+ <a href="#{url_for '/?l=ru'}">Russian</a>.
23
+ }, %Q{
24
+ <a href="http://lex-lingo.de">Lingo</a> ist ein frei verfügbares System
25
+ zur linguistisch und statistisch<br />basierten automatischen Indexierung
26
+ und bringt aktuell Unterstützung für
27
+ <a href="#{url_for '/?l=de'}">Deutsch</a>,
28
+ <a href="#{url_for '/?l=en'}">Englisch</a> und
29
+ <a href="#{url_for '/?l=ru'}">Russisch</a> mit.
30
+ }, %Q{
31
+ <a href="http://lex-lingo.de">Lingo</a> – бесплатное программное обеспечение
32
+ для автоматической обработки текстов (АОТ) на естественном языке, как
33
+ лингвистической, так и статистической. Lingo может обрабатывать тексты на
34
+ <a href="#{url_for '/?l=de'}">английском</a>,
35
+ <a href="#{url_for '/?l=en'}">немецком</a> и
36
+ <a href="#{url_for '/?l=ru'}">русском</a> языке.
26
37
  } %>
27
38
  </div>
28
39
 
29
40
  <div id="main">
30
41
  <form action="<%= url_for '/' %>" method="post">
31
42
  <div>
32
- <fieldset><legend><strong><%= t 'Input', 'Eingabe' %></strong></legend>
43
+ <fieldset><legend><strong><%= t 'Input', 'Eingabe', 'ввод данных' %></strong></legend>
33
44
  <textarea name="q" rows="20" cols="50"><%= @q %></textarea>
34
45
  </fieldset>
35
46
 
36
- <fieldset><legend><strong><%= t 'Output', 'Ausgabe' %></strong></legend>
47
+ <fieldset><legend><strong><%= t 'Output', 'Ausgabe', 'вывод данных' %></strong></legend>
37
48
  <textarea readonly="readonly" rows="20" cols="50"><%= @r %></textarea>
38
49
  </fieldset>
39
50
 
40
51
  <br />
41
52
 
42
- <strong><%= t 'Language', 'Sprache' %></strong> = <select name="l">
43
- <% for l in LANGS %>
53
+ <strong><%= t 'Language', 'Sprache', 'язык' %></strong> = <select name="l">
54
+ <% for l in L %>
44
55
  <option value="<%= l %>"<%= ' selected="selected"' if l == @l %>><%= l %></option>
45
56
  <% end %>
46
57
  </select>
@@ -48,9 +59,9 @@
48
59
  <br />
49
60
  <br />
50
61
 
51
- <input type="submit" value="<%= t 'Start processing...', 'Verarbeitung starten...' %>"></input> |
52
- <input type="reset" value="<%= t 'Reset form', 'Formular zurücksetzen' %>"></input> |
53
- <a href="<%= url_for '/' %>"><%= t 'New request', 'Neue Anfrage' %></a>
62
+ <input type="submit" value="<%= t 'Start processing...', 'Verarbeitung starten...', 'начать обработку...' %>"></input> |
63
+ <input type="reset" value="<%= t 'Reset form', 'Formular zurücksetzen', 'очистить формуляр' %>"></input> |
64
+ <a href="<%= url_for '/' %>"><%= t 'New request', 'Neue Anfrage', 'новый запрос' %></a>
54
65
  </div>
55
66
  </form>
56
67
 
@@ -58,31 +69,78 @@
58
69
  </div>
59
70
 
60
71
  <div id="legend">
61
- <strong><%= t 'Legend', 'Legende' %></strong>:
72
+ <strong><%= t 'Legend', 'Legende', 'Сокращения' %></strong>:
62
73
  <table>
63
- <tr><th>s </th><td><%= t 'Noun', 'Substantiv' %></td></tr>
64
- <tr><th>a </th><td><%= t 'Adjective', 'Adjektiv' %></td></tr>
65
- <tr><th>v </th><td><%= t 'Verb', 'Verb' %></td></tr>
66
- <tr><th>e </th><td><%= t 'Proper name', 'Eigenname' %></td></tr>
67
- <tr><th>w </th><td><%= t 'Word class without suffixes', 'Wortklasse ohne Suffixe' %></td></tr>
68
- <tr><th>t </th><td><%= t 'Word class without suffixes (e.g. high frequency terms)', 'Wortklasse ohne Suffixe (z.B. Hochfrequenzterme)' %></td></tr>
69
- <tr><th>y </th><td><%= t 'Synonym', 'Synonym' %></td></tr>
70
- <tr><th>q (=SEQ)</th><td><%= t 'Sequence (algorithmically identified phrase)', 'Sequenz (algorithmisch erkannter Mehrwortbegriff)' %></td></tr>
71
- <tr><th>m (=MUL)</th><td><%= t 'Phrase', 'Mehrwortbegriff' %></td></tr>
72
- <tr><th>k (=KOM)</th><td><%= t 'Compound', 'Kompositum' %></td></tr>
73
- <tr><th>+ </th><td><%= t 'Part of a compound', 'Kompositum-Bestandteil' %></td></tr>
74
- <tr><th>x+ </th><td><%= t 'Unknown part of a hyphenated compound', 'unbekannter Kompositum-Bestandteil einer Bindestrich-Konstruktion' %></td></tr>
75
- <tr><th>? </th><td><%= t 'Unknown word', 'unbekanntes Wort' %></td></tr>
76
- <tr><th>MU? </th><td><%= t 'Part of a phrase (unknown word)', 'Mehrwortbestandteil (unbekanntes Wort)' %></td></tr>
77
- <tr><th>HELP </th><td><%= t 'e.g. Special characters', 'z.B. unbekanntes Sonderzeichen' %></td></tr>
78
- <tr><th>ABRV </th><td><%= t 'Possible abbreviation with a full stop in the middle', 'mögliche Abk. mit eingeschlossenem Punkt (z.B. "Ausst.Kat")' %></td></tr>
79
- <tr><th>PUNC </th><td><%= t 'Punctuation etc.', 'Satzzeichen etc.' %></td></tr>
80
- <tr><th>OTHR </th><td><%= t 'Other character', 'Sonstiges Zeichen' %></td></tr>
81
- <tr><th>URLS </th><td><%= t 'URL', 'URL' %></td></tr>
82
- <tr><th>NUMS </th><td><%= t 'Number', 'Zahl' %></td></tr>
74
+ <tr><th>s </th><td><%= t 'Noun',
75
+ 'Substantiv',
76
+ 'существительное' %></td></tr>
77
+ <tr><th>a </th><td><%= t 'Adjective',
78
+ 'Adjektiv',
79
+ 'прилагательное' %></td></tr>
80
+ <tr><th>v </th><td><%= t 'Verb',
81
+ 'Verb',
82
+ 'глагол' %></td></tr>
83
+ <tr><th>e </th><td><%= t 'Proper name',
84
+ 'Eigenname',
85
+ 'имя собственное' %></td></tr>
86
+ <tr><th>w </th><td><%= t 'Word class without suffixes',
87
+ 'Wortklasse ohne Suffixe',
88
+ 'бесфлективная часть речи' %></td></tr>
89
+ <tr><th>t </th><td><%= t 'Word class without suffixes (e.g. high frequency terms)',
90
+ 'Wortklasse ohne Suffixe (z.B. Hochfrequenzterme)',
91
+ 'бесфлективная часть речи (н-р высокочастотные термины)' %></td></tr>
92
+ <tr><th>y </th><td><%= t 'Synonym',
93
+ 'Synonym',
94
+ 'синоним' %></td></tr>
95
+ <tr><th>q (=SEQ)</th><td><%= t 'Sequence (algorithmically identified phrase)',
96
+ 'Sequenz (algorithmisch erkannter Mehrwortbegriff)',
97
+ 'сочетание (составная лексема, алгоритмически выделяемая)' %></td></tr>
98
+ <tr><th>m (=MUL)</th><td><%= t 'Phrase',
99
+ 'Mehrwortbegriff',
100
+ 'составная лексема' %></td></tr>
101
+ <tr><th>k (=KOM)</th><td><%= t 'Compound',
102
+ 'Kompositum',
103
+ 'сложное слово' %></td></tr>
104
+ <tr><th>+ </th><td><%= t 'Part of a compound',
105
+ 'Kompositum-Bestandteil',
106
+ 'компонент сложного слова' %></td></tr>
107
+ <tr><th>x+ </th><td><%= t 'Unknown part of a hyphenated compound',
108
+ 'unbekannter Kompositum-Bestandteil einer Bindestrich-Konstruktion',
109
+ 'неизвестный компонент сложного слова, пишущегося через дефис' %></td></tr>
110
+ <tr><th>? </th><td><%= t 'Unknown word',
111
+ 'unbekanntes Wort',
112
+ 'неизвестное слово' %></td></tr>
113
+ <tr><th>MU? </th><td><%= t 'Part of a phrase (unknown word)',
114
+ 'Mehrwortbestandteil (unbekanntes Wort)',
115
+ 'часть составной лексемы (неизвестное слово)' %></td></tr>
116
+ <tr><th>HELP </th><td><%= t 'e.g. Special characters',
117
+ 'z.B. unbekanntes Sonderzeichen',
118
+ 'н-р, неизвестный спецсимвол' %></td></tr>
119
+ <tr><th>ABRV </th><td><%= t 'Possible abbreviation with a full stop in the middle',
120
+ 'mögliche Abk. mit eingeschlossenem Punkt (z.B. "Ausst.Kat")',
121
+ 'возможное сокращение с точкой внутри' %></td></tr>
122
+ <tr><th>PUNC </th><td><%= t 'Punctuation etc.',
123
+ 'Satzzeichen etc.',
124
+ 'знак пунктуации' %></td></tr>
125
+ <tr><th>OTHR </th><td><%= t 'Other character',
126
+ 'Sonstiges Zeichen',
127
+ 'прочие знаки' %></td></tr>
128
+ <tr><th>URLS </th><td><%= t 'URL',
129
+ 'URL',
130
+ 'URL' %></td></tr>
131
+ <tr><th>NUMS </th><td><%= t 'Number',
132
+ 'Zahl',
133
+ 'числительное' %></td></tr>
83
134
  </table>
84
135
  </div>
85
136
 
137
+ <div id="config">
138
+ <strong><%= t 'Configuration', 'Konfiguration', 'конфигурация' %></strong>:
139
+ <pre><%= CFG %></pre>
140
+ </div>
141
+
142
+ <br style="clear: both" />
143
+
86
144
  <div id="footer">
87
145
  <em>powered by</em> <a href="http://lex-lingo.de">Lingo</a>
88
146
  <em>and</em> <a href="http://www.sinatrarb.com">Sinatra</a>