जैसा कि वादा किया गया था, यहाँ मेरा काहिरा संस्करण है। मैंने इसे Lua के साथ लिपिबद्ध किया, निर्देशिकाओं को चलाने के लिए lfs का उपयोग किया। मुझे इन छोटी चुनौतियों से प्यार है, क्योंकि वे मुझे एपीआई का पता लगाने की अनुमति देते हैं जो मैं काफी समय से खोदना चाहता था ...
lfs और LuaCairo दोनों क्रॉस-प्लेटफॉर्म हैं, इसलिए इसे अन्य प्रणालियों (फ्रेंच WinXP प्रो SP3 पर परीक्षण) पर काम करना चाहिए।
जैसे ही मैंने पेड़ पर चढ़ा, मैंने एक पहला संस्करण ड्राइंग फ़ाइल नाम बनाया। लाभ: कोई स्मृति उपरिव्यय। असुविधा: मुझे पहले से छवि का आकार निर्दिष्ट करना है, इसलिए लिस्टिंग के कट जाने की संभावना है।
इसलिए मैंने इस संस्करण को बनाया, पहले डायरेक्टरी ट्री को चलते हुए, इसे एक लुआ टेबल में संग्रहीत किया। फिर, फ़ाइलों की संख्या जानने के लिए, कैनवास को फिट करने के लिए (कम से कम लंबवत) बनाने और नामों को आरेखित करना।
आप आसानी से PNG रेंडरिंग और SVG वन के बीच स्विच कर सकते हैं। उत्तरार्द्ध के साथ समस्या: काहिरा इसे निम्न स्तर पर उत्पन्न करता है, एसवीजी की पाठ क्षमता का उपयोग करने के बजाय अक्षरों को खींचता है। ठीक है, कम से कम, यह फ़ॉन्ट के बिना सिस्टम पर भी सटीक रेंडरिंग की गारंटी देता है। लेकिन फाइलें बड़ी हैं ... वास्तव में एक समस्या नहीं है यदि आप इसे .svgz फाइल करने के बाद इसे संक्षिप्त करते हैं।
या सीधे एसवीजी उत्पन्न करना बहुत कठिन नहीं होना चाहिए, मैंने अतीत में एसवीजी उत्पन्न करने के लिए लुआ का उपयोग किया था।
-- LuaFileSystem <http://www.keplerproject.org/luafilesystem/>
require"lfs"
-- LuaCairo <http://www.dynaset.org/dogusanh/>
require"lcairo"
local CAIRO = cairo
local PI = math.pi
local TWO_PI = 2 * PI
--~ local dirToList = arg[1] or "C:/PrgCmdLine/Graphviz"
--~ local dirToList = arg[1] or "C:/PrgCmdLine/Tecgraf"
local dirToList = arg[1] or "C:/PrgCmdLine/tcc"
-- Ensure path ends with /
dirToList = string.gsub(dirToList, "([^/])$", "%1/")
print("Listing: " .. dirToList)
local fileNb = 0
--~ outputType = 'svg'
outputType = 'png'
-- dirToList must have a trailing slash
function ListDirectory(dirToList)
local dirListing = {}
for file in lfs.dir(dirToList) do
if file ~= ".." and file ~= "." then
local fileAttr = lfs.attributes(dirToList .. file)
if fileAttr.mode == "directory" then
dirListing[file] = ListDirectory(dirToList .. file .. '/')
else
dirListing[file] = ""
end
fileNb = fileNb + 1
end
end
return dirListing
end
--dofile[[../Lua/DumpObject.lua]] -- My own dump routine
local dirListing = ListDirectory(dirToList)
--~ print("\n" .. DumpObject(dirListing))
print("Found " .. fileNb .. " files")
--~ os.exit()
-- Constants to change to adjust aspect
local initialOffsetX = 20
local offsetY = 50
local offsetIncrementX = 20
local offsetIncrementY = 12
local iconOffset = 10
local width = 800 -- Still arbitrary
local titleHeight = width/50
local height = offsetIncrementY * (fileNb + 1) + titleHeight
local outfile = "CairoDirTree." .. outputType
local ctxSurface
if outputType == 'svg' then
ctxSurface = cairo.SvgSurface(outfile, width, height)
else
ctxSurface = cairo.ImageSurface(CAIRO.FORMAT_RGB24, width, height)
end
local ctx = cairo.Context(ctxSurface)
-- Display a file name
-- file is the file name to display
-- offsetX is the indentation
function DisplayFile(file, bIsDir, offsetX)
if bIsDir then
ctx:save()
ctx:select_font_face("Sans", CAIRO.FONT_SLANT_NORMAL, CAIRO.FONT_WEIGHT_BOLD)
ctx:set_source_rgb(0.5, 0.0, 0.7)
end
-- Display file name
ctx:move_to(offsetX, offsetY)
ctx:show_text(file)
if bIsDir then
ctx:new_sub_path() -- Position independent of latest move_to
-- Draw arc with absolute coordinates
ctx:arc(offsetX - iconOffset, offsetY - offsetIncrementY/3, offsetIncrementY/3, 0, TWO_PI)
-- Violet disk
ctx:set_source_rgb(0.7, 0.0, 0.7)
ctx:fill()
ctx:restore() -- Restore original settings
end
-- Increment line offset
offsetY = offsetY + offsetIncrementY
end
-- Erase background (white)
ctx:set_source_rgb(1.0, 1.0, 1.0)
ctx:paint()
--~ ctx:set_line_width(0.01)
-- Draw in dark blue
ctx:set_source_rgb(0.0, 0.0, 0.3)
ctx:select_font_face("Sans", CAIRO.FONT_SLANT_NORMAL, CAIRO.FONT_WEIGHT_BOLD)
ctx:set_font_size(titleHeight)
ctx:move_to(5, titleHeight)
-- Display title
ctx:show_text("Directory tree of " .. dirToList)
-- Select font for file names
ctx:select_font_face("Sans", CAIRO.FONT_SLANT_NORMAL, CAIRO.FONT_WEIGHT_NORMAL)
ctx:set_font_size(10)
offsetY = titleHeight * 2
-- Do the job
function DisplayDirectory(dirToList, offsetX)
for k, v in pairs(dirToList) do
--~ print(k, v)
if type(v) == "table" then
-- Sub-directory
DisplayFile(k, true, offsetX)
DisplayDirectory(v, offsetX + offsetIncrementX)
else
DisplayFile(k, false, offsetX)
end
end
end
DisplayDirectory(dirListing, initialOffsetX)
if outputType == 'svg' then
cairo.show_page(ctx)
else
--cairo.surface_write_to_png(ctxSurface, outfile)
ctxSurface:write_to_png(outfile)
end
ctx:destroy()
ctxSurface:destroy()
print("Found " .. fileNb .. " files")
बेशक, आप शैलियों को बदल सकते हैं। मैंने कनेक्शन लाइनें नहीं खींचीं, मैंने इसे आवश्यक नहीं देखा। मैं उन्हें बाद में वैकल्पिक रूप से जोड़ सकता हूं।