----------------------------------------------------------------------- -- Extended HTML exporter in Lua for SciTE -- Version 0.9.5, 20070805 -- Based on SciTE_ExporterHTML.lua Version 0.9.3, 20040812 -- -- Adapted from SciTE sources (scite/src/Exporters.cxx CVS 20040723) -- by Kein-Hong Man (This is a straightforward -- conversion and so I decline to claim it as my own.) -- -- Copyright 1998-2007 by Neil Hodgson -- All Rights Reserved -- -- Permission to use, copy, modify, and distribute this software and -- its documentation for any purpose and without fee is hereby granted, -- provided that the above copyright notice appear in all copies and -- that both that copyright notice and this permission notice appear in -- supporting documentation. -- -- NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -- INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN -- NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR -- CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -- NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION -- WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -- ----------------------------------------------------------------------- -- USAGE -- -- * Please see SciTELuaExporters.html for notes on how to get this -- exporter up and running. -- * Requires SciTE_ExportBase.lua to be loaded first. -- * Has been tested casually with these lexers: lua, cpp, props, -- and basic text giving byte-for-byte identical output. -- * There is an extra property, "export.html.monospace" because -- useMonoFont is not exposed, so the following is default: -- export.html.monospace=0 -- * Added option for disabling HTML background as suggested by Ingmar -- Hupp on the SciTE list: -- # boolean: 1=have background (default), 0=no background -- export.html.background=1 -- * Adds encoding type of UTF-8 if this is set in SciTE ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- a simple check to alert of namespace collision, but allows different -- files to define their own functions in the exporters table ----------------------------------------------------------------------- if exporters then if exporters.SaveToHTML then error("SciTE_ExporterHTML: exporters.SaveToHTML already defined") end else exporters = {} end ----------------------------------------------------------------------- -- exporters:SaveToHTML -- -- Exports the document in the current window to a HTML format file. -- ----------------------------------------------------------------------- function exporters:SaveToHTML() local selBeg, selEnd = exportutil.GetSelPos() local HTMLDefaultTabSize = 4 -- helper functions to take care of flag bit/data reads -- note: SC_FOLDLEVELNUMBERMASK mask must have all ones!! local function foldlevel(raw) return raw % (SC_FOLDLEVELNUMBERMASK + 1) - SC_FOLDLEVELBASE end -- returns SC_FOLDLEVELHEADERFLAG flag in boolean -- note: SC_FOLDLEVELHEADERFLAG must have a single bit set local function foldheaderflag(lvl) local mask = SC_FOLDLEVELHEADERFLAG * 2 - 1 return lvl % mask >= SC_FOLDLEVELHEADERFLAG end editor:Colourise(0, -1) local tabSize = tonumber(props["tabsize"]) if not tabSize or tabSize == 0 then tabSize = HTMLDefaultTabSize end local wysiwyg = exportutil.propbool("export.html.wysiwyg", 1) local tabs = exportutil.propbool("export.html.tabs") local folding = exportutil.propbool("export.html.folding") local onlyStylesUsed = exportutil.propbool("export.html.styleused") local titleFullPath = exportutil.propbool("export.html.title.fullpath") local useMonoFont = exportutil.propbool("export.html.monospace") local useBackground = exportutil.propbool("export.html.background", 1) -- local lengthDoc = editor.Length local styleIsUsed = {} if onlyStylesUsed then -- check the used styles for i = selBeg, selEnd - 1 do styleIsUsed[exportutil.StyleAt(i)] = true end else for i = 0, exportutil.STYLE_MAX do styleIsUsed[i] = true end end styleIsUsed[exportutil.STYLE_DEFAULT] = true local saveName = exportutil.exportfile(props["FileDir"], props["FileName"], "html") local fp = io.open(saveName, "wt") if not fp then error("exporters:SaveToHTML: could not save file \""..saveName.."\"") end if exportutil.VERBOSE ~= 0 then _ALERT("\nExporting to HTML, filepath: "..saveName) end fp:write("\n", "\n", "\n") if titleFullPath then fp:write("", props["FilePath"], "\n") else fp:write("", props["FileNameExt"], "\n") end -- enable UTF-8 if encoding is so set in SciTE, doesn't check validity local utf8 = editor.CodePage == SC_CP_UTF8 if utf8 then fp:write("\n") end -- Probably not used by robots, but making a little advertisement for those looking -- at the source code doesn't hurt... fp:write("\n") if folding then fp:write("\n") end fp:write("\n", "\n") if bgColour then fp:write("\n") else fp:write("\n") end local line = editor:LineFromPosition(selBeg) local level = foldlevel(editor.FoldLevel[line]) local newLevel local styleCurrent = exportutil.StyleAt(selBeg) local inStyleSpan = false -- Global span for default attributes if wysiwyg then fp:write("") else fp:write("
")
  end

  if folding then
      local lvl = editor.FoldLevel[selBeg]
      level = foldlevel(lvl)

      if foldheaderflag(lvl) then
        fp:write("- ")
      else
        fp:write("  ")
      end
  end

  if styleIsUsed[styleCurrent] then
    fp:write("")
    inStyleSpan = true
  end
  -- Else, this style has no definition (beside default one):
  -- no span for it, except the global one

  local column = 0
  local i = selBeg
  while i < selEnd do
    local ch = exportutil.CharAt(i)
    local style = exportutil.StyleAt(i)

    if style ~= styleCurrent then
      if inStyleSpan then
        fp:write("")
        inStyleSpan = false
      end
      if ch ~= "\r" and ch ~= "\n" then     -- No need of a span for the EOL
        if styleIsUsed[style] then
          fp:write("")
          inStyleSpan = true
        end
        styleCurrent = style
      end
    end--style
    if ch == " " then
      if wysiwyg then
        local prevCh = "\0"
        if column == 0 then   -- At start of line, must put a   because regular space will be collapsed
          prevCh = " "
        end
        while i < selEnd and exportutil.CharAt(i) == " " do
          if prevCh ~= " " then
            fp:write(" ")
          else
            fp:write(" ")
          end
          prevCh = exportutil.CharAt(i)
          i = i + 1
          column = column + 1
        end
        i = i - 1 -- the last incrementation will be done by the for loop
      else
        fp:write(" ")
        column = column + 1
      end
    elseif ch == "\t" then
        local ts = tabSize - column % tabSize
        if wysiwyg then
          for itab = 0, ts - 1 do
            if itab % 2 == 1 then
              fp:write(" ")
            else
              fp:write(" ")
            end
          end
          column = column + ts
        else
          if tabs then
            fp:write(ch)
            column = column + 1
          else
            fp:write(string.rep(" ", ts))
            column = column + ts
          end
        end--wysiwyg
    elseif ch == "\r" or ch == "\n" then
      if inStyleSpan then
        fp:write("")
        inStyleSpan = false
      end
      if ch == "\r" and exportutil.CharAt(i + 1) == "\n" then
        i = i + 1 -- CR+LF line ending, skip the "extra" EOL char
      end
      column = 0
      if wysiwyg then
        fp:write("
") end styleCurrent = exportutil.StyleAt(i + 1) if folding then line = editor:LineFromPosition(i + 1) local lvl = editor.FoldLevel[line] newLevel = foldlevel(lvl) if newLevel < level then fp:write("") end fp:write("\n") -- here to get clean code if newLevel > level then fp:write("") end if foldheaderflag(lvl) then fp:write("- ") else fp:write("  ") end level = newLevel else fp:write("\n") end--folding if styleIsUsed[styleCurrent] and exportutil.CharAt(i + 1) ~= "\r" and exportutil.CharAt(i + 1) ~= "\n" then -- We know it's the correct next style, -- but no (empty) span for an empty line fp:write("") inStyleSpan = true end else if ch == "<" then fp:write("<") elseif ch == ">" then fp:write(">") elseif ch == "&" then fp:write("&") else fp:write(ch) end column = column + 1 end--if ch i = i + 1 end--while if inStyleSpan then fp:write("") end if folding then while level > 0 do fp:write("") level = level - 1 end end if not wysiwyg then fp:write("
") else fp:write("
") end fp:write("\n\n\n") fp:close() if exportutil.VERBOSE ~= 0 then exportutil.progress("... done.") end end -- end of script