update
This commit is contained in:
parent
d66e481b6c
commit
a1f651ca61
|
@ -28,11 +28,11 @@ open System.IO
|
|||
class
|
||||
let mutable root: string = ""
|
||||
member this.pageURL(): string = $"{root}{name}.html"
|
||||
member this.setPageRoot(path: string) =
|
||||
if path.EndsWith "/" then
|
||||
root <- path
|
||||
member this.setPageRoot(path: Uri) =
|
||||
if path.AbsolutePath.EndsWith "/" then
|
||||
root <- path.AbsolutePath
|
||||
else
|
||||
root <- path+"/"
|
||||
root <- path.AbsolutePath + "/"
|
||||
end
|
||||
|
||||
/// 内容定义元素 =================================================================================
|
||||
|
@ -759,4 +759,449 @@ open System.IO
|
|||
doc.WriteTo(writer)
|
||||
writer.Flush()
|
||||
out.ToString()
|
||||
end
|
||||
|
||||
type IndexPage(name: string, childs: Present.IDomUnit list) =
|
||||
class
|
||||
inherit Present.PageAccess("index")
|
||||
new(name) = IndexPage(name, [])
|
||||
|
||||
member this.append(arg: Present.IDomUnit list) =
|
||||
IndexPage(name, childs @ arg)
|
||||
|
||||
interface Present.IDomUnit with
|
||||
member this.name(): string = name
|
||||
member this.object(): AstImport.AstObject =
|
||||
raise (System.NotImplementedException())
|
||||
|
||||
interface PageText with
|
||||
member this.bindPage(): obj = this
|
||||
member this.getHtmlText(): string =
|
||||
let doc = XmlDocument()
|
||||
|
||||
let doc_type = doc.CreateDocumentType("html", null, null, null)
|
||||
doc.AppendChild(doc_type) |> ignore
|
||||
|
||||
let html = doc.CreateElement("html")
|
||||
let head = doc.CreateElement("head")
|
||||
let charset = doc.CreateElement("meta")
|
||||
charset.SetAttribute("charset", "UTF-8")
|
||||
head.AppendChild(charset) |> ignore
|
||||
|
||||
let refresh = doc.CreateElement("meta")
|
||||
refresh.SetAttribute("http-equiv", "refresh")
|
||||
refresh.SetAttribute("content", "5")
|
||||
head.AppendChild(refresh) |> ignore
|
||||
|
||||
let title = doc.CreateElement("title")
|
||||
title.AppendChild(doc.CreateTextNode(name)) |> ignore
|
||||
head.AppendChild(title) |> ignore
|
||||
|
||||
let style = doc.CreateElement("style")
|
||||
style.AppendChild(doc.CreateTextNode("""body{
|
||||
background-color:lightgray;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-left:300px;
|
||||
margin-top: 50px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
div.outline {
|
||||
max-width:90%;
|
||||
#outline:green dotted thick;
|
||||
margin:auto;
|
||||
display:flex;
|
||||
background-color:#f0f0f0;
|
||||
}
|
||||
div#left-nav{
|
||||
min-width:30%;
|
||||
max-width:30%;
|
||||
|
||||
# border:1px solid red;
|
||||
# outline:green dotted thick;
|
||||
overflow:clip;
|
||||
padding:20px;
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
#e0e0e0 0%,
|
||||
#ffffff 100%
|
||||
);
|
||||
}
|
||||
div#left-nav p {
|
||||
word-wrap:break-word;
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
div.content {
|
||||
padding: 5px;
|
||||
padding-left: 20px;
|
||||
max-width: 90%;
|
||||
outline: #e0e0e0 solid 1px;
|
||||
box-shadow: 2px 2px 2px gray;
|
||||
}
|
||||
.content p {
|
||||
word-wrap:break-word;
|
||||
}
|
||||
""")) |> ignore
|
||||
head.AppendChild(style) |> ignore
|
||||
|
||||
html.AppendChild(head) |> ignore
|
||||
doc.AppendChild(html) |> ignore
|
||||
|
||||
let body = doc.CreateElement("body")
|
||||
html.AppendChild(body) |> ignore
|
||||
|
||||
let h1 = doc.CreateElement("h1")
|
||||
h1.AppendChild(doc.CreateTextNode(name)) |> ignore
|
||||
body.AppendChild(h1) |> ignore
|
||||
|
||||
let div_outline = doc.CreateElement("div")
|
||||
div_outline.SetAttribute("class", "outline")
|
||||
body.AppendChild(div_outline) |> ignore
|
||||
|
||||
let div_nav = doc.CreateElement("div")
|
||||
div_nav.SetAttribute("id", "left-nav")
|
||||
div_outline.AppendChild(div_nav) |> ignore
|
||||
this.initNavigate(div_nav) |> ignore
|
||||
|
||||
let div_content = doc.CreateElement("div")
|
||||
div_content.SetAttribute("id", "content")
|
||||
div_content.SetAttribute("class", "content")
|
||||
div_outline.AppendChild(div_content) |> ignore
|
||||
this.contentAppend(div_content, childs)
|
||||
|
||||
let out = new StringWriter()
|
||||
let writer = new XmlTextWriter(out)
|
||||
writer.Formatting = Formatting.Indented |> ignore
|
||||
doc.WriteTo(writer)
|
||||
writer.Flush()
|
||||
out.ToString()
|
||||
|
||||
member this.initNavigate(nav: XmlElement): unit =
|
||||
let vdoc = nav.OwnerDocument
|
||||
let p1 = vdoc.CreateElement("p")
|
||||
let a1 = vdoc.CreateElement("a")
|
||||
a1.SetAttribute("href", "#volume");
|
||||
a1.AppendChild(vdoc.CreateTextNode("卷宗组织")) |> ignore
|
||||
p1.AppendChild(a1) |> ignore
|
||||
nav.AppendChild(p1) |> ignore
|
||||
|
||||
let p2 = vdoc.CreateElement("p")
|
||||
let a2 = vdoc.CreateElement("a")
|
||||
a2.SetAttribute("href", "#story");
|
||||
a2.AppendChild(vdoc.CreateTextNode("故事脉络")) |> ignore
|
||||
p2.AppendChild(a2) |> ignore
|
||||
nav.AppendChild(p2) |> ignore
|
||||
|
||||
let p4 = vdoc.CreateElement("p")
|
||||
let a4 = vdoc.CreateElement("a")
|
||||
a4.SetAttribute("href", "#story-graph");
|
||||
a4.AppendChild(vdoc.CreateTextNode("脉络图示")) |> ignore
|
||||
p4.AppendChild(a4) |> ignore
|
||||
nav.AppendChild(p4) |> ignore
|
||||
|
||||
let p3 = vdoc.CreateElement("p")
|
||||
let a3 = vdoc.CreateElement("a")
|
||||
a3.SetAttribute("href", "#volume-graph");
|
||||
a3.AppendChild(vdoc.CreateTextNode("卷宗图示")) |> ignore
|
||||
p3.AppendChild(a3) |> ignore
|
||||
nav.AppendChild(p3) |> ignore
|
||||
|
||||
member this.contentAppend(content: XmlElement, childs: Present.IDomUnit list): unit =
|
||||
let vdoc = content.OwnerDocument
|
||||
// volume汇总
|
||||
let div_volume = vdoc.CreateElement("div")
|
||||
div_volume.SetAttribute("data-type", "volume")
|
||||
div_volume.SetAttribute("class", "content")
|
||||
let volume_title = vdoc.CreateElement("h3")
|
||||
volume_title.SetAttribute("id", "volume")
|
||||
volume_title.AppendChild(vdoc.CreateTextNode("卷宗组织")) |> ignore
|
||||
div_volume.AppendChild(volume_title) |> ignore
|
||||
content.AppendChild(div_volume) |> ignore
|
||||
for p in childs do
|
||||
match p with
|
||||
| :? Present.VolumePage ->
|
||||
let div_page = vdoc.CreateElement("div")
|
||||
let page_a = vdoc.CreateElement("a")
|
||||
let page_bind = p :?> Present.PageAccess
|
||||
page_a.SetAttribute("href", page_bind.pageURL())
|
||||
page_a.AppendChild(vdoc.CreateTextNode(p.name())) |> ignore
|
||||
div_page.AppendChild(page_a) |> ignore
|
||||
div_volume.AppendChild(div_page) |> ignore
|
||||
| _ -> ()
|
||||
|
||||
// story汇总
|
||||
let div_story = vdoc.CreateElement("div")
|
||||
div_story.SetAttribute("data-type", "story")
|
||||
div_story.SetAttribute("class", "content")
|
||||
let story_title = vdoc.CreateElement("h3")
|
||||
story_title.SetAttribute("id", "story")
|
||||
story_title.AppendChild(vdoc.CreateTextNode("故事脉络")) |> ignore
|
||||
div_story.AppendChild(story_title) |> ignore
|
||||
content.AppendChild(div_story) |> ignore
|
||||
for p in childs do
|
||||
match p with
|
||||
| :? Present.StoryPage ->
|
||||
let div_page = vdoc.CreateElement("div")
|
||||
let page_a = vdoc.CreateElement("a")
|
||||
let page_bind = p :?> Present.PageAccess
|
||||
page_a.SetAttribute("href", page_bind.pageURL())
|
||||
page_a.AppendChild(vdoc.CreateTextNode(p.name())) |> ignore
|
||||
div_page.AppendChild(page_a) |> ignore
|
||||
div_story.AppendChild(div_page) |> ignore
|
||||
| _ -> ()
|
||||
|
||||
// storylines 网络图
|
||||
let div_story_svg = vdoc.CreateElement("div")
|
||||
div_story_svg.SetAttribute("data-type", "story_svg")
|
||||
div_story_svg.SetAttribute("id", "story-graph")
|
||||
let story_h3 = vdoc.CreateElement("h3")
|
||||
story_h3.AppendChild(vdoc.CreateTextNode("脉络图示")) |> ignore
|
||||
div_story_svg.AppendChild(story_h3) |> ignore
|
||||
let image = vdoc.CreateElement("img")
|
||||
image.SetAttribute("src", "./storys_display.svg")
|
||||
div_story_svg.AppendChild(image) |> ignore
|
||||
content.AppendChild(div_story_svg) |> ignore
|
||||
|
||||
// volumes 引用图
|
||||
let div_volume_svg = vdoc.CreateElement("div")
|
||||
div_volume_svg.SetAttribute("data-type", "volume_svg")
|
||||
div_volume_svg.SetAttribute("id", "volume-graph")
|
||||
let volume_h3 = vdoc.CreateElement("h3")
|
||||
volume_h3.AppendChild(vdoc.CreateTextNode("卷宗图示")) |> ignore
|
||||
div_volume_svg.AppendChild(volume_h3) |> ignore
|
||||
let image2 = vdoc.CreateElement("img")
|
||||
image2.SetAttribute("src", "./volume_display.svg")
|
||||
div_volume_svg.AppendChild(image2) |> ignore
|
||||
content.AppendChild(div_volume_svg) |> ignore
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
type StorylineGraphMake(gname:string, items: Present.PageAccess list) =
|
||||
class
|
||||
let lines = items |> List.filter(fun v-> v :? Present.StoryPage)
|
||||
|> List.map(fun v->v:?>Present.StoryPage)
|
||||
|> List.map(fun s->s :> Present.IDomUnit)
|
||||
|> List.map(fun s->s.object() :?> AstImport.StoryDef)
|
||||
|
||||
member private this.node_collect(objs: AstImport.AstObject list) =
|
||||
match objs with
|
||||
| [] -> []
|
||||
| _ ->
|
||||
match objs.Head with
|
||||
| :? AstImport.StoryDef as story ->
|
||||
let list_a = this.node_collect(story.children())
|
||||
(list_a|> List.map(fun (_, b, c) -> Some(story), b, c))@this.node_collect(objs.Tail)
|
||||
| :? AstImport.SliceDef as slice ->
|
||||
let list_a = this.node_collect(slice.children())
|
||||
(list_a|> List.map(fun (_, _, c) -> None, Some(slice), 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)
|
||||
|
||||
member this.getGraphCode(): string =
|
||||
let node_about = this.node_collect(lines|> List.map(fun d -> d :> AstImport.AstObject))
|
||||
|
||||
// 获取节点字典
|
||||
let node_map = node_about|> List.filter(fun (_, _, c) -> c :? AstImport.PointDef)
|
||||
|> List.map(
|
||||
fun (a, b, c) ->
|
||||
$"{a.Value.name()}&{b.Value.name()}&{(c:?>AstImport.PointDef).name()}", c.address()
|
||||
)
|
||||
|
||||
|
||||
// 节点声明
|
||||
let story_decl = lines |> List.map(fun story ->
|
||||
$"""node_{story.address()}[label="{story.name()}" shape="cds"]""")
|
||||
|> List.reduce(fun a b -> a + "\n" + b)
|
||||
let points_decl = node_about |> List.map(fun (_, _, point) ->
|
||||
match point with
|
||||
| :? AstImport.PointDef as def->
|
||||
$"""node_{point.address()}[label="{def.name()}" shape="rect"]"""
|
||||
| :? AstImport.PointRef as ref ->
|
||||
$"""node_{point.address()}[label="{ref.pointRef()}" style="dotted"]"""
|
||||
| _ -> failwith "mismatch"
|
||||
)
|
||||
|> List.reduce(fun a b -> a + "\n" + b)
|
||||
let nodes_decl = story_decl + points_decl
|
||||
|
||||
|
||||
// 提取所有情节声明
|
||||
let slice_nodes = node_about|> List.map(fun (a, b, _)->a.Value,b.Value)|> List.distinctBy(fun (_, b) -> b.address())
|
||||
let rec get_slice_decl = fun (slices_t: (AstImport.StoryDef*AstImport.SliceDef) list)->
|
||||
match slices_t with
|
||||
| [] -> []
|
||||
| _ ->
|
||||
let story, slice = slices_t.Head
|
||||
let slice_childs = node_about
|
||||
|> List.filter(
|
||||
fun (_, b, _) ->
|
||||
slice.address() = b.Value.address()
|
||||
)
|
||||
|> List.map(fun (_, _, n) -> $"node_{n.address()}")
|
||||
|> List.reduce(fun a b -> $"{a}->{b}")
|
||||
|
||||
let slice_def = $"""subgraph cluster_{slice.address()}{{ label="{story.name()}::{slice.name()}" {slice_childs} }}"""
|
||||
slice_def::get_slice_decl(slices_t.Tail)
|
||||
let slice_relates = get_slice_decl(slice_nodes)|> List.reduce(fun a b -> a + "\n" + b)
|
||||
|
||||
|
||||
// 构建引用指向
|
||||
let refer_nodes = node_about|> List.filter(fun (_, _, n) -> n:? AstImport.PointRef)
|
||||
|> List.map(fun (_, _, n) -> n :?> AstImport.PointRef)
|
||||
let rec get_refer_decl = fun(list_def: (string*string)list) ->
|
||||
match list_def with
|
||||
| [] -> []
|
||||
| _ ->
|
||||
let node_name,node_addr = list_def.Head
|
||||
let refers_about = refer_nodes|> List.filter(fun d -> node_name = $"{d.storyRef()}&{d.sliceRef()}&{d.pointRef()}")
|
||||
match refers_about with
|
||||
| [] -> get_refer_decl(list_def.Tail)
|
||||
| _ ->
|
||||
let refer_arrows = refers_about|> List.map(fun d -> $"node_{d.address()}->node_{node_addr}")
|
||||
|> List.reduce(fun a b -> a + "\n" + b)
|
||||
refer_arrows::get_refer_decl(list_def.Tail)
|
||||
let refer_arrows = get_refer_decl(node_map)|> List.reduce(fun a b -> a + "\n" + b)
|
||||
|
||||
|
||||
// 串联情节
|
||||
let rec slice_combine = fun(items: AstImport.AstObject list) ->
|
||||
match items with
|
||||
| [] -> []
|
||||
| _ ->
|
||||
match items.Head with
|
||||
| :? AstImport.SliceDef as defs ->
|
||||
let points = defs.children()|> List.filter(fun d -> not(d :? AstImport.TextItem))
|
||||
match points with
|
||||
| [] -> []
|
||||
| _ ->
|
||||
(points.Head, points.Item(points.Length-1))::slice_combine(items.Tail)
|
||||
| :? AstImport.StoryDef as defs ->
|
||||
slice_combine(defs.children())
|
||||
| _ -> slice_combine(items.Tail)
|
||||
let story_arrows = lines |> List.map(fun story ->
|
||||
let slice_ends = slice_combine([story])
|
||||
match slice_ends with
|
||||
| [] -> ""
|
||||
| _ ->
|
||||
let arrow_link = slice_ends |> List.map(fun (a,b) -> $"node_{a.address()}&&&&node_{b.address()}")
|
||||
|> List.reduce(fun a b -> $"{a}->{b}")
|
||||
$"""node_{story.address()}->{arrow_link.Replace("&&&&", "\n")}"""
|
||||
)
|
||||
|> List.reduce(fun a b -> a + "\n" + b)
|
||||
|
||||
$"""digraph node_relates{{
|
||||
rankdir=LR
|
||||
label="{gname}"
|
||||
{nodes_decl}
|
||||
{slice_relates}
|
||||
{refer_arrows}
|
||||
{story_arrows}
|
||||
}}"""
|
||||
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)
|
||||
|
||||
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())
|
||||
|
||||
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)
|
||||
|
||||
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 temps = refers_link_assemble(point_map)
|
||||
let refer_arrows = refers_link_assemble(point_map)|> List.reduce(fun a b -> a + "\n" + b)
|
||||
|
||||
$"""graph{{ label="{gname}" {clusters_desc} {refer_arrows} }}"""
|
||||
|
||||
end
|
|
@ -5,13 +5,29 @@ open HtmlStruct.Assemble
|
|||
open HtmlStruct.Content
|
||||
open HtmlStruct.Present
|
||||
open System.IO
|
||||
open System.Text
|
||||
open System
|
||||
open System.Diagnostics
|
||||
|
||||
let args = System.Environment.GetCommandLineArgs()|> Array.toList
|
||||
if args.Length <> 5 then
|
||||
failwith "程序调用参数错误:AstConv.exe -file xast文件路径 -odir 输出文件夹路径"
|
||||
|
||||
let file_in, dir_o = match args.Item(1), args.Item(3) with
|
||||
| "-file","-odir" ->
|
||||
if not(FileInfo(args.Item 2).Exists) then
|
||||
failwith "指定xast文件不存在"
|
||||
if not(DirectoryInfo(args.Item 4).Exists) then
|
||||
failwith "指定输出文件夹不存在"
|
||||
FileInfo(args.Item 2), DirectoryInfo(args.Item 4)
|
||||
| _ -> failwith "程序调用参数错误:AstConv.exe -file xast文件路径 -odir 输出文件夹路径"
|
||||
|
||||
let out_dir = Uri(dir_o.FullName)
|
||||
|
||||
let doc = XmlDocument()
|
||||
doc.Load("E:/storyline.xast")
|
||||
doc.Load(file_in.FullName)
|
||||
|
||||
let prog = Program.GenerateFrom(doc)
|
||||
|
||||
let entry = AstVisitEntry(prog)
|
||||
let visitor = UnitGenerate(prog)
|
||||
entry.visitWith(visitor) |> ignore
|
||||
|
@ -20,7 +36,7 @@ let volume_pages = volume_page_assemble(visitor.contents()) |> List.map<VolumePa
|
|||
let story_pages = story_page_assemble(visitor.contents()) |> List.map<StoryPage, IDomUnit> (fun x->x)
|
||||
let point_pages = point_page_assemble(volume_pages @ story_pages)
|
||||
|
||||
volume_pages @ story_pages @ point_pages |> List.iter (fun it -> (it:?>PageAccess).setPageRoot("E:"))
|
||||
volume_pages @ story_pages @ point_pages |> List.iter (fun it -> (it:?>PageAccess).setPageRoot(out_dir))
|
||||
let makers = volume_pages @ story_pages @ point_pages
|
||||
|> List.map(fun page_unit ->
|
||||
match page_unit with
|
||||
|
@ -33,6 +49,26 @@ let makers = volume_pages @ story_pages @ point_pages
|
|||
| _ -> failwith ""
|
||||
)
|
||||
|
||||
let index_page = IndexPage("汇总页面", volume_pages @ story_pages @ point_pages)
|
||||
index_page.setPageRoot(out_dir)
|
||||
let content = (index_page :> PageText).getHtmlText()
|
||||
let href = index_page.pageURL()
|
||||
File.WriteAllLines(href, [content])
|
||||
for refs in makers do
|
||||
let file_path = (refs.bindPage() :?> PageAccess).pageURL()
|
||||
File.WriteAllLines(file_path, [refs.getHtmlText()])
|
||||
File.WriteAllLines(file_path, [refs.getHtmlText()])
|
||||
|
||||
let graph = StorylineGraphMake("故事线网络", story_pages|> List.map(fun x -> x :?> PageAccess))
|
||||
let graph_code = graph.getGraphCode()
|
||||
|
||||
let stream = new StreamWriter(Path.Combine(dir_o.FullName, "storys_display.dot"), false)
|
||||
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
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"profiles": {
|
||||
"AstConv": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "-file \"E:/storyline.xast\" -odir \"E:/diro\""
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue