Ru-Board.club
← Вернуться в раздел «Программы»

» OutWiker

Автор: unreal666
Дата сообщения: 15.02.2015 13:24
Jenyay
добавь, плиз, в метод parseParams файла src/outwiker/pages/wiki/parser/command.py поддержку парсинга неименованных параметров (т.е. параметров типа "значение_параметра" без всяких имен и равно) с автоназначением им имени типа arg0, arg1 и т.п.

Добавлено:
шаблон для этого, наверно, надо будет изменить с

Код: pattern = ur"""((?P<name>[\w.]+)
(\s*=\s*(?P<param>([-_\w.]+)|((?P<quote>["']).*?(?P=quote)) ) )?\s*)"""
Автор: Jenyay
Дата сообщения: 15.02.2015 19:02
unreal666

А можешь сказать для чего, и как тогда понять, где закончился arg0 и начался arg1? Приведи пример, как это должно выглядеть.
Автор: unreal666
Дата сообщения: 16.02.2015 02:16
Jenyay
Для чего? Ну иногда нужно, чтобы плагин юзал просто позиционные параметры, кол-во которых может быть любым. Можно, конечно, их вручную обзывать по типу arg0/1/2, но это уже как бы излишним будет, т.к. их имена не будут нести смысла.
А вариант? Ну типа такого

Код: (:tmpl name="prev" "td" 'class="needclass"':)
(:tmpl name="info-panel" "date=2011.06.08" 'autor=autor' "article-link=http://site.com/":)
(:tmpl name="flags" "translation" "tutorial":)
(:tmpl name="toc" "3" "nonum":)
Автор: Jenyay
Дата сообщения: 16.02.2015 08:10
Надо подумать, как это правильнее сделать в общем виде. Пока ты можешь просто перезгрузить метод parseParams в своей команде - я обычно так и делаю, когда мне от нее нужно что-то специфическое.
Автор: unreal666
Дата сообщения: 16.02.2015 09:36
Jenyay
сделал отдельно в плагине

Код: def parseParams (params):
"""
Parse params string into parts: key - value. Key may contain a dot.
Sample params:
param1 Параметр2.subparam = 111 Параметр3 = " bla bla bla" param4.sub.param2 = "111" param5 =' 222 ' param7 = " sample 'bla bla bla' example" param8 = ' test "bla-bla-bla" test '

Changes in 1.9.0.761: name may contain a dot.
"""
defaultNameParam = u"arg"
paramIndex = 0
pattern = ur"""(?P<name>[\w.]+)
(\s*=\s*(?P<param>[-_\w.]+|(?P<quote>["']).*?(?P=quote) ) )?\s*
| (?P<posparam>(?P<posquote>["']).*?(?P=posquote) )\s*"""

result = {}

regex = re.compile (pattern, re.IGNORECASE | re.MULTILINE | re.DOTALL | re.VERBOSE | re.UNICODE)
matches = regex.finditer (params)

for match in matches:
name = match.group ("name")
param = match.group ("param")
if name is not None and param is None:
param = u""
elif name is None:
name = defaultNameParam + unicode(paramIndex)
param = match.group ("posparam")
paramIndex += 1

result[name] = Command.removeQuotes (param)

return result
Автор: Jenyay
Дата сообщения: 16.02.2015 11:29
unreal666

Спасибо. попозже гляну.
Автор: unreal666
Дата сообщения: 16.02.2015 13:55
По части тега [>цитата<]. Посмотрел код - для его парсинга используется класс QuotedString. Хотя по идее этот тег может быть вложенным (к примеру, мне это сейчас понадобилось), т.е. к нему не очень корректно применять данный тег.
Автор: Jenyay
Дата сообщения: 16.02.2015 13:58
С вложенными тегами в этом парсере вообще беда, не только в этом месте.
Автор: Jenyay
Дата сообщения: 16.02.2015 14:27
Тоже попробую.
Автор: unreal666
Дата сообщения: 16.02.2015 14:45
хотя нет. Надо еще подумать - регесп подправить. Временно убрал. Если получится, обратно выложу.
Автор: Jenyay
Дата сообщения: 16.02.2015 19:08
unreal666

Я тут сейчас переписываю HtmlImprover, так что готовься морально, что в твоем форке что-то не смержится.
Автор: unreal666
Дата сообщения: 17.02.2015 21:16
Jenyay
кажется намутил

Код: # -*- coding: UTF-8 -*-

from outwiker.libs.pyparsing import Suppress, CharsNotIn, Combine, ZeroOrMore, NotAny, Forward, OneOrMore


class QuoteFactory (object):
"""
Фабрика для создания токена для цитат
"""
@staticmethod
def make (parser):
return QuoteToken(parser).getToken()


