# File lib/gilenson/gilenson_port.rb, line 95
 95:   def to_html(no_paragraph = false)
 96: 
 97:     text = @_text
 98:     
 99:     # -2. игнорируем ещё регексп
100:     ignored = []
101: 
102: 
103:     text.scan(@ignore) do |result|
104:       ignored << result
105:     end
106: 
107:     text.gsub!(@ignore, @mark_ignored)  # маркер игнора
108: 
109:     # -1. запрет тагов html
110:     text.gsub!(/&/, '&amp;') if @settings["html"]
111: 
112: 
113:      # 0. Вырезаем таги
114:     #  проблема на самом деле в том, на что похожи таги.
115:     #   вариант 1, простой (закрывающий таг) </abcz>
116:     #   вариант 2, простой (просто таг)      <abcz>
117:     #   вариант 3, посложней                 <abcz href="abcz">
118:     #   вариант 4, простой (просто таг)      <abcz />
119:     #   вариант 5, вакка                     \xA2\xA2...== нафиг нафиг
120:     #   самый сложный вариант - это когда в параметре тага встречается вдруг символ ">"
121:     #   вот он: <abcz href="abcz>">
122:     #  как работает вырезание? введём спецсимвол. Да, да, спецсимвол.
123:     #    нам он ещё вопьётся =)
124:     #  заменим все таги на спец.символ, запоминая одновременно их в массив. 
125:     #  и будем верить, что спец.символы в дикой природе не встречаются.
126: 
127:     tags = []
128:     if (@skip_tags)
129:  #     re =  /<\/?[a-z0-9]+("+ # имя тага
130:  #                              "\s+("+ # повторяющая конструкция: хотя бы один разделитель и тельце
131:  #                                     "[a-z]+("+ # атрибут из букв, за которым может стоять знак равенства и потом
132:  #                                              "=((\'[^\']*\')|(\"[^\"]*\")|([0-9@\-_a-z:\/?&=\.]+))"+ # 
133:  #                                           ")?"+
134:  #                                  ")?"+
135:  #                            ")*\/?>|\xA2\xA2[^\n]*?==/i;
136: 
137: #          re =  /<\/?[a-z0-9]+(\s+([a-z]+(=((\'[^\']*\')|(\"[^\"]*\")|([0-9@\-_a-z:\/?&=\.]+)))?)?)*\/?>|\xA2\xA2[^\n]*?==/ui
138: 
139:       re =  /(<\/?[a-z0-9]+(\s+([a-z]+(=((\'[^\']*\')|(\"[^\"]*\")|([0-9@\-_a-z:\/?&=\.]+)))?)?)*\/?>)/ui
140: 
141: # по-хорошему атрибуты тоже нужно типографить. Или не нужно? бугага...
142: 
143:       tags = text.scan(re).map{|tag| tag[0] }
144: #            match = "&lt;" + match if @settings["html"]
145:       text.gsub!(re, @mark_tag) #маркер тега, мы используем Invalid UTF-sequence для него
146:   
147: #    puts "matched #{tags.size} tags"
148:     end
149: 
150:     # 1. Запятые и пробелы
151:     if @settings["spacing"]
152:       text.gsub!( /(\s*)([,]*)/sui, '\2\1');
153:       text.gsub!( /(\s*)([\.?!]*)(\s*[ЁА-ЯA-Z])/su, '\2\1\3');
154:     end
155: 
156:     # 2. Разбиение на строки длиной не более ХХ символов
157:     # --- для ваки не портировано ---
158:     # --- для ваки не портировано ---
159: 
160:     # 3. Спецсимволы
161:     # 0. дюймы с цифрами
162:     text.gsub!(/\s([0-9]{1,2}([\.,][0-9]{1,2})?)\"/ui, ' \1&quot;') if @settings["inches"]
163: 
164:     # 1. лапки
165:     if (@settings["quotes"])
166:       text.gsub!( /\"\"/ui, "&quot;&quot;")
167:       text.gsub!( /\"\.\"/ui, "&quot;.&quot;")
168:       _text = '""';
169:       while _text != text do  
170:         _text = text
171:         text.gsub!( /(^|\s|\201|\xF0\xF0\xF0\xF0|>)\"([0-9A-Za-z\'\!\s\.\?\,\-\&\;\:\_\xF0\xF0\xF0\xF0\201]+(\"|&#148;))/ui, '\1&#147;\2')
172:         #this doesnt work in-place. somehow.
173:         text = text.gsub( /(\&\#147\;([A-Za-z0-9\'\!\s\.\?\,\-\&\;\:\xF0\xF0\xF0\xF0\201\_]*).*[A-Za-z0-9][\xF0\xF0\xF0\xF0\201\?\.\!\,]*)\"/ui, '\1&#148;')
174:       end
175:     end
176: 
177:     # 2. ёлочки
178:     if @settings["laquo"]
179:       text.gsub!( /\"\"/ui, "&quot;&quot;");
180:       text.gsub!( /(^|\s|\201|\xF0\xF0\xF0\xF0|>|\()\"((\201|\xF0\xF0\xF0\xF0)*[~0-9ёЁA-Za-zА-Яа-я\-:\/\.])/ui, "\\1&laquo;\\2");
181:       # nb: wacko only regexp follows:
182:       text.gsub!( /(^|\s|\201|\xF0\xF0\xF0\xF0|>|\()\"((\201|\xF0\xF0\xF0\xF0|\/&nbsp;|\/|\!)*[~0-9ёЁA-Za-zА-Яа-я\-:\/\.])/ui, "\\1&laquo;\\2")
183:       _text = "\"\"";
184:       while (_text != text) do
185:         _text = text;
186:         text.gsub!( /(\&laquo\;([^\"]*)[ёЁA-Za-zА-Яа-я0-9\.\-:\/](\201|\xF0\xF0\xF0\xF0)*)\"/sui, "\\1&raquo;")
187:         # nb: wacko only regexps follows:
188:         text.gsub!( /(\&laquo\;([^\"]*)[ёЁA-Za-zА-Яа-я0-9\.\-:\/](\201|\xF0\xF0\xF0\xF0)*\?(\201|\xF0\xF0\xF0\xF0)*)\"/sui, "\\1&raquo;")
189:         text.gsub!( /(\&laquo\;([^\"]*)[ёЁA-Za-zА-Яа-я0-9\.\-:\/](\201|\xF0\xF0\xF0\xF0|\/|\!)*)\"/sui, "\\1&raquo;")
190:       end
191:     end
192: 
193: 
194:       # 2b. одновременно ёлочки и лапки
195:       if (@settings["quotes"] && (@settings["laquo"] or @settings["farlaquo"]))
196:         text.gsub!(/(\&\#147;\;(([A-Za-z0-9'!\.?,\-&;:]|\s|\xF0\xF0\xF0\xF0|\201)*)&laquo;(.*)&raquo;)&raquo;/ui,"\\1&#148;");
197:       end
198: 
199: 
200:       # 3. тире
201:       if (@settings["dash"])
202:         text.gsub!( /(\s|;)\-(\s)/ui, "\\1&ndash;\\2")
203:       end
204: 
205: 
206:       # 3a. тире длинное
207:       if (@settings["emdash"])
208:         text.gsub!( /(\s|;)\-\-(\s)/ui, "\\1&mdash;\\2")
209:         # 4. (с)
210:         text.gsub!(/\([сСcC]\)((?=\w)|(?=\s[0-9]+))/u, "&copy;") if @settings["(c)"]
211:         # 4a. (r)
212:         text.gsub!( /\(r\)/ui, "<sup>&#174;</sup>") if @settings["(r)"]
213: 
214:         # 4b. (tm)
215:         text.gsub!( /\(tm\)|\(тм\)/ui, "&#153;") if @settings["(tm)"]
216:         # 4c. (p)   
217:         text.gsub!( /\(p\)/ui, "&#167;") if @settings["(p)"]
218:       end
219: 
220: 
221:       # 5. +/-
222:       text.gsub!(/[^+]\+\-/ui, "&#177;") if @settings["+-"]
223: 
224: 
225:       # 5a. 12^C
226:       if @settings["degrees"]
227:         text.gsub!( /-([0-9])+\^([FCС])/, "&ndash;\\1&#176;\\2")
228:         text.gsub!( /\+([0-9])+\^([FCС])/, "+\\1&#176;\\2")
229:         text.gsub!( /\^([FCС])/, "&#176;\\1")
230:       end
231: 
232: 
233:        # 6. телефоны
234:       if @settings["phones"]
235:         @phonemasks[0].each_with_index do |v, i|
236:           text.gsub!(v, @phonemasks[1][i])
237:         end
238:       end
239: 
240: 
241:     # 7. Короткие слова и &nbsp;
242:     if (@settings["wordglue"])
243: 
244:       text = " " + text + " ";
245:       _text = " " + text + " ";
246:       until _text == text
247:          _text = text
248:          text.gsub!( /(\s+)([a-zа-яА-Я]{1,2})(\s+)([^\\s$])/ui, '\1\2&nbsp;\4')
249:          text.gsub!( /(\s+)([a-zа-яА-Я]{3})(\s+)([^\\s$])/ui,   '\1\2&nbsp;\4')
250:       end
251: 
252:       for i in @glueleft
253:          text.gsub!( /(\s)(#{i})(\s+)/sui, '\1\2&nbsp;')
254:       end
255: 
256:       for i in @glueright 
257:          text.gsub!( /(\s)(#{i})(\s+)/sui, '&nbsp;\2\3')
258:       end
259:     end
260: 
261: 
262: 
263:     # 8. Склейка ласт. Тьфу! дефисов.
264:     text.gsub!( /([a-zа-яА-Я0-9]+(\-[a-zа-яА-Я0-9]+)+)/ui, '<nobr>\1</nobr>') if @settings["dashglue"]
265: 
266: 
267:     # 9. Макросы
268: 
269: 
270: 
271:     # 10. Переводы строк
272:     # --- для ваки не портировано ---
273:     # --- для ваки не портировано ---
274: 
275: 
276:     # БЕСКОНЕЧНОСТЬ. Вставляем таги обратно.
277:   #  if (@skip_tags)
278: #    text = text.split("\xF0\xF0\xF0\xF0").join
279: #        
280: 
281:   tags.each do |tag|
282:     text.sub!(@mark_tag, tag)
283:   end
284: 
285: #        i = 0
286: #        text.gsub!(@mark_tag) {
287: #          i + 1
288: #          tags[i-1]
289: #        }
290: 
291: #      text = text.split("\xF0\xF0\xF0\xF0")
292: #puts "reinserted #{i} tags"
293: #
294:   #  end
295:     
296: 
297: #ext.gsub!("a", '')
298: #      raise "Text still has tag markers!" if text.include?("a")
299: 
300:     # БЕСКОНЕЧНОСТЬ-2. вставляем ещё сигнорированный регексп
301:     #
302: #      if @ignore
303: #        ignored.each { | tag | text.sub!(@mark_ignored, tag) }
304: #      end
305: 
306: #      raise "Text still has ignored markers!" if text.include?("\201")
307: 
308:     # БОНУС: прокручивание ссылок через A(...)
309:     # --- для ваки не портировано ---
310:     # --- для ваки не портировано ---
311: 
312:     # фуф, закончили.
313:  #   text.gsub!(/<nobr>/, "<span class=\"nobr\">").gsub(/<\/nobr>/, "</span>") if (@de_nobr)
314: 
315: #    text.gsub!(/<nobr>/, "<span class=\"nobr\">").gsub(/<\/nobr>/, "</span>") if (@de_nobr)
316: 
317:     text.gsub(/(\s)+$/, "").gsub(/^(\s)+/, "")
318: 
319:   end