lingo 1.8.3 → 1.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>