# Module `lib.htmltemplate.htmlparser`

This script parse the template.html file and creates the template classes that can be used to compose a web page. This automatically creates the content of file lib/htmltemplate/htmlclasses.py

Expand source code

    # Distributed under Pycameresp License
    # Copyright (c) 2023 Remi BERTHOLET
    """ This script parse the template.html file and creates the template classes
    that can be used to compose a web page.
    This automatically creates the content of file lib/htmltemplate/htmlclasses.py """
    # pylint:disable=consider-using-f-string
    import re

    def findall(pattern, text):
            """ Finds the %(xxx)s fields in the line """
            spl = re.compile(pattern).split(text)
            result = []
            begin_tag = ""
            end_tag   = None
            begin_format = ""
            end_format = ""
            initText = text
            for s in spl:
                    text = text[len(s)+2:]
                    end = text.find(")s")
                    var = ""
                    if len(text) > 0:
                            var = text[:end]
                            result.append(var)
                    if var == "content":
                            begin_tag += s
                            end_tag = ""
                    elif end_tag is not None:
                            end_tag += s
                            if var != "":
                                    if var in ["disabled","checked","active","selected","required","novalidate"]:
                                            end_format += " b'%s' if self.%s else b'',"%(var, var)
                                    else:
                                            end_format += "self.%s,"%var
                                    end_tag += "\x25s"
                    else:
                            begin_tag += s
                            if var != "":
                                    if var in ["disabled","checked","active","selected","required","novalidate"]:
                                            begin_format += " b'%s' if self.%s else b'',"%(var, var)
                                    else:
                                            begin_format += "self.%s,"%var
                                    begin_tag += "\x25s"
                    text = text[end+2:]
            if end_tag is None:
                    end_tag = ""
                    end_format = ""
            return result, begin_tag, end_tag, begin_format, end_format

    def parse(force=False):
            """ Parse the www/template.html and createsthe content of file lib/htmltemplate/htmlclasses.py """
            from htmltemplate import WWW_DIR, TEMPLATE_FILE, TEMPLATE_PY
            # pylint: disable=duplicate-string-formatting-argument
            # pylint:disable=unspecified-encoding
            print("Parse html template")
            lines = open(WWW_DIR+TEMPLATE_FILE).readlines()
            py_class_file = open(TEMPLATE_PY,"w")
            py_class_file.write("''' File automatically generated with template.html content '''\n# pylint:disable=missing-function-docstring\n# pylint:disable=global-variable-not-assigned\n# pylint:disable=trailing-whitespace\n# pylint:disable=too-many-lines\nfrom htmltemplate.template import Template \n")

            stack = []
            ignored = False
            for line in lines:
                    if "<!--" in line:
                            spl = line.split("<!--")
                            if ":ignore_begin-->" in line:
                                    ignored = True
                            elif ":ignore_end-->" in line:
                                    ignored = False
                            elif ignored is False:
                                    if ":begin-->" in line:
                                            classname = spl[1].split(":begin-->")[0]
                                            stack.append([classname,"",""])
                                    elif ":end-->" in line:
                                            classname = spl[1].split(":end-->")[0]
                                            if classname != stack[-1][0]:
                                                    raise SyntaxError()
                                            classname, text, comment = stack.pop()
                                            attributes, begin_tag, end_tag, begin_format, end_format = findall(r'\%\([A-Za-z_0-9]*\)s',text)

                                            print("Html template update %s"%classname)
                                            classattributes = set()
                                            for attribute in attributes:
                                                    classattributes.add(attribute)
                                            classattributes = list(classattributes)
                                            classattributes.sort()
                                            comment = comment.rstrip()

                                            py_class_file.write("""\n%s\n"""%comment)

                                            if begin_tag != "":
                                                    py_class_file.write("""beg_tag%s = b'''%s'''\n"""%(classname,begin_tag))
                                            if end_tag != "":
                                                    py_class_file.write("""end_tag%s = b'''%s'''\n"""%(classname,end_tag))
                                            py_class_file.write("""def %s(*args, **params):\n"""%classname)

                                            py_class_file.write("""\tself = Template(*(("%s",) + args), **params)\n\n"""%classname)

                                            py_class_file.write("""\tdef get_begin(self):\n""")
                                            if begin_format == "":
                                                    if begin_tag != "":
                                                            py_class_file.write("""\t\tglobal beg_tag%s\n"""%classname)
                                                            py_class_file.write("""\t\treturn beg_tag%s\n"""%(classname))
                                                    else:
                                                            py_class_file.write("""\t\treturn b''\n""")
                                            else:
                                                    py_class_file.write("""\t\tglobal beg_tag%s\n"""%classname)
                                                    py_class_file.write("""\t\treturn beg_tag%s%s(%s)\n"""%(classname, "\x25",begin_format[:-1]))
                                            py_class_file.write("""\tself.get_begin     = get_begin\n\n""")

                                            py_class_file.write("""\tdef get_end(self):\n""")
                                            if end_format == "":
                                                    if end_tag != "":
                                                            py_class_file.write("""\t\tglobal end_tag%s\n"""%classname)
                                                            py_class_file.write("""\t\treturn end_tag%s\n"""%(classname))
                                                    else:
                                                            py_class_file.write("""\t\treturn b''\n""")
                                            else:
                                                    py_class_file.write("""\t\tglobal end_tag%s\n"""%classname)
                                                    py_class_file.write("""\t\treturn end_tag%s%s(%s)\n"""%(classname, "\x25", end_format[:-1]))
                                            py_class_file.write("""\tself.get_end       = get_end\n\n""")

                                            for attribute in classattributes:
                                                    if attribute in ["pattern"]:
                                                            py_class_file.write('\tself.{:<12} = params.get("{}", b"*")\n'.format(attribute,attribute))
                                                    elif attribute in ["id","name"]:
                                                            py_class_file.write('\tself.{:<12} = params.get("{}", b"%d"%id(self))\n'.format(attribute,attribute))
                                                    elif attribute in ["disabled","active","novalidate","required"]:
                                                            py_class_file.write('\tself.{:<12} = params.get("{}", False)\n'.format(attribute,attribute))
                                                    elif attribute in ["checked"]:
                                                            py_class_file.write('\tself.{:<12} = params.get("{}", True)\n'.format(attribute,attribute))
                                                    else:
                                                            py_class_file.write('\tself.{:<12} = params.get("{}", b"")\n'.format(attribute,attribute))
                                            py_class_file.write('\tself.end_init(**params)\n')
                                            py_class_file.write('\treturn self\n')
                                    else:
                                            raise SyntaxError()
                    else:
                            if ignored is False:
                                    if line.strip() != "":
                                            if len(stack) >= 1:
                                                    stack[-1][1] += line.strip()
                                                    stack[-1][2] += "# " +line.lstrip()

            py_class_file.close()

## Functions

`def findall(pattern, text)`

  Finds the %(xxx)s fields in the line

  Expand source code

      def findall(pattern, text):
              """ Finds the %(xxx)s fields in the line """
              spl = re.compile(pattern).split(text)
              result = []
              begin_tag = ""
              end_tag   = None
              begin_format = ""
              end_format = ""
              initText = text
              for s in spl:
                      text = text[len(s)+2:]
                      end = text.find(")s")
                      var = ""
                      if len(text) > 0:
                              var = text[:end]
                              result.append(var)
                      if var == "content":
                              begin_tag += s
                              end_tag = ""
                      elif end_tag is not None:
                              end_tag += s
                              if var != "":
                                      if var in ["disabled","checked","active","selected","required","novalidate"]:
                                              end_format += " b'%s' if self.%s else b'',"%(var, var)
                                      else:
                                              end_format += "self.%s,"%var
                                      end_tag += "\x25s"
                      else:
                              begin_tag += s
                              if var != "":
                                      if var in ["disabled","checked","active","selected","required","novalidate"]:
                                              begin_format += " b'%s' if self.%s else b'',"%(var, var)
                                      else:
                                              begin_format += "self.%s,"%var
                                      begin_tag += "\x25s"
                      text = text[end+2:]
              if end_tag is None:
                      end_tag = ""
                      end_format = ""
              return result, begin_tag, end_tag, begin_format, end_format

`def parse(force=False)`

  Parse the www/template.html and createsthe content of file lib/htmltemplate/htmlclasses.py

  Expand source code

      def parse(force=False):
              """ Parse the www/template.html and createsthe content of file lib/htmltemplate/htmlclasses.py """
              from htmltemplate import WWW_DIR, TEMPLATE_FILE, TEMPLATE_PY
              # pylint: disable=duplicate-string-formatting-argument
              # pylint:disable=unspecified-encoding
              print("Parse html template")
              lines = open(WWW_DIR+TEMPLATE_FILE).readlines()
              py_class_file = open(TEMPLATE_PY,"w")
              py_class_file.write("''' File automatically generated with template.html content '''\n# pylint:disable=missing-function-docstring\n# pylint:disable=global-variable-not-assigned\n# pylint:disable=trailing-whitespace\n# pylint:disable=too-many-lines\nfrom htmltemplate.template import Template \n")

              stack = []
              ignored = False
              for line in lines:
                      if "<!--" in line:
                              spl = line.split("<!--")
                              if ":ignore_begin-->" in line:
                                      ignored = True
                              elif ":ignore_end-->" in line:
                                      ignored = False
                              elif ignored is False:
                                      if ":begin-->" in line:
                                              classname = spl[1].split(":begin-->")[0]
                                              stack.append([classname,"",""])
                                      elif ":end-->" in line:
                                              classname = spl[1].split(":end-->")[0]
                                              if classname != stack[-1][0]:
                                                      raise SyntaxError()
                                              classname, text, comment = stack.pop()
                                              attributes, begin_tag, end_tag, begin_format, end_format = findall(r'\%\([A-Za-z_0-9]*\)s',text)

                                              print("Html template update %s"%classname)
                                              classattributes = set()
                                              for attribute in attributes:
                                                      classattributes.add(attribute)
                                              classattributes = list(classattributes)
                                              classattributes.sort()
                                              comment = comment.rstrip()

                                              py_class_file.write("""\n%s\n"""%comment)

                                              if begin_tag != "":
                                                      py_class_file.write("""beg_tag%s = b'''%s'''\n"""%(classname,begin_tag))
                                              if end_tag != "":
                                                      py_class_file.write("""end_tag%s = b'''%s'''\n"""%(classname,end_tag))
                                              py_class_file.write("""def %s(*args, **params):\n"""%classname)

                                              py_class_file.write("""\tself = Template(*(("%s",) + args), **params)\n\n"""%classname)

                                              py_class_file.write("""\tdef get_begin(self):\n""")
                                              if begin_format == "":
                                                      if begin_tag != "":
                                                              py_class_file.write("""\t\tglobal beg_tag%s\n"""%classname)
                                                              py_class_file.write("""\t\treturn beg_tag%s\n"""%(classname))
                                                      else:
                                                              py_class_file.write("""\t\treturn b''\n""")
                                              else:
                                                      py_class_file.write("""\t\tglobal beg_tag%s\n"""%classname)
                                                      py_class_file.write("""\t\treturn beg_tag%s%s(%s)\n"""%(classname, "\x25",begin_format[:-1]))
                                              py_class_file.write("""\tself.get_begin     = get_begin\n\n""")

                                              py_class_file.write("""\tdef get_end(self):\n""")
                                              if end_format == "":
                                                      if end_tag != "":
                                                              py_class_file.write("""\t\tglobal end_tag%s\n"""%classname)
                                                              py_class_file.write("""\t\treturn end_tag%s\n"""%(classname))
                                                      else:
                                                              py_class_file.write("""\t\treturn b''\n""")
                                              else:
                                                      py_class_file.write("""\t\tglobal end_tag%s\n"""%classname)
                                                      py_class_file.write("""\t\treturn end_tag%s%s(%s)\n"""%(classname, "\x25", end_format[:-1]))
                                              py_class_file.write("""\tself.get_end       = get_end\n\n""")

                                              for attribute in classattributes:
                                                      if attribute in ["pattern"]:
                                                              py_class_file.write('\tself.{:<12} = params.get("{}", b"*")\n'.format(attribute,attribute))
                                                      elif attribute in ["id","name"]:
                                                              py_class_file.write('\tself.{:<12} = params.get("{}", b"%d"%id(self))\n'.format(attribute,attribute))
                                                      elif attribute in ["disabled","active","novalidate","required"]:
                                                              py_class_file.write('\tself.{:<12} = params.get("{}", False)\n'.format(attribute,attribute))
                                                      elif attribute in ["checked"]:
                                                              py_class_file.write('\tself.{:<12} = params.get("{}", True)\n'.format(attribute,attribute))
                                                      else:
                                                              py_class_file.write('\tself.{:<12} = params.get("{}", b"")\n'.format(attribute,attribute))
                                              py_class_file.write('\tself.end_init(**params)\n')
                                              py_class_file.write('\treturn self\n')
                                      else:
                                              raise SyntaxError()
                      else:
                              if ignored is False:
                                      if line.strip() != "":
                                              if len(stack) >= 1:
                                                      stack[-1][1] += line.strip()
                                                      stack[-1][2] += "# " +line.lstrip()

              py_class_file.close()