Index: /trunk/cli/dune
===================================================================
--- /trunk/cli/dune	(revision 5)
+++ /trunk/cli/dune	(revision 6)
@@ -2,4 +2,4 @@
  (name txt)
  (public_name txt)
- (modules txt authors convert conversion file index last listing new topics html atom gemini pull)
+ (modules txt authors convert conversion file index last listing new topics html atom gemini publish pull)
  (libraries text_parse.converter text_parse.parsers logarion msgpck curl str cmdliner))
Index: /trunk/cli/file.ml
===================================================================
--- /trunk/cli/file.ml	(revision 5)
+++ /trunk/cli/file.ml	(revision 6)
@@ -1,10 +1,5 @@
-let split_filetypes files =
-	let acc (dirs, files) x = if Sys.is_directory x
-		then (x::dirs, files) else (dirs, x::files) in
-	List.fold_left acc ([],[]) files
-
 open Logarion
 let file files =
-	let dirs, files = split_filetypes files in
+	let dirs, files = File_store.split_filetypes files in
 	let _link_as_named dir file = Unix.link file (Filename.concat dir file) in
 	let link_with_id dir file =
@@ -15,5 +10,5 @@
 
 let unfile files =
-	let dirs, files = split_filetypes files in
+	let dirs, files = File_store.split_filetypes files in
 	let unlink dir file = try Unix.unlink (Filename.concat dir file)
 		with Unix.(Unix_error(ENOENT,_,_))-> () in
Index: /trunk/cli/publish.ml
===================================================================
--- /trunk/cli/publish.ml	(revision 6)
+++ /trunk/cli/publish.ml	(revision 6)
@@ -0,0 +1,30 @@
+let targets () =
+	let home =
+		try Sys.getenv "txtpubdir" with Not_found ->
+		try Sys.getenv "HOME" with Not_found -> ""
+	in
+	List.filter
+		(fun x -> try Sys.is_directory (snd x) with Sys_error _ -> false)
+		[
+			"htm", home ^ "/public/html";
+			"gmi", home ^ "/public/gemini";
+			"", home ^ "/public/gopher";
+		]
+
+open Logarion
+let publish ids =
+	let predicate t = List.mem t.Text.id ids in
+	let targets = targets () in
+	let pub_dirs = List.map (fun x -> snd x) targets in
+	try File_store.iter ~predicate (fun (_t, p) -> File.file ((List.hd p)::pub_dirs))
+	with Unix.Unix_error (Unix.EEXIST, _, _) -> ();
+	List.iter (fun t ->
+		Index.((load (snd t)) false None None None None);
+		Convert.convert_dir (fst t) false (snd t))
+		targets
+
+open Cmdliner
+let term =
+	let ids = Arg.(value & pos_all string [] & info [] ~docv:"text ids") in
+	let doc = "convert texts into standart public dirs public_{html,gemini,gopher} if they exists" in
+	Term.(const publish $ ids), Term.info "publish" ~doc ~man:[ `S "DESCRIPTION"; `P doc ]
Index: /trunk/cli/txt.ml
===================================================================
--- /trunk/cli/txt.ml	(revision 5)
+++ /trunk/cli/txt.ml	(revision 6)
@@ -15,4 +15,5 @@
 	Listing.term;
 	New.term;
+	Publish.term;
 	Pull.term;
 	Topics.term;
Index: /trunk/lib/file_store.ml
===================================================================
--- /trunk/lib/file_store.ml	(revision 5)
+++ /trunk/lib/file_store.ml	(revision 6)
@@ -4,5 +4,10 @@
 
 let extension = ".txt"
-let def_dir = try Sys.getenv "LOGARION_DIR" with Not_found -> "."
+let def_dir () =
+	let share = Sys.getenv "HOME" ^ "/.local/share/texts/" in
+	try Sys.getenv "txtdir" with Not_found ->
+		match Sys.is_directory share with
+		| true -> share
+		| false | exception (Sys_error _) -> "."
 
 let to_string f =
@@ -50,4 +55,9 @@
 		) else it
 
+let split_filetypes files =
+	let acc (dirs, files) x = if Sys.is_directory x
+		then (x::dirs, files) else (dirs, x::files) in
+	List.fold_left acc ([],[]) files
+
 (* Compare file system nodes to skip reparsing? *)
 let list_fs ?(r=false) dir =
@@ -73,5 +83,5 @@
 	@@ List.fold_left (fold_valid_text predicate) new_iteration flist
 
-let iter ?(r=false) ?(dir=def_dir) ?(predicate=fun _ -> true) ?order ?number fn =
+let iter ?(r=false) ?(dir=def_dir ()) ?(predicate=fun _ -> true) ?order ?number fn =
 	let flist = list_fs ~r dir in match order with
 	| Some comp -> List.iter fn @@ fold_sort_take ~predicate ~number comp flist
@@ -79,5 +89,5 @@
 		List.fold_left (fold_valid_text predicate) new_iteration flist
 
-let fold ?(r=false) ?(dir=def_dir) ?(predicate=fun _ -> true) ?order ?number fn acc =
+let fold ?(r=false) ?(dir=def_dir ()) ?(predicate=fun _ -> true) ?order ?number fn acc =
 	let flist = list_fs ~r dir in match order with
 	| Some comp -> List.fold_left fn acc @@ fold_sort_take ~predicate ~number comp flist
@@ -85,5 +95,5 @@
 		List.fold_left (fold_valid_text predicate) new_iteration flist
 
-let with_id ?(r=false) ?(dir=def_dir) id =
+let with_id ?(r=false) ?(dir=def_dir ()) id =
 	let matched acc path =
 		match to_text path with
@@ -126,5 +136,5 @@
 	if Sys.file_exists candidate then Error "Name clash, try again" else Ok candidate
 
-let with_text ?(dir=def_dir) new_text =
+let with_text ?(dir=def_dir ()) new_text =
 	match id_filename dir extension new_text with
 	| Error _ as e -> e