class QuoteToken (object):
quoteStart = Suppress('[>')
quoteEnd = Suppress('<]')
anyChar = CharsNotIn('', exact=1)
anyExcept = Combine( ZeroOrMore( NotAny (quoteStart | quoteEnd) + anyChar ) )
# anyExcept = Regex(r'(?:(?!\[>|<\]).)*')
token = Forward()
token << (quoteStart + ( OneOrMore( anyExcept + OneOrMore(token) ) + anyExcept | anyExcept ) +
quoteEnd).leaveWhitespace()

def __init__ (self, parser):
self.parser = parser


def getToken (self):
return QuoteToken.token.setParseAction(self.__parse)("quote")


def __parse (self, s, l, t):
return u''.join([u'<blockquote>', self.parser.parseWikiMarkup (u''.join(t)), u'</blockquote>'])
Автор: unreal666
Дата сообщения: 18.02.2015 06:51
короче просто дополнительно модифицировал tokenurl.py для защиты от лишних преобразований :

Код: # -*- coding: UTF-8 -*-

import re

from outwiker.libs.pyparsing import Regex, NotAny


class UrlFactory (object):
@staticmethod
def make (parser):
return UrlToken(parser).getToken()


class UrlToken (object):
token = ( Regex (ur'(?:=\s*")?', re.IGNORECASE | re.UNICODE) +
Regex (ur"((?# Начало разбора IP )(?<!\.)(?:25[0-5]|2[0-4]\d|1\d\d|0?[1-9]\d|0{,2}[1-9])(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)){3}(?!\.[0-9])(?!\w)(?# Конец разбора IP )|(((news|telnet|nttp|file|http|ftp|https|page)://)|(www|ftp)\.)[-\w0-9\.]+[-\w0-9]+)(:[0-9]*)?(/([-\w0-9_,\$\.\+\!\*\(\):@|&=\?/~\#\%]*[-\w0-9_\$\+\!\*\(\):@|&=\?/~\#\%])?)?", re.IGNORECASE | re.UNICODE) +
NotAny('</a>') )("url")

def __init__ (self, parser):
self.parser = parser


def getToken (self):
return UrlToken.token.setParseAction(self.__convertToUrlLink)


def __convertToUrlLink (self, s, l, t):
"""
Преобразовать ссылку на интернет-адрес
"""
if t[0] is not u'':
return t

start = t[1]

if (not start.startswith ("http://") and
not start.startswith ("ftp://") and
not start.startswith ("news://") and
not start.startswith ("gopher://") and
not start.startswith ("telnet://") and
not start.startswith ("nttp://") and
not start.startswith ("file://") and
not start.startswith ("https://") and
not start.startswith ("page://")):
return self.__getUrlTag ("http://" + start, start)

return self.__getUrlTag (start, start)


def __getUrlTag (self, url, comment):
return '<a href="%s">%s</a>' % (url.strip(), self.parser.parseLinkMarkup (comment.strip()))
Автор: Jenyay
Дата сообщения: 18.02.2015 07:35

Цитата:
только не понял, нафига в __getUrlTag нужно self.parser.parseLinkMarkup, если в ссылке нечего парсить?


