44
55# built-in
66from io import StringIO
7+ import mimetypes
78from pathlib import Path
89from typing import Iterable , cast
910
1011# third-party
12+ from svgen .element .html import div
1113from vcorelib .io .file_writer import IndentedFileWriter
1214from vcorelib .math .time import byte_count_str
1315from vcorelib .paths import rel
1719DIR_FILE = "dir.html"
1820
1921
22+ def file_preview (path : Path , link : Path ) -> str :
23+ """Get possible preview text for a file."""
24+
25+ preview = ""
26+
27+ if path .is_file ():
28+ mime , _ = mimetypes .guess_type (path , strict = False )
29+ if mime and mime .startswith ("image" ):
30+ preview = div (tag = "img" , src = f"/{ link } " , alt = str (link )).encode_str (
31+ newlines = False
32+ )
33+
34+ return preview
35+
36+
37+ def write_markdown_dir (
38+ writer : IndentedFileWriter , path : Path , base : Path
39+ ) -> None :
40+ """Write markdown contents for a single directory."""
41+
42+ curr_dir = rel (path , base = base )
43+
44+ line = f"### `{ base .name } /{ curr_dir } `"
45+
46+ # Link to go up a directory.
47+ if curr_dir != Path ():
48+ line += f" ([..](/{ curr_dir .parent } /{ DIR_FILE } ))"
49+
50+ writer .write (line )
51+ writer .empty ()
52+
53+ writer .write ("| name | size | preview |" )
54+ writer .write ("|------|------|---------|" )
55+
56+ for item in sorted (path .iterdir ()):
57+ curr = rel (item , base = base )
58+
59+ name = f"`{ curr .name } `"
60+ if item .is_dir ():
61+ name = f"**{ name } **"
62+
63+ stats = _stats (item )
64+ assert stats
65+ size_str = byte_count_str (stats .st_size ) if item .is_file () else ""
66+
67+ writer .write (
68+ f"| [{ name } ](/{ curr } ) | { size_str } | { file_preview (item , curr )} |"
69+ )
70+
71+ writer .empty ()
72+
73+
2074def markdown_for_dir (
2175 paths_bases : Iterable [tuple [Path , Path ]],
2276 extra_links : dict [str , Iterable [str ]] = None ,
@@ -40,31 +94,7 @@ def markdown_for_dir(
4094 writer .empty ()
4195
4296 for path , base in paths_bases :
43- curr_dir = rel (path , base = base )
44- writer .write (f"### `{ base .name } /{ curr_dir } `" )
45- writer .empty ()
46-
47- # Link to go up a directory.
48- if curr_dir != Path ():
49- writer .write (f"* [..](/{ curr_dir .parent } /{ DIR_FILE } )" )
50-
51- writer .write ("| name | size |" )
52- writer .write ("|------|------|" )
53- for item in sorted (path .iterdir ()):
54- curr = rel (item , base = base )
55-
56- name = f"`{ curr .name } `"
57- if item .is_dir ():
58- name = f"**{ name } **"
59-
60- stats = _stats (item )
61- assert stats
62- size_str = (
63- byte_count_str (stats .st_size ) if item .is_file () else ""
64- )
65- writer .write (f"| [{ name } ](/{ curr } ) | { size_str } |" )
66-
67- writer .empty ()
97+ write_markdown_dir (writer , path , base )
6898
6999 result : str = cast (StringIO , writer .stream ).getvalue ()
70100
0 commit comments