diff --git a/categ/display.lua b/categ/display.lua new file mode 100755 index 0000000..315b923 --- /dev/null +++ b/categ/display.lua @@ -0,0 +1,58 @@ +#!/usr/bin/env lua + +-- display.lua +-- Display content of a file and attempt to match some specific words +-- author: Olivier DOSSMANN (olivier+lua@dossmann.net) + +--[[ requirement ]]-- +require 'lfs' -- apt-get install liblua5.1-filesystem0 || luarocks install luafilesystem + +function process(filepath) + -- parse given file + for line in io.lines(filepath) do + -- check if this line is a comment ("# my comment"), a category ("[[My category]]Its description") or an element ("Title##Description##URL##Image") + is_comment = string.find(line, '^#+.*') + is_title = string.find(line, '%[%[(.*)%]%](.*)') + is_element = string.find(line, '(.*)##(.*)##(.*)##(.*)') + if is_comment then + -- do nothing because it's a comment + elseif is_title then + title = '' + for t in string.gmatch(line, '%[%[(.*)%]%].*') do title = title .. t end + description ='' + for d in string.gmatch(line, '%[%[.*%]%](.*)') do description = description .. d end + print("TITLE: " .. '\n\t' .. title .. '\n\t' .. description) + elseif is_element then + title = '' + description = '' + url = '' + img = '' + for t in string.gmatch(line, '(.*)##.*##.*##.*') do title = title .. t end + for d in string.gmatch(line, '.*##(.*)##.*##.*') do description = description .. d end + for u in string.gmatch(line, '.*##.*##(.*)##.*') do url = url .. u end + for i in string.gmatch(line, '.*##.*##.*##(.*)') do img = img .. i end + print("ELEMENT: " .. '\n\t' .. title .. '\n\t' .. description .. '\n\t' .. url .. '\n\t' .. img) + end + end +end + +function help() + print('Usage: ' .. arg[0] .. ' FILE...') +end + +if arg and table.getn(arg) > 0 then + for i, file in pairs(arg) do + if i > 0 then + attr = lfs.attributes(file) + if attr and attr.mode == 'file' then + process(file) + else + print('INFO: ' .. file .. ' is not a file or doesn\'t exists.') + end + end + end +else + print('WARNING: No argument given.') + help() + os.exit(1) +end diff --git a/composants/categ.html b/composants/categ.html new file mode 100644 index 0000000..703c10d --- /dev/null +++ b/composants/categ.html @@ -0,0 +1,8 @@ + + +

${CATEG_TITLE}

+

${CATEG_DESC}

+ +
 
diff --git a/composants/index.html b/composants/index.html new file mode 100644 index 0000000..8881867 --- /dev/null +++ b/composants/index.html @@ -0,0 +1,31 @@ + + + + ${TITLE} + + + + + + +
+

${PORTEAIL_TITLE}

