diff --git a/AstConv/HtmlStruct.fs b/AstConv/HtmlStruct.fs index e5ad8e4..09280af 100644 --- a/AstConv/HtmlStruct.fs +++ b/AstConv/HtmlStruct.fs @@ -995,103 +995,101 @@ open System.IO }}""" end - //type VolumeGraphMake(gname: string, story_volume_set: Present.PageAccess list) = - // class - // member private this.node_collect(objs: AstImport.AstObject list) = - // match objs with - // | [] -> [] - // | _ -> - // match objs.Head with - // | :? AstImport.StoryDef as story -> - // let list = this.node_collect(story.children()) - // (list|> List.map(fun (_, b, c) -> Some(story :> AstImport.AstObject), b, c))@this.node_collect(objs.Tail) - // | :? AstImport.SliceDef as slice -> - // let list = this.node_collect(slice.children()) - // (list|> List.map(fun (_, _, c) -> None, Some(slice :> AstImport.AstObject), c))@this.node_collect(objs.Tail) - // | :? AstImport.VolumeDef as volume -> - // let list = this.node_collect(volume.children()) - // (list|> List.map(fun (_, b, c) -> Some(volume), b, c))@this.node_collect(objs.Tail) - // | :? AstImport.ArticleDef as article -> - // let list = this.node_collect(article.children()) - // (list|> List.map(fun (_, _, c) -> None, Some(article), c))@this.node_collect(objs.Tail) - // | :? AstImport.PointDef as point -> - // (None, None, point :> AstImport.AstObject)::this.node_collect(objs.Tail) - // | :? AstImport.PointRef as refer -> - // (None, None, refer)::this.node_collect(objs.Tail) - // | _ -> this.node_collect(objs.Tail) + type VolumeGraphMake(gname: string, story_volume_set: Present.PageAccess list) = + class + member private this.nodedefs_collect(objs: AstImport.AstObject list) = + match objs with + | [] -> [] + | _ -> + match objs.Head with + | :? AstImport.StoryDef as story -> + let list_a = this.nodedefs_collect(story.children()) + (list_a|> List.map(fun (_, b) -> Some(objs.Head), b))@this.nodedefs_collect(objs.Tail) - // member this.getGraphCode(): string = - // let storys = story_volume_set - // |> List.filter(fun dt -> dt :? Present.StoryPage) - // |> List.map(fun d -> d :?> Present.StoryPage) - // |> List.map(fun d -> d :> Present.IDomUnit) - // |> List.map(fun d -> d.object()) - // let volumes= story_volume_set - // |> List.filter(fun dt -> dt :? Present.VolumePage) - // |> List.map(fun dt -> dt :?> Present.VolumePage) - // |> List.map(fun d -> d :> Present.IDomUnit) - // |> List.map(fun d -> d.object()) + | :? AstImport.FragmentSlice as slice -> + (None, objs.Head)::this.nodedefs_collect(objs.Tail) - // let rec point_code_generate(list: AstImport.AstObject list) = - // match list with - // | [] -> [] - // | _ -> - // let item_current = list.Head - // match item_current with - // | :? AstImport.StoryDef as story -> - // let subcluster = point_code_generate(story.children()) - // let clusters_desc = if subcluster.Length > 0 then subcluster|> List.reduce(fun a b -> a + "\n" + b) else "" - // let story_desc = $""" subgraph cluster_{story.address()} {{ label="{story.name()}" {clusters_desc} }} """ - // story_desc::point_code_generate(list.Tail) - // | :? AstImport.SliceDef as slice -> - // let node_exists = point_code_generate(slice.children()) - // let nodes_desc = if node_exists.Length > 0 then node_exists|> List.reduce(fun a b -> a+"\n"+b) else "" - // let slice_desc = $""" subgraph cluster_{slice.address()} {{ label="{slice.name()}" {nodes_desc} }} """ - // slice_desc::point_code_generate(list.Tail) - // | :? AstImport.PointDef as point -> - // let node_desc = $""" node_{point.address()}[label="{point.name()}" shape="rect" style="diagonals"] """ - // node_desc::point_code_generate(list.Tail) - // | :? AstImport.PointRef as refer -> - // let refer_desc = $""" node_{refer.address()}[label="{refer.pointRef()}" style="dotted"] """ - // refer_desc::point_code_generate(list.Tail) - // | :? AstImport.ArticleDef as article -> - // let refer_descx = point_code_generate(article.children()) - // let nodes_desc = if refer_descx.Length > 0 then refer_descx|> List.reduce(fun a b -> a+"\n"+b) else "" - // let article_desc = $""" subgraph cluster_{article.address()} {{ label="{article.name()}" {nodes_desc} }} """ - // article_desc::point_code_generate(list.Tail) - // | :? AstImport.VolumeDef as volume -> - // let subclusters = point_code_generate(volume.children()) - // let clusters_desc = if subclusters.Length > 0 then subclusters|> List.reduce(fun a b -> a + "\n" + b) else "" - // let volume_desc = $""" subgraph cluster_{volume.address()} {{ label="{volume.name()}" {clusters_desc} }} """ - // volume_desc::point_code_generate(list.Tail) - // | _ -> point_code_generate(list.Tail) - - // let clusters_desc = (point_code_generate(storys)@point_code_generate(volumes))|> List.reduce(fun a b -> a + "\n" + b) + | :? AstImport.VolumeDef as volume -> + let list_a = this.nodedefs_collect(volume.children()) + (list_a|> List.map(fun (_, b)-> Some(objs.Head), b))@this.nodedefs_collect(objs.Tail) + + | :? AstImport.ArticleDef as article -> + (None, objs.Head)::this.nodedefs_collect(objs.Tail) + + | _ -> this.nodedefs_collect(objs.Tail) + + member this.getGraphCode(): string = + let storys = story_volume_set + |> List.filter(fun dt -> dt :? Present.StoryPage) + |> List.map(fun d -> d :?> Present.StoryPage) + |> List.map(fun d -> d :> Present.IDomUnit) + |> List.map(fun d -> d.object()) + let volumes= story_volume_set + |> List.filter(fun dt -> dt :? Present.VolumePage) + |> List.map(fun dt -> dt :?> Present.VolumePage) + |> List.map(fun d -> d :> Present.IDomUnit) + |> List.map(fun d -> d.object()) + + // 生成所有cluster + let rec point_code_generate(list: AstImport.AstObject list) = + match list with + | [] -> [] + | _ -> + let item_current = list.Head + match item_current with + | :? AstImport.StoryDef as story -> + let sub_content = point_code_generate(story.children()) + let content_desc = if sub_content.Length > 0 then sub_content|> List.reduce(fun a b -> a + b) else "" + let story_desc = $"""subgraph cluster_{story.address()} {{ label="{story.name()}" {content_desc} }} + """ + story_desc::point_code_generate(list.Tail) + + | :? AstImport.FragmentSlice as slice -> + let slice_desc = $"""node_{slice.address()}[label="{slice.name()}" shape="rect"] + """ + slice_desc::point_code_generate(list.Tail) + + | :? AstImport.VolumeDef as volume -> + let sub_content = point_code_generate(volume.children()) + let content_desc = if sub_content.Length > 0 then sub_content|> List.reduce(fun a b -> a + b) else "" + let volume_desc = $""" subgraph cluster_{volume.address()} {{ label="{volume.name()}" {content_desc} }} + """ + volume_desc::point_code_generate(list.Tail) + + | :? AstImport.ArticleDef as article -> + let article_desc = $"""node_{article.address()}[label="{article.name()}"] + """ + article_desc::point_code_generate(list.Tail) + + | _ -> point_code_generate(list.Tail) + let clusters_desc = (point_code_generate(storys)@point_code_generate(volumes))|> List.reduce(fun a b -> a + b) - // let points_about = this.node_collect(storys @ volumes) - // let point_map = points_about|> List.filter(fun (_, _, d) -> d :? AstImport.PointDef) - // |> List.map(fun (a, b, c) -> - // let story_def = a.Value :?> AstImport.StoryDef - // let slice_def = b.Value :?> AstImport.SliceDef - // $"{story_def.name()}&{slice_def.name()}&{(c :?> AstImport.PointDef).name()}", c.address() - // ) - // let rec refers_link_assemble(nodes: (string*string)list) = - // match nodes with - // | [] -> [] - // | _ -> - // let node_sig, address = nodes.Head - // let referx = points_about|> List.filter(fun (_, _, n) -> n :? AstImport.PointRef) - // |> List.map(fun (_, _, c) -> c :?> AstImport.PointRef) - // |> List.filter(fun n -> - // let sig_ref = $"{n.storyRef()}&{n.sliceRef()}&{n.pointRef()}" - // sig_ref = node_sig - // ) - // let code_curr = referx |> List.map(fun x-> $"node_{x.address()}--node_{address}") - // code_curr@refers_link_assemble(nodes.Tail) + // 提取所有可视节点 + let child_nodes = this.nodedefs_collect(storys)@this.nodedefs_collect(volumes) + // 获取节点字典 + let node_map = child_nodes|> List.filter(fun (_, b) -> b:? AstImport.FragmentSlice) + |> List.map(fun (a, b) -> + let story_e = a.Value :?> AstImport.StoryDef + let fragm_e = b :?> AstImport.FragmentSlice + $"{story_e.name()}&{fragm_e.name()}", b.address()) - // let temps = refers_link_assemble(point_map) - // let refer_arrows = refers_link_assemble(point_map)|> List.reduce(fun a b -> a + "\n" + b) + let rst = child_nodes |> List.filter(fun (_, b) -> b:? AstImport.ArticleDef) // 筛选文章节点 + |> List.map(fun (_, b) -> b:?> AstImport.ArticleDef) // 获取文章节点 + |> List.map(fun v -> v, (v.children()|> List.filter(fun v-> v:? AstImport.FragmentRef))) // 获取文章节点和他的引用线 + |> List.filter(fun (_, al)-> al.Length > 0) - // $"""graph{{ label="{gname}" {clusters_desc} {refer_arrows} }}""" + let refers = rst|> List.map(fun (a, refsa) -> + refsa|> List.map(fun refn -> + let refx = refn :?> AstImport.FragmentRef + let target_name = $"""{refx.storyRef()}&{refx.sliceRef()}""" + let _, target_address = node_map|> List.filter(fun (a, _) -> a = target_name)|> List.item 0 + $"""node_{a.address()}--node_{target_address} + """ + ) + ) + |> List.reduce (fun a b -> a @ b) + |> List.reduce (fun a b -> a + b) - // end \ No newline at end of file + $"""graph{{ label="{gname}" {clusters_desc} {refers} }}""" + + end \ No newline at end of file diff --git a/AstConv/Program.fs b/AstConv/Program.fs index d39c293..638faa8 100644 --- a/AstConv/Program.fs +++ b/AstConv/Program.fs @@ -71,9 +71,9 @@ stream.Write(graph_code) stream.Flush() Process.Start("dot", $"""-Tsvg -o{Path.Combine(dir_o.FullName, "storys_display.svg")} {Path.Combine(dir_o.FullName, "storys_display.dot")}""") |> ignore -//let graph2 = VolumeGraphMake("卷章引用网络", (volume_pages@story_pages)|> List.map(fun d -> d :?> PageAccess)) -//let graph2_code = graph2.getGraphCode() -//let stream2 = new StreamWriter(Path.Combine(dir_o.FullName, "volume_display.dot"), false) -//stream2.Write(graph2_code) -//stream2.Flush() -//Process.Start("dot", $"""-Tsvg -o{Path.Combine(dir_o.FullName, "volume_display.svg")} {Path.Combine(dir_o.FullName, "volume_display.dot")}""") |> ignore +let graph2 = VolumeGraphMake("卷章引用网络", (volume_pages@story_pages)|> List.map(fun d -> d :?> PageAccess)) +let graph2_code = graph2.getGraphCode() +let stream2 = new StreamWriter(Path.Combine(dir_o.FullName, "volume_display.dot"), false) +stream2.Write(graph2_code) +stream2.Flush() +Process.Start("dot", $"""-Tsvg -o{Path.Combine(dir_o.FullName, "volume_display.svg")} {Path.Combine(dir_o.FullName, "volume_display.dot")}""") |> ignore