CL-WHO в Python: умный или просто глупый? - PullRequest
0 голосов
/ 15 апреля 2011

Я не могу сказать, это умно или просто глупо.Мне нравится CL-WHO, и я также люблю Python, так что я нашел способ смешать их.Я хочу сказать следующее:

tag("html",
    lst(
      tag("head"),
      tag("body",
        lst(
          tag("h1", "This is the headline"),
          tag("p", "This is the article"),
          tag("p",
            tag("a", "Click here for more", ["href", "http://nowhere.com"]))))))

и сделать так, чтобы оно оценилось следующим образом:

<html>
    <head>
    </head>
    <body>
      <h1>This is the headline</h1>
      <p>This is the article</p>
      <p>
        <a href="http://nowhere.com">Click here for more</a>
      </p>
    </body>
  </html>

Выглядит так же, как CL-WHO, но с функциональной нотацией вместо s-выражений.Итак, я начал с этой функции генерации тегов:

def tag(name, inner="", attribs=[], close=True):
  ret = []
  ret.append('<' + name)
  while attribs.__len__() > 0:
      ret.append(' %s="%s"' % (attribs.pop(0),attribs.pop(0)))
  ret.append(">")
  if type(inner).__name__ == 'list':
    ret.extend(inner)
  else:
    ret.append(inner)
  if close:
    ret.append('</%s>' % name)
  return "".join(ret)

inner может быть списком, а квадратные скобки для списков безобразны во всем этом коде Lispy, поэтому я хочу функцию, которая создает список из своих аргументов:

def lst(*args):
  return [x for x in args]

Чтобы упростить генерацию условного кода, вам нужен оператор if, который представляет собой функцию, которая оценивает один из двух результатов, как в Lisp, поэтому вы можете вложить его.Императивный стиль управления потоком, если не подойдет.

def fif(cond, a, b):
  if cond:
    return a
  else:
    return b

Vioila.Теперь вы можете создать образец страницы следующим образом:

def gen(x):
  """Sample function demonstratine conditional HTML generation. Looks just like CL-WHO!"""
  return tag("html",
    lst(
      tag("head"),
      tag("body",
        lst(
          fif(x == 1, tag("h1", "This is the headline"), tag("h1", "No, THIS is the headline")),
          tag("p", "This is the article"),
          tag("p",
            tag("a", "Click here for more", ["href", "http://nowhere.com"]))))))

print gen(1)

Там, где это начинает ломаться, это циклы.Все, что зацикливается, должно быть извлечено в отдельную функцию.Так о чем ты думаешь?Интересно или тупой?Попробуйте и скажите мне, что вы думаете.

1 Ответ

1 голос
/ 16 апреля 2011

Вы должны html-экранировать каждый текстовый узел, значение атрибута и т. Д. Или html-инъекцию, и XSS вас укусит.

Помимо полнофункциональных шаблонных систем (mako, genhi, chameleon, jinja и т. Д.)библиотека, более похожая на то, что вы делаете, вероятно, lxml

>>> from lxml.html.builder import HTML, HEAD, BODY, H1, P, A
>>> from lxml.html import tostring
>>> 
>>> h = HTML(
...         HEAD(
...             BODY(
...                 H1('This is the headline'),
...                 P('This is the article'),
...                 P(
...                     A('Click here for more', href='http://nowhere.com')))))
>>> print tostring(h, pretty_print=True)
<html><head><body>
<h1>This is the headline</h1>
<p>This is the article</p>
<p><a href="http://nowhere.com">Click here for more</a></p>
</body></head></html>

И вы можете использовать троичный оператор

H1("This is the headline" if x==1 else "No, THIS is the headline")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...