+
+ + +
+ ${INTRODUCTION} + ${CONTENT} +
+ +${MENU} + + + + + + diff --git a/composants/one_element.html b/composants/one_element.html new file mode 100644 index 0000000..8cc2a2e --- /dev/null +++ b/composants/one_element.html @@ -0,0 +1,10 @@ +
  • + + + ${ELEMENT_TITLE}
    + + ${IMG_DESC} +
    +
    +
  • + diff --git a/porteail.lua b/porteail.lua new file mode 100755 index 0000000..90fb425 --- /dev/null +++ b/porteail.lua @@ -0,0 +1,275 @@ +#!/usr/bin/env lua + +-- porteail.lua + +--[[ Requirements ]]-- + +require 'lfs' + +--[[ Variables ]]-- + +-- Mandatories files +local configFile = './' .. 'configrc' +-- Default directories values +local currentpath = os.getenv('CURDIR') or '.' +local default_dir_category = 'categ' +local default_dir_component = 'composants' +local default_dir_destination = 'porteail' +local default_dir_img_destination = 'image' +local default_dir_img_source = 'img' +local default_dir_css_source = 'style' +-- Default files values +local default_img_filename = 'generique.png' +local default_index_filename = 'index.html' +local default_template_index_filename = 'index.html' +local default_template_categ_filename = 'categ.html' +local default_template_element_filename = 'one_element.html' +local default_css_filename = 'noir.css' +local default_css_menu_without = 'sans_menu.css' +local default_css_menu_with = 'avec_menu.css' +-- Other defaults values +local default_categ_extension = 'txt' +local DIR_SEP = '/' +local default_css_name = 'Défaut' + +--[[ Functions ]]-- + +function readFile(path, mode) + result = '' + if not mode then + mode = 'r' + end + if mode ~= 'r' and mode ~= 'rb' then + print('Unknown read mode!') + os.exit(1) + end + attr = lfs.attributes(path) + if attr and attr.mode == 'file' then + f = assert(io.open(path, mode)) + result = assert(f:read('*a')) + assert(f:close()) + end + return result +end + +function getConfig(file) + result = {} + f = assert(io.open(file, 'r')) + while true do + line = f.read(f) + if not line then break end + local key = line:match('([^#].-)[ ]+=') + local val = line:match('=[ ]+(.*)') + local comment = string.find(line, '^#+(.*)') + if comment then + -- do nothing with comment + elseif key then + result[key] = val + end + end + assert(f:close()) + return result +end + +function replace(string, table) + return string:gsub("$(%b{})", function(string) + return table[string:sub(2,-2)] + end) +end + +function listing (path, extension) + files = {} + if lfs.attributes(path) then + for file in lfs.dir(path) do + if file ~= "." and file ~= ".." then + local f = path..'/'..file + local attr = lfs.attributes (f) + filext = (string.match(file, "[^\\/]-%.?([^%.\\/]*)$")) + if attr.mode == 'file' and filext == extension then + table.insert(files, f) + end + end + end + else + files = nil + end + return files +end + +function basename (string, suffix) + string = string or '' + local basename = string.gsub (string, '[^'.. DIR_SEP ..']*'.. DIR_SEP ..'', '') + if suffix then + basename = string.gsub (basename, suffix, '') + end + return basename +end + +function processImage(image, source, img_destination, destination, default_img) + -- if no image given, use default one + if not image or image == nil or image == '' then + image = default_img + end + -- create image weblink + result = img_destination .. '/' .. basename(image) + -- check if this image exists + attr = lfs.attributes(destination .. '/' .. result) + if not attr then + img_path = source .. '/' .. image + f = assert(io.open(img_path, 'rb')) + img_src = assert(f:read('*a')) + assert(f:close()) + img_dest = assert(io.open(destination .. '/' .. result, 'wb')) + assert(img_dest:write(img_src)) + assert(img_dest:close()) + end + return result +end + +function process(filepath, template_categ, template_element, img_destination, destination, img_source, default_img) + -- parse given file + local categ_page = '' + local elements = {} + for line in io.lines(filepath) do + local element = '' + -- check if this line is a comment ("# my comment"), a category ("[[My category]]Its description") or an element ("Title##Description##URL##Image") + is_comment = string.find(line, '^#+.*') + is_title = string.find(line, '%[%[(.*)%]%](.*)') + is_element = string.find(line, '(.*)##(.*)##(.*)##(.*)') + if is_comment then + -- do nothing because it's a comment + elseif is_title then + title = '' + for t in string.gmatch(line, '%[%[(.*)%]%].*') do title = title .. t end + description ='' + for d in string.gmatch(line, '%[%[.*%]%](.*)') do description = description .. d end + categ_page = replace(template_categ, {CATEG_TITLE=title, CATEG_DESC=description}) + elseif is_element then + title = '' + description = '' + url = '' + img = '' + for t in string.gmatch(line, '(.*)##.*##.*##.*') do title = title .. t end + for d in string.gmatch(line, '.*##.*##(.*)##.*') do description = description .. d end + for u in string.gmatch(line, '.*##(.*)##.*##.*') do url = url .. u end + for i in string.gmatch(line, '.*##.*##.*##(.*)') do img = img .. i end + img_description = " " + img_url = processImage(img, img_source, img_destination, destination, default_img) + url = url:gsub('%&', '%&') + element = replace(template_element, {ELEMENT_URL=url, ELEMENT_DESC=description, ELEMENT_TITLE=title, IMG_URL=img_url, IMG_DESC=img_description}) + table.insert(elements, element) + end + end + local text_elements = '' + for k, v in pairs(elements) do + text_elements = text_elements .. v + end + local result = replace(categ_page, {ELEMENTS=text_elements}) + return result +end + +--[[ Principal ]]-- + +-- fetch user defined values +config = getConfig(configFile) + +-- create values for directories +categ = config['CATEGORIES'] or default_dir_category +component = config['COMPOSANTS'] or default_dir_component +destination = config['CIBLE'] or default_dir_destination +img_destination = config['CIBLE_IMAGE'] or default_dir_img_destination +img_source = config['IMAGES'] or default_dir_img_source +css_source = config['CSS'] or default_dir_css_source +-- create values for files +index_filename = config['INDEX'] or default_index_filename +main_template = config['TEMPLATE_INDEX'] or default_template_index_filename +template_categ_filename = config['TEMPLATE_CATEG'] or default_template_categ_filename +template_element_filename = config['TEMPLATE_ELEMENT'] or default_template_element_filename +default_img = config['DEFAUT_IMG'] or default_img_filename +css_filename = config['STYLE'] or default_css_filename +css_menu = default_css_menu_without +local menu = config['MENU'] or '' +if config['MENU'] then + css_menu = default_css_menu_with +end +local introduction = config['INTRO'] or '' +-- other default values +categ_extension = config['CATEGORIES_EXT'] or default_categ_extension +css_name = config['CSS_NAME'] or default_css_name + +-- get pages +index = readFile(currentpath .. '/' .. component .. '/' .. index_filename, 'r') +template_categ = readFile(currentpath .. '/' .. component .. '/' .. template_categ_filename, 'r') +template_element = readFile(currentpath .. '/' .. component .. '/' .. template_element_filename, 'r') +-- open menu file if menu have been activated +local menu_content = '' +if menu ~= '' then + menu_content = readFile(component .. '/' .. menu, 'r') +end +-- open introduction file if intro have been activated +local introduction_content = '' +if introduction ~= '' then + introduction_content = readFile(component .. '/' .. introduction, 'r') +end + +-- Check if public and image directory exists +for i, dir in pairs({destination, destination .. '/' .. img_destination}) do + if lfs.attributes(dir) == nil then + assert(lfs.mkdir(dir)) + end +end + +-- Browse categ directory +local categories_files = listing (currentpath .. '/' .. categ, categ_extension) +local content = '' +if categories_files then + for k,v in pairs(categories_files) do + -- read category content + attr = lfs.attributes(v) + if attr and attr.mode == 'file' then + content = content .. process(v, template_categ, template_element, img_destination, destination, img_source, default_img) + end + end +else + print ("-- No category file found!") +end + +-- Create index file in destination directory +result = assert(io.open(destination .. '/' .. main_template, 'wb')) +-- create substitution table +substitutions = { + TITLE=config['TITRE'] .. ' - Accueil', + PORTEAIL_TITLE=config['TITRE'], + CONTENT=content, + INTRODUCTION=introduction_content, + MENU=menu_content, + CSS_COLOR=css_filename, + CSS_NAME=css_name, + DEFAULT_CSS=css_menu, +} +-- replace variables in result +homepage = replace(index, substitutions) +assert(result:write(homepage)) +-- close file +assert(result:close()) + +-- Copy miscellaneous files to destination +to_be_copied = { + component .. '/' .. 'html5.js', + css_source .. '/' .. css_filename, + css_source .. '/' .. css_menu, +} +for i, filepath in pairs(to_be_copied) do + fileattr = lfs.attributes(filepath) + if not fileattr or fileattr.mode ~= 'file' then + print (filepath .. " doesn't exist or is not a file!") + os.exit(1) + end + dest = destination .. '/' .. basename(filepath) + filecontent = readFile(filepath, 'r') + destfile = assert(io.open(dest, 'wb')) + assert(destfile:write(filecontent)) + assert(destfile:close()) +end + +--[[ END ]]--