Например, чтобы можно было писать [[http://example.com | '''коммент''']].
Автор: unreal666
Дата сообщения: 18.02.2015 07:42
Jenyay
но в данном классе какой от этого толк? Ведь ему на вход подаются обычные ссылки, а не текст такого вида.
Автор: Jenyay
Дата сообщения: 18.02.2015 07:55
Нет, почему? Он же комментарий к ссылке обрабатывает таким образом, а не саму ссылку.
Автор: unreal666
Дата сообщения: 18.02.2015 08:01
это в классе LinkToken имеет смысл, а этот класс парсит чисто ссылку (то, что подпадает под шаблон).
даже по коду видно, что передается в этот метод.

Код: def __convertToUrlLink (self, s, l, t):
"""
Преобразовать ссылку на интернет-адрес
"""
if t[0] is not u'':
return t

start = t[1]

if (not start.startswith ("http://") and
not start.startswith ("ftp://") and
not start.startswith ("news://") and
not start.startswith ("gopher://") and
not start.startswith ("telnet://") and
not start.startswith ("nttp://") and
not start.startswith ("file://") and
not start.startswith ("https://") and
not start.startswith ("page://")):
return self.__getUrlTag ("http://" + start, start)

return self.__getUrlTag (start, start)
Автор: Jenyay
Дата сообщения: 18.02.2015 08:13
А, я думал мы и говорим про LinkToken. Тогда да, это не нужно.
Автор: unreal666
Дата сообщения: 20.02.2015 09:49
Ты в ближайшее время не собираешься править файлы в папке src\outwiker\pages\wiki\parser ?

А то собираюсь там много чего подправить:
- вынести токены из методов getToken в поля их классов. Методы токенов setParseAction будут все также добавлять в методе getToken.
- в классы фабрик токенов добавить метод __init__. При создании объектов-экземпляров_классов_фабрик у этих фабрик будет присваиваться поле parser, которое и будет юзаться в кэлбеках для setParseAction. Один фиг эти кэлбеки вызываются уже после создания парсера, так что это поле на момент вызова кэлбека уже будет заполнено.

ЗЫ.
Хотя наверно этот поле parser буду заполнять не у всех фабрик, а создам общую фиктивную пустую фабрику-контейнер, в которой и хранить это поле (может еще и для чего другого хранить пригодится).

В чем польза такого? При перезагрузке/переходе на другие заметки токены не будут пересоздаваться. Будет изменяться только парсер.

Я сейчас у себя сделал возможность вложения жирного текста в курсив (пока не заливал в git), т.е.

Код: ''курсив '''жирный курсив''' курсив''
Автор: Jenyay
Дата сообщения: 20.02.2015 11:53
unreal666

Цитата:
Ты в ближайшее время не собираешься править файлы в папке src\outwiker\pages\wiki\parser


Хотел поправить что-то по мелочам, но не глобально.

Добавлено:
unreal666

Я тут в отдельной ветке htmlimprover сделал возможность переключения между "улучшателями" и добавил "новый" улучшатель, которые расставляет расставляет абзацы с помощью тегов p. Вроде получилось лучше, чем было, но, наверное, надо где-то еще подточить напильником.

Там еще дальше буду продолжать пилить, собираюсь вынести новый "улучшатель" в отдельный плагин.
Автор: unreal666
Дата сообщения: 20.02.2015 13:32
Jenyay
да уже заметил. Просто пока времени не было разобраться, что к чему там
Автор: unreal666
Дата сообщения: 21.02.2015 05:10
Посмотрел сейчас улучшайзер. По умолчанию в качестве разделителя строк установлен <br/>. Может лучше установить <p>, что по умолчанию было как в предыдущих версиях?
Автор: Jenyay
Дата сообщения: 23.02.2015 19:43
unreal666

Цитата:
Посмотрел сейчас улучшайзер. По умолчанию в качестве разделителя строк установлен <br/>. Может лучше установить <p>, что по умолчанию было как в предыдущих версиях?


Улучшатель через <p> я вообще собираюсь в плагин вынести. Через BR поведение мне кажется более логичным для тех, кому не нужен HTML-код.
Автор: unreal666
Дата сообщения: 27.02.2015 19:46
Jenyay
- <br> - тег текстового (или как там в css они наз-ся) уровня, а не блочного, в отличие от <p> => соответствующие ограничения css
- через <p> проще применять css для абзацев (точнее не проще, а вообще непонятно как)
- нельзя будет применять css отдельно для абзаца и отдельно при двойного принудительного разрыва строк.
Автор: Jenyay
Дата сообщения: 27.02.2015 21:06
unreal666

Что правильнее с точки зрения HTML использовать <p>, я понимаю. Но обычному пользователю, далекому от HTML, понятнее, когда сколько раз нажмешь Enter, столько же пропустится строк.
Автор: unreal666
Дата сообщения: 03.03.2015 17:46
Парсинг страниц (т.е. создание/использование объекта - экземпляра класса Parser) может происходить одновременно (параллельно) для нескольких заметок, к примеру, в разных вкладках?
Или этот процесс происходит последовательно, т.е. пока одна вкладка не отпрасит, другая не будет парсить?
Автор: Jenyay
Дата сообщения: 03.03.2015 18:06
unreal666

Парсинг происходит только при переключении в режим Просмотр или HTML для викистраниц.
Автор: unreal666
Дата сообщения: 03.03.2015 19:10
Jenyay
Это понятно.
Но, если к примеру открыто 2 вкладки-заметки и сначала на 1-ой я перешел в режим просмотра => она ренедиртся долго => переключился на 2-ую вкладку-заметку => там тоже перешел в режим просмотра.
Будут ли в таком случае рендериться обе заметки или пока 1-ая не завершится 2-ая не будет рендериться?
Автор: Jenyay
Дата сообщения: 03.03.2015 19:29
В этой части программа однопоточная, и пока не отрендерится страница, нельзя будет переключиться на другую страницу.
Автор: unreal666
Дата сообщения: 04.03.2015 10:58
это нормально, что при "ненужности" объекта parser класс Parser не вызывает деструктор, даже при выходе из проги?
проверял втыканием в данный класс метода __del__:

Код: def __del__(self):
print u'Это деструктор'

Страницы: 123456789101112131415161718192021222324252627282930

Предыдущая тема: Acronis True Image Home vs Clonezilla


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.