💾 Archived View for gemini.conman.org › extensions › GLV-1 › handlers › reflow.lua captured on 2023-11-14 at 10:06:40.

View Raw

More Information

⬅️ Previous capture (2022-06-04)

-=-=-=-=-=-=-

-- ************************************************************************
--
--    A reflow experiment,
--    Copyright 2020 by Sean Conner.  All Rights Reserved.
--
--    This program is free software: you can redistribute it and/or modify
--    it under the terms of the GNU General Public License as published by
--    the Free Software Foundation, either version 3 of the License, or
--    (at your option) any later version.
--
--    This program is distributed in the hope that it will be useful,
--    but WITHOUT ANY WARRANTY; without even the implied warranty of
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--    GNU General Public License for more details.
--
--    You should have received a copy of the GNU General Public License
--    along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
--    Comments, questions and criticisms can be sent to: sean@conman.org
--
-- ************************************************************************
-- luacheck: globals init handler
-- luacheck: ignore 611

local wrapt    = require "org.conman.string".wrapt
local syslog   = require "org.conman.syslog"
local lpeg     = require "lpeg"
local io       = require "io"
local string   = require "string"

local ipairs   = ipairs
local tonumber = tonumber

_ENV = {}

-- ************************************************************************

function init(conf)
  if not conf.file then
    return false,"Missing file directive"
  end
  return true
end

-- ************************************************************************

local parse = lpeg.P";" * (lpeg.R"09"^1 / tonumber) * lpeg.P(-1)
            + lpeg.P(-1) * lpeg.Cc(80)
            
function handler(conf,_,_,pathinfo,ios)
  local width = parse:match(pathinfo)
  if not width or width < 10 then
    ios:write("59\r\n")
    return 59
  end
  
  local file,err = io.open(conf.file,"r")
  
  if not file then
    syslog('error',"%s = %s",conf.file,err)
    ios:write("40\r\n")
    return 40
  end
  
  ios:write("20 text/gemini\r\n")
  
  local literal = false
  
  for line in file:lines() do
    if line:match "^%#" then
      local hdr,title = line:match("^(%#+)%s*(.*)")
      local text      = wrapt(title,width - (#hdr + 1))
      
      ios:write(string.format("%s %s",hdr,text[1]),"\r\n")
      for i = 2 , #text do
        ios:write(string.format("%s %s",string.rep(" ",#hdr),text[i]),"\r\n")
      end
      
    elseif line:match "^```$" then
      literal = not literal
      
    elseif line:match "^%=%>" then
      local url,text = line:match("^%=%>%s*(%S+)%s*(.*)")
      if text == "" then text = url end
      ios:write(string.format("=> %s",text:sub(1,width - 3)),"\r\n")
      
    else
      if literal then
        ios:write(line:sub(1,width),"\r\n")
      else
        local text = wrapt(line,width)
        for _,l in ipairs(text) do
          ios:write(l,"\r\n")
        end
      end
    end
  end
  
  return 20
end

-- ************************************************************************

return _ENV