docs: def render(plain,
             urlHandler=None,
             templatePaths=None,
             options=None,
             defaultTag='div',
             wikiStyle='basic'):
      """
      Renders the inputted plain text wiki information into HTML rich text.
      
      :param      plain       |  <str> | \
                                 Include some additional documentation
                  urlHandler  |  <UlrHandler> || None
      
      :return     <str> html
      """
      if not plain:
          return ''
  
      __style = WIKI_STYLES.styles.get(wikiStyle, WIKI_STYLES.styles['basic'])
  
      # process the wiki text with the mako template system
      if not urlHandler:
          urlHandler = UrlHandler.current()
  
      # render the text out from mako template
      plain = projex.makotext.render(plain,
                                     options=options,
                                     templatePaths=templatePaths,
                                     silent=True)
  
      # generate wiki doc info
      lines = re.split('\n\r|\r\n|\n|\r', plain)
      curr_section = ''
      curr_section_level = 0
      html = []
      skip = []
      nowiki_stack = []
      nowiki_mode = 'pre'
      code_stack = []
      table_stack = []
      list_stack = []
      section_stack = []
      toc_data = []
      align_div = ''
      list_indent = None
      ignore_list_stack = False
  
      # add the default tag
      html.append(__style['wiki_open'].format(tag=defaultTag))
  
      for i, line in enumerate(lines):
          ignore_list_stack = False
          sline = line.strip()
  
          #----------------------------------------------------------------------
          #                           INDENTATION CHECKS
          #----------------------------------------------------------------------
  
          # check to see if we are continuing a list entry
          if list_indent:
              line_indent = len(re.match('\s*', line).group())
  
              if line_indent < list_indent:
                  list_indent = None
                  html.append(__style['list_item_close'])
              else:
                  ignore_list_stack = True
  
                  if not sline:
                      html.append(__style['spacer'])
                      continue
  
          if i in skip:
              continue
  
          #----------------------------------------------------------------------
          #                           ALIGNMENT
          #----------------------------------------------------------------------
  
          # check for a center option
          center = EXPR_CENTER.match(sline)
          right = EXPR_RIGHT.match(sline)
          left = EXPR_LEFT.match(sline)
  
          if center:
              style = center.groups()[0]
              line = center.groups()[1].strip()
  
              if align_div and align_div != 'center':
                  html.append(__style['align_close'])
                  align_div = ''
  
              if not align_div:
                  if style == '--':
                      html.append(__style['align_center'])
                  else:
                      html.append(__style['align_center_floated'])
                  align_div = 'center'
  
              else:
                  html.append(__style['newline'])
  
          # check for a right align option
          elif right:
              style = right.groups()[0]
              line = right.groups()[1]
  
              if align_div and align_div != 'right':
                  html.append(__style['align_close'])
                  align_div = ''
  
              if not align_div:
                  if style == '--':
                      html.append(__style['align_right'])
                  else:
                      html.append(__style['align_right_floated'])
                  align_div = 'right'
              else:
                  html.append(__style['newline'])
  
          # check for a left align option
          elif left:
              style = left.groups()[1]
              line = left.groups()[0]
  
              if align_div and align_div != 'left':
                  html.append(__style['align_close'])
                  align_div = ''
  
              if not align_div:
                  if style == '--':
                      html.append(__style['align_left'])
                  else:
                      html.append(__style['align_left_floated'])
  
                  align_div = 'left'
              else:
                  html.append(__style['newline'])
  
          # otherwise, clear alignment
          elif align_div:
              html.append(__style['align_close'])
              align_div = ''
  
          #----------------------------------------------------------------------
          #                           INDENTATION CHECKS
          #----------------------------------------------------------------------
  
          # make sure we're on the same level
          if curr_section and sline and (len(line) - len(line.lstrip())) < curr_section_level:
              html += section_stack
              section_stack = []
  
              curr_section = ''
              curr_section_level = 0
  
          count = i
          while sline.endswith('\\') and count + 1 < len(lines):
              sline += ' ' + lines[count + 1].strip()
              skip.append(count)
              count += 1
  
          #----------------------------------------------------------------------
          #                           IGNORE WIKI INFORMATION
          #----------------------------------------------------------------------
  
          # check to see what is wiki protected
          if sline.startswith('<nowiki'):
              mode = re.search('mode="(\w*)"', sline)
              if mode:
                  nowiki_mode = nstr(mode.group(1))
              else:
                  nowiki_mode = None
  
              if not ignore_list_stack:
                  html += list_stack
                  list_stack = []
  
              html += table_stack
              table_stack = []
  
              if nowiki_mode is None:
                  html.append(__style['nowiki_open'])
                  nowiki_stack.append(__style['nowiki_close'])
              else:
                  nowiki_stack.append('')
  
              continue
  
          elif sline == '</nowiki>':
              html += nowiki_stack
              nowiki_stack = []
              continue
  
          elif nowiki_stack:
              if nowiki_mode == 'safe':
                  html.append(line)
              else:
                  html.append(xml.sax.saxutils.escape(line))
              continue
  
          #----------------------------------------------------------------------
          #                           TABLES
          #----------------------------------------------------------------------
  
          parts = line.split(' | ')
          if len(parts) == 1:
              html += table_stack
              table_stack = []
  
          # replace standard items
          for key, repl in PRE_ESCAPE_REPLACE.items():
              line = line.replace(key, repl)
  
          # strip out nowiki lines
          nowiki_dict = {}
          count = 0
          for section in EXPR_NOWIKI.findall(line)[::2]:
              nowiki_dict['nowiki_%i' % count] = section
              newtext = '%%(nowiki_%i)s' % count
              line = line.replace('<nowiki>%s</nowiki>' % section, newtext)
              count += 1
  
          #----------------------------------------------------------------------
          #                           SECTIONS
          #----------------------------------------------------------------------
  
          # check for a div section
          section = EXPR_SECTION.match(sline)
          if section:
              html += code_stack
              code_stack = []
  
              name = section.group(2)
              if name != curr_section:
                  html += section_stack
                  section_stack = []
  
                  if name not in SECTION_ALERTS:
                      section_stack.append(__style['section_close'])
  
                      display = projex.text.capitalizeWords(name)
                      mapped = SECTION_MAP.get(name, display)
  
                      html.append(__style['section_open'].format(name=name,
                                                                 title=mapped))
                  else:
                      display = projex.text.capitalizeWords(name)
                      mapped = SECTION_MAP.get(name, display)
  
                      section_stack.append(__style['section_alert_close'])
                      url, success = urlHandler.resolve('img:%s.png' % name)
                      html.append(__style['section_alert_open'].format(name=name,
                                                                       title=mapped))
  
                  curr_section = name
              else:
                  html.append(__style['newline'])
  
              sline = sline.replace(section.group(), '')
              line = line.replace(section.group(), ' ' * len(section.group()))
              curr_section_level = len(line) - len(line.lstrip())
  
          #----------------------------------------------------------------------
          #                           CODE
          #----------------------------------------------------------------------
  
          # check for code
          code = EXPR_CODE.match(sline)
          if code:
              templ = ''
              code_line = code.groups()[0]
  
              if not code_stack:
                  lang = 'python'
                  lang_search = EXPR_LANG.search(code_line)
  
                  if lang_search:
                      lang = lang_search.groups()[0]
                      code_line = code_line.replace(lang_search.group(), '')
  
                  templ = __style['code_open'].format(lang=lang)
                  code_stack.append(__style['code_close'])
  
              escaped = xml.sax.saxutils.escape(code_line)
  
              if not ignore_list_stack:
                  html += list_stack
                  list_stack = []
  
              html += table_stack
              table_stack = []
  
              html.append(templ + escaped)
              continue
  
          # exit out of the code mode
          else:
              html += code_stack
              code_stack = []
  
          #----------------------------------------------------------------------
  
          # make sure we have no html data in the line
          if not sline:
              html.append(__style['paragraph_close'])
              html.append(__style['paragraph_open'])
              continue
  
          # check for horizontal rules
          if EXPR_HR.match(sline):
              style = ''
              html.append(__style['hr'].format(style=style))
              continue
  
          #----------------------------------------------------------------------
          #                           HEADERS
          #----------------------------------------------------------------------
  
          # check for headers
          header = EXPR_HEADER.match(sline)
          if header:
              hopen, title, hclose = header.groups()
              hopencount = len(hopen)
              title = title.strip()
  
              if hopencount == len(hclose):
                  name = projex.text.underscore(title)
                  add = __style['header'].format(name=name,
                                                 title=title,
                                                 size=len(hopen))
                  spacing = '#' * hopencount
                  opts = (spacing, name, title)
                  toc_data.append('%s. [[#%s|%s]]' % opts)
  
                  if not ignore_list_stack:
                      html += list_stack
                      list_stack = []
  
                  html += table_stack
                  table_stack = []
  
                  html.append(add)
                  continue
  
          line = xml.sax.saxutils.escape(line)
  
          for key, repl in POST_ESCAPE_REPLACE.items():
              line = line.replace(key, repl)
  
          #----------------------------------------------------------------------
          #                           CLASS TYPES
          #----------------------------------------------------------------------
  
          # resolve any class links
          for result in EXPR_CLASS_LINK.findall(line):
              opts = result.split()
              for o, cls in enumerate(opts):
                  # ignore base classes, need modules
                  if '.' not in cls:
                      continue
  
                  url, success = urlHandler.resolveClass(cls)
                  if success:
                      opts[o] = __style['link_class'].format(url=url,
                                                             text=cls.split('.')[-1])
  
              info = __style['span_class'].format(crumbs=' '.join(opts))
              line = line.replace('&lt;' + result + '&gt;', info)
  
          #----------------------------------------------------------------------
          #                           GENERAL FORMATTING
          #----------------------------------------------------------------------
  
          # replace formatting options
          for section in EXPR_UNDERLINE.findall(line)[::2]:
              text = __style['underline'].format(text=section)
              line = line.replace("___%s___" % section, text)
  
          for section in EXPR_INLINE_CODE.findall(line)[::2]:
              text = __style['inline_code'].format(text=section)
              line = line.replace("`%s`" % section, text)
  
          for section in EXPR_STRIKEOUT.findall(line)[::2]:
              text = __style['strikeout'].format(text=section)
              line = line.replace("---%s---" % section, text)
  
          for section in EXPR_BOLD.findall(line)[::2]:
              text = __style['bold'].format(text=section)
              line = line.replace("'''%s'''" % section, text)
  
          for section in EXPR_ITALIC.findall(line)[::2]:
              text = __style['italic'].format(text=section)
              line = line.replace("''%s''" % section, text)
  
          #----------------------------------------------------------------------
          #                           IMAGES
          #----------------------------------------------------------------------
  
          # resolve any images
          for grp, url in EXPR_IMG.findall(line):
              urlsplit = url.split('|')
              last_word = re.findall('\w+', urlsplit[0])[-1]
  
              if len(urlsplit) == 1:
                  urlsplit.append('')
  
              url, _ = urlHandler.resolveImage(urlsplit[0])
              line = line.replace(grp, __style['img'].format(url=url,
                                                             style=urlsplit[1],
                                                             title=last_word))
  
          #----------------------------------------------------------------------
          #                           COLORS
          #----------------------------------------------------------------------
  
          # resolve any colors
          for grp, coloring in EXPR_COLOR.findall(line):
              splt = coloring.split('|')
              if len(splt) == 1:
                  splt.append('')
  
              line = line.replace(grp, __style['color'].format(color=splt[0],
                                                               text=splt[1]))
  
          #----------------------------------------------------------------------
          #                           SPANS
          #----------------------------------------------------------------------
  
          # resolve any spans
          for grp, coloring in EXPR_SPAN.findall(line):
              splt = coloring.split('|')
              if len(splt) == 1:
                  splt.append('')
  
              templ = '<span style="%s">%s</span>' % (splt[0], splt[1])
              line = line.replace(grp, __style['span'].format(style=splt[0],
                                                              text=splt[1]))
  
          #----------------------------------------------------------------------
          #                           LINKS
          #----------------------------------------------------------------------
  
          # resolve any external urls
          for result in EXPR_EXTLINK.findall(line):
              grp = result[0]
              url = result[1]
  
              urlsplit = url.split()
              if len(urlsplit) == 1:
                  urlsplit.append(urlsplit[0])
  
              url = urlsplit[0]
              urltext = ' '.join(urlsplit[1:])
  
              line = line.replace(grp, __style['link_ext'].format(url=url, text=urltext))
  
          # resolve any internal urls
          for grp, url in EXPR_INTLINK.findall(line):
              urlsplit = url.split('|')
              if len(urlsplit) == 1:
                  last_word = re.findall('\w+', urlsplit[0])[-1]
                  urlsplit.append(last_word)
  
              url = urlsplit[0]
              title = '|'.join(urlsplit[1:])
              found = True
  
              tagsplit = url.split('#')
              if len(tagsplit) == 1:
                  url = url
                  tag = ''
              else:
                  url = tagsplit[0]
                  tag = '#'.join(tagsplit[1:])
  
              # make sure the url exists
              if url:
                  url, exists = urlHandler.resolve(url)
                  if not exists:
                      found = False
  
              # join together the resolved url and the tag
              if tag:
                  url = url + '#' + tag
  
              # generate the link
              if found:
                  templ = __style['link_found'].format(url=url, text=title)
              else:
                  templ = __style['link_not_found'].format(url=url, text=title)
  
              line = line.replace(grp, templ)
  
          #----------------------------------------------------------------------
          #                           LISTS
          #----------------------------------------------------------------------
  
          # process lists
          results = EXPR_LIST.match(line)
          if results:
              level, linetext = results.groups()
              level_count = len(level)
              level_type = 'unordered' if level[-1] == '*' else 'ordered'
  
              while level_count > len(list_stack):
                  html.append(__style[level_type + '_list_open'])
                  list_stack.append(__style[level_type + '_list_close'])
  
              while len(list_stack) > level_count:
                  html.append(list_stack[-1])
                  list_stack = list_stack[:-1]
  
              space_line = line.replace(level + '.', ' ' * (len(level) + 1))
              list_indent = len(re.match('\s*', space_line).group())
  
              html.append(__style['list_item_open'])
              html.append(linetext)
  
              continue
  
          elif not ignore_list_stack:
              html += list_stack
              list_stack = []
  
          #----------------------------------------------------------------------
          #                           TABLES
          #----------------------------------------------------------------------
  
          parts = line.split(' | ')
          if len(parts) > 1:
              if not table_stack:
                  table_stack.append(__style['table_close'])
                  html.append(__style['table_open'])
  
              cell_type = 'td'
              styles = ''
  
              cells = []
              for part in parts:
                  results = EXPR_TABLE_CELL.search(part)
  
                  if not results:
                      cells.append(__style['table_cell'].format(tag='td',
                                                                style='',
                                                                text=part.strip()))
  
                  else:
                      grp, cell_type, styles = results.groups()
  
                      if not styles:
                          styles = ''
                      else:
                          styles = styles.strip('[]')
  
                      part = part.replace(grp, '').strip()
                      opts = (cell_type, styles, part, cell_type)
  
                      cells.append(__style['table_cell'].format(tag=cell_type,
                                                                style=styles,
                                                                text=part))
  
              line = __style['table_row'].format(text=''.join(cells))
  
              html.append((line % nowiki_dict))
  
          else:
              html += table_stack
              table_stack = []
  
              html.append(line % nowiki_dict)
  
      if align_div:
          html.append(__style['align_close'])
  
      if list_indent:
          html.append(__style['list_item_close'])
  
      html += table_stack
      html += list_stack
      html += code_stack
      html += nowiki_stack
      html += section_stack
  
      html.append(__style['wiki_close'].format(tag=defaultTag))
      html_txt = '\n'.join(html)
  
      # resolve any table of contents
      for toc, options in EXPR_TOC.findall(html_txt):
          toc_wiki = '\n\t'.join(toc_data)
          toc_html = __style['toc_open']
          toc_html += render(toc_wiki, urlHandler, templatePaths, options, 'div', wikiStyle)
          toc_html += __style['toc_close']
  
          html_txt = html_txt.replace(toc, toc_html)
  
      # replace \[ and \] options
      html_txt = html_txt.replace('\[', '[').replace('\]', ']')
  
      return html_txt