What tool to use to draw file tree diagram [closed] What tool to use to draw file tree diagram [closed] shell shell

What tool to use to draw file tree diagram [closed]


Copying and pasting from the MS-DOS tree command might also work for you. Examples:

tree

C:\Foobar>treeC:.├───FooScripts├───barconfig├───Baz│   ├───BadBaz│   └───Drop...

tree /F

C:\Foobar>treeC:.├───FooScripts│    foo.sh├───barconfig│    bar.xml├───Baz│   ├───BadBaz│   │    badbaz.xml│   └───Drop...

tree /A

C:\Foobar>tree /AC:.+---FooScripts+---barconfig+---Baz¦   +---BadBaz¦   \---Drop...

tree /F /A

C:\Foobar>tree /AC:.+---FooScripts¦    foo.sh+---barconfig¦    bar.xml+---Baz¦   +---BadBaz¦   ¦    badbaz.xml¦   \---Drop...

Syntax [source]

tree [drive:][path] [/F] [/A]

drive:\path — Drive and directory containing disk for display of directory structure, without listing files.

/F — Include all files living in every directory.

/A — Replace graphic characters used for linking lines with ext characters , instead of graphic characters. /a is used with code pages that do not support graphic characters and to send output to printers that do not properly interpret graphic characters.


Graphviz - from the web page:

The Graphviz layout programs take descriptions of graphs in a simple text language, and make diagrams in several useful formats such as images and SVG for web pages, Postscript for inclusion in PDF or other documents; or display in an interactive graph browser. (Graphviz also supports GXL, an XML dialect.)

It's the simplest and most productive tool I've found to create a variety of boxes-and-lines diagrams. I have and use Visio and OmniGraffle, but there's always the temptation to make "just one more adjustment".

It's also quite easy to write code to produce the "dot file" format that Graphiz consumes, so automated diagram production is also nicely within reach.


As promised, here is my Cairo version. I scripted it with Lua, using lfs to walk the directories. I love these little challenges, as they allow me to explore APIs I wanted to dig for quite some time...
lfs and LuaCairo are both cross-platform, so it should work on other systems (tested on French WinXP Pro SP3).

I made a first version drawing file names as I walked the tree. Advantage: no memory overhead. Inconvenience: I have to specify the image size beforehand, so listings are likely to be cut off.

So I made this version, first walking the directory tree, storing it in a Lua table. Then, knowing the number of files, creating the canvas to fit (at least vertically) and drawing the names.
You can easily switch between PNG rendering and SVG one. Problem with the latter: Cairo generates it at low level, drawing the letters instead of using SVG's text capability. Well, at least, it guarantees accurate rending even on systems without the font. But the files are bigger... Not really a problem if you compress it after, to have a .svgz file.
Or it shouldn't be too hard to generate the SVG directly, I used Lua to generate SVG in the past.

-- LuaFileSystem <http://www.keplerproject.org/luafilesystem/>require"lfs"-- LuaCairo <http://www.dynaset.org/dogusanh/>require"lcairo"local CAIRO = cairolocal PI = math.pilocal 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 slashfunction 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 dirListingend--dofile[[../Lua/DumpObject.lua]] -- My own dump routinelocal dirListing = ListDirectory(dirToList)--~ print("\n" .. DumpObject(dirListing))print("Found " .. fileNb .. " files")--~ os.exit()-- Constants to change to adjust aspectlocal initialOffsetX = 20local offsetY = 50local offsetIncrementX = 20local offsetIncrementY = 12local iconOffset = 10local width = 800 -- Still arbitrarylocal titleHeight = width/50local height = offsetIncrementY * (fileNb + 1) + titleHeightlocal outfile = "CairoDirTree." .. outputTypelocal ctxSurfaceif outputType == 'svg' then  ctxSurface = cairo.SvgSurface(outfile, width, height)else  ctxSurface = cairo.ImageSurface(CAIRO.FORMAT_RGB24, width, height)endlocal ctx = cairo.Context(ctxSurface)-- Display a file name-- file is the file name to display-- offsetX is the indentationfunction 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 + offsetIncrementYend-- Erase background (white)ctx:set_source_rgb(1.0, 1.0, 1.0)ctx:paint()--~ ctx:set_line_width(0.01)-- Draw in dark bluectx: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 titlectx:show_text("Directory tree of " .. dirToList)-- Select font for file namesctx:select_font_face("Sans", CAIRO.FONT_SLANT_NORMAL, CAIRO.FONT_WEIGHT_NORMAL)ctx:set_font_size(10)offsetY = titleHeight * 2-- Do the jobfunction 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  endendDisplayDirectory(dirListing, initialOffsetX)if outputType == 'svg' then    cairo.show_page(ctx)else  --cairo.surface_write_to_png(ctxSurface, outfile)  ctxSurface:write_to_png(outfile)endctx:destroy()ctxSurface:destroy()print("Found " .. fileNb .. " files")

Of course, you can change the styles. I didn't draw the connection lines, I didn't saw it as necessary. I might add them optionally later.