diff --git a/AstConv/AstImport.fs b/AstConv/AstImport.fs index 88328fc..0757705 100644 --- a/AstConv/AstImport.fs +++ b/AstConv/AstImport.fs @@ -7,7 +7,8 @@ open System.Linq /// 带有地址的对象 type AstObject() = class - member this.address() = string(this.GetHashCode ()) + abstract member address:unit -> string + default this.address():string = string(this.GetHashCode ()) abstract member members:unit -> AstObject list default this.members(): AstObject list = [] @@ -51,19 +52,17 @@ open System.Linq end /// 引用节点 - type PointRef(bind: XmlElement, texts: TextItem list) = + type FragmentRef(bind: XmlElement, texts: TextItem list) = class inherit AstObject() - new(bind: XmlElement) = PointRef(bind, []) + new(bind: XmlElement) = FragmentRef(bind, []) - member this.pointRef() = - bind.GetAttribute "point" member this.sliceRef() = bind.GetAttribute "slice" member this.storyRef() = bind.GetAttribute "story" member this.appendChild(objs: TextItem list) = - PointRef(bind, texts@objs) + FragmentRef(bind, texts@objs) member this.children() = texts @@ -75,77 +74,35 @@ open System.Linq | null -> [] | _ -> match TextItem.GenerateText(child) with - | Some text -> text::PointRef.GenerateFromChildSibling(child.NextSibling) - | None -> PointRef.GenerateFromChildSibling(child.NextSibling) + | Some text -> text::FragmentRef.GenerateFromChildSibling(child.NextSibling) + | None -> FragmentRef.GenerateFromChildSibling(child.NextSibling) - static member GeneratePointRef(ref_opt: XmlNode): Option = + static member GeneratePointRef(ref_opt: XmlNode): Option = match ref_opt with | :? XmlElement as refo when refo.Name.Equals "refer" -> - let text_objects = PointRef.GenerateFromChildSibling(refo.FirstChild) - Some(PointRef(refo, text_objects)) + let text_objects = FragmentRef.GenerateFromChildSibling(refo.FirstChild) + Some(FragmentRef(refo, text_objects)) | _ -> None end - /// 定义节点 - type PointChildType = |Text of TextItem |Refer of PointRef - type PointDef(bind: XmlElement, objs: AstObject list) = - class - inherit AstObject() - new(bind: XmlElement) = PointDef(bind, []) - - member this.name() = bind.GetAttribute "name" - - member this.appendChild(o: PointChildType) = - match o with - |Text t -> PointDef(bind, objs@[t]) - |Refer r -> PointDef(bind, objs@[r]) - - member this.children() = objs - - override this.members(): AstObject list = objs - - static member GenerateFromChildSibling(child: XmlNode): PointChildType list = - match child with - | null -> [] - | _ -> - let h = match child.Name with - | "text-section" -> Some(Text(TextItem.GenerateText(child).Value)) - | "refer" -> Some(Refer(PointRef.GeneratePointRef(child).Value)) - | _ -> None - match h with - | Some childx -> childx::PointDef.GenerateFromChildSibling(child.NextSibling) - | None -> PointDef.GenerateFromChildSibling(child.NextSibling) - - static member GeneratePointDef(def_opt: XmlNode) : Option = - match def_opt with - | :? XmlElement as defo when defo.Name.Equals "point" -> - let child_objs = PointDef.GenerateFromChildSibling(defo.FirstChild) - let objs = child_objs |> List.map ( - fun o-> match o with - |Refer refs -> refs :> AstObject - |Text text -> text :> AstObject - ) - Some(PointDef(defo, objs)) - | _ -> None - - end - - type SliceChildType = |Text of TextItem |Define of PointDef + type SliceChildType = |Text of TextItem |Ref of FragmentRef /// 情节节点 - type SliceDef(bind: XmlElement, objs: AstObject list) = + type FragmentSlice(bind: XmlElement, objs: AstObject list) = class inherit AstObject() - new(bind: XmlElement) = SliceDef(bind, []) + new(bind: XmlElement) = FragmentSlice(bind, []) member this.name() = bind.GetAttribute "name" member this.appendChild(o: SliceChildType) = match o with - | Text t -> SliceDef(bind, objs@[t]) - | Define d -> SliceDef(bind, objs@[d]) + | Text t -> FragmentSlice(bind, objs@[t]) + | Ref d -> FragmentSlice(bind, objs@[d]) member this.children() = objs override this.members(): AstObject list = objs + override this.address (): string = + bind.GetAttribute "address" static member GenerateFromChildSibling(child: XmlNode): SliceChildType list = match child with @@ -153,27 +110,27 @@ open System.Linq | _ -> let h = match child.Name with | "text-section" -> Some(Text(TextItem.GenerateText(child).Value)) - | "point" -> Some(Define(PointDef.GeneratePointDef(child).Value)) + | "refer" -> Some(Ref(FragmentRef.GeneratePointRef(child).Value)) | _ -> None match h with - | Some value -> value::SliceDef.GenerateFromChildSibling(child.NextSibling) - | _ -> SliceDef.GenerateFromChildSibling(child.NextSibling) + | Some value -> value::FragmentSlice.GenerateFromChildSibling(child.NextSibling) + | _ -> FragmentSlice.GenerateFromChildSibling(child.NextSibling) - static member GenerateSliceDef(slice_opt: XmlNode): Option = + static member GenerateSliceDef(slice_opt: XmlNode): Option = match slice_opt with | :? XmlElement as slice when slice.Name.Equals "slice" -> - let mbrs = SliceDef.GenerateFromChildSibling(slice.FirstChild) + let mbrs = FragmentSlice.GenerateFromChildSibling(slice.FirstChild) let objs = mbrs |> List.map ( fun o-> match o with - |Define defs -> defs :> AstObject + |Ref defs -> defs :> AstObject |Text text -> text :> AstObject ) - Some(SliceDef(slice, objs)) + Some(FragmentSlice(slice, objs)) | _ -> None end - type StoryChildType = |Text of TextItem |Slice of SliceDef + type StoryChildType = |Text of TextItem |Slice of FragmentSlice /// 故事节点 type StoryDef(bind: XmlElement, objs: AstObject list) = class @@ -191,6 +148,8 @@ open System.Linq member this.children() = objs override this.members(): AstObject list = objs + override this.address (): string = + bind.GetAttribute "address" static member GenerateFromChildSibling(child: XmlNode): StoryChildType list = match child with @@ -198,7 +157,7 @@ open System.Linq | _ -> let h = match child.Name with | "text-section" -> Some(Text(TextItem.GenerateText(child).Value)) - | "slice" -> Some(Slice(SliceDef.GenerateSliceDef(child).Value)) + | "slice" -> Some(Slice(FragmentSlice.GenerateSliceDef(child).Value)) | _->None match h with | Some value -> value::StoryDef.GenerateFromChildSibling(child.NextSibling) @@ -218,7 +177,7 @@ open System.Linq | _ -> None end - type ArticleChildType = |Text of TextItem |Refer of PointRef + type ArticleChildType = |Text of TextItem |Refer of FragmentRef /// 章节节点 type ArticleDef(bind: XmlElement, objs: AstObject list) = class @@ -237,6 +196,8 @@ open System.Linq ArticleDef(bind, objs@items) override this.members(): AstObject list = objs + override this.address (): string = + bind.GetAttribute "address" static member GenerateFromChildSibling(child: XmlNode): ArticleChildType list = match child with @@ -244,7 +205,7 @@ open System.Linq | _ -> let data = match child.Name with | "text-section" -> Some(Text(TextItem.GenerateText(child).Value)) - | "refer" -> Some(Refer(PointRef.GeneratePointRef(child).Value)) + | "refer" -> Some(Refer(FragmentRef.GeneratePointRef(child).Value)) | _ -> None match data with | Some value -> value::ArticleDef.GenerateFromChildSibling(child.NextSibling) @@ -281,6 +242,8 @@ open System.Linq VolumeDef(bind, objs@items) override this.members(): AstObject list = objs + override this.address (): string = + bind.GetAttribute "address" static member GenerateFromChildSibling(child: XmlNode): VolumeChildType list = match child with diff --git a/AstConv/HtmlStruct.fs b/AstConv/HtmlStruct.fs index ae8e8d3..b82ffa7 100644 --- a/AstConv/HtmlStruct.fs +++ b/AstConv/HtmlStruct.fs @@ -23,7 +23,7 @@ open System.IO end /// 可访问页面 - type PageAccess(name: string) = + type PageAccess(name: string, dom: IDomUnit option, childs: IDomUnit list) = class let mutable root: string = "" member this.pageURL(): string = $"{root}{name}.html" @@ -32,94 +32,100 @@ open System.IO root <- path.AbsolutePath else root <- path.AbsolutePath + "/" - end - - /// 内容定义元素 ================================================================================= - type Forwards(item: AstImport.AstObject) = - class - let mutable defines_page: Option = None - let mutable assemble_page: Option = None - - member this.elementID(): string = item.address() - /// 节点定义页面,本元素完整URL - member this.definedURL(): string = - match defines_page with - | Some v -> $"{v.pageURL()}#{this.elementID()}" - | None -> failwith "节点元素定义页面配置错误" - member this.setDefines(page: PageAccess) = - defines_page <- Some(page) - - /// 节点汇集页面,本元素完整URL - member this.assembleURL():string = - match assemble_page with - | Some v -> $"{v.pageURL()}#{this.elementID()}" - | None -> failwith "节点元素汇集页面配置错误" - member this.setAssemble(page: PageAccess) = - assemble_page <- Some(page) - end - - /// 回访定义元素 ================================================================================= - type Backwards(bind_item: Forwards, refer_anchor: string) = - class - member this.defsElement() = - bind_item - member this.elementID(): string = - bind_item.elementID() - member this.backwardsLink(): string = - bind_item.definedURL() - member this.referAnchor(): string = refer_anchor - end - - - /// 访问页面:概括页面、卷宗页面、故事线页面、节点汇总 ================================================= - type VolumePage(page_name: string, volume: IDomUnit, childs: IDomUnit list) = - class - inherit PageAccess(page_name) - new(page_name, volume) = VolumePage(page_name, volume, []) + abstract member makeNew:string -> IDomUnit option -> IDomUnit list -> PageAccess + default this.makeNew n d cs : PageAccess = failwith "需要在子类中实现makeNew方法" + interface IDomUnit with - member this.name():string = volume.name() - member this.object() = - volume.object() + member this.name():string = dom.Value.name() + member this.object() = dom.Value.object() interface IContainer with member this.children(): IDomUnit list = childs member this.append(new_list: IDomUnit list): IContainer = - VolumePage(page_name, volume, childs@new_list) + this.makeNew name dom (childs@new_list) :> IContainer end - type StoryPage(page_name: string, story: IDomUnit, childs: IDomUnit list) = + /// 内容定义元素 ================================================================================= + type Forward = + interface + abstract member elementID:unit -> string + abstract member definedURL:unit -> string + abstract member setDefines:PageAccess -> unit + abstract member assembleURL:unit -> string + abstract member setAssemble:PageAccess -> unit + end + + /// 回访定义元素 ================================================================================= + type Backward = + interface + abstract member defsElement:unit -> Forward + abstract member elementID:unit -> string + abstract member backwardsLink:unit -> string + abstract member referAnchor:unit -> string + end + + + type AssembleForward(item: AstImport.AstObject) = class - inherit PageAccess(page_name) + let mutable defines_page: Option = None + let mutable assemble_page: Option = None + + interface Forward with + member this.elementID(): string = item.address() + /// 节点定义页面,本元素完整URL + member this.definedURL(): string = + match defines_page with + | Some v -> $"{v.pageURL()}#{(this:>Forward).elementID()}" + | None -> failwith "节点元素定义页面配置错误" + member this.setDefines(page: PageAccess) = + defines_page <- Some(page) + + /// 节点汇集页面,本元素完整URL + member this.assembleURL():string = + match assemble_page with + | Some v -> $"{v.pageURL()}#{(this:>Forward).elementID()}" + | None -> failwith "节点元素汇集页面配置错误" + member this.setAssemble(page: PageAccess) = + assemble_page <- Some(page) + end + type AssembleBackward(bind_item: Forward, refer_anchor: string) = + class + interface Backward with + member this.defsElement() = bind_item + member this.elementID(): string = bind_item.elementID() + member this.backwardsLink(): string = bind_item.definedURL() + member this.referAnchor(): string = refer_anchor + end + + + /// 访问页面:概括页面、卷宗页面、故事线页面、节点汇总 ================================================= + type VolumePage(page_name: string, volume: IDomUnit option, childs: IDomUnit list) = + class + inherit PageAccess(page_name, volume, childs) + new(page_name, volume) = VolumePage(page_name, volume, []) + + override this.makeNew (n: string) (d: IDomUnit option) (cs: IDomUnit list): PageAccess = + VolumePage(n, d, cs) + end + + type StoryPage(page_name: string, story: IDomUnit option, childs: IDomUnit list) = + class + inherit PageAccess(page_name, story, childs) new(page_name, story) = StoryPage(page_name, story, []) - interface IDomUnit with - member this.name():string = story.name() - member this.object() = - story.object() - - interface IContainer with - member this.children(): IDomUnit list = childs - member this.append(list: IDomUnit list): IContainer = - StoryPage(page_name, story, childs@list) + override this.makeNew (n: string) (d: IDomUnit option) (cs: IDomUnit list): PageAccess = + StoryPage(n, d, cs) end - type PointPage(page_name: string, point: IDomUnit, refer_list: IDomUnit list) = + type SlicePage(page_name: string, point: IDomUnit option, refer_list: IDomUnit list) = class - inherit PageAccess(page_name) - new(page_name, point) = PointPage(page_name, point, []) + inherit PageAccess(page_name, point, refer_list) + new(page_name, point) = SlicePage(page_name, point, []) - member this.defines() = - point - - interface IDomUnit with - member this.name():string = point.name() - member this.object() = point.object() - - interface IContainer with - member this.children(): IDomUnit list = refer_list - member this.append(childs: IDomUnit list): IContainer = - PointPage(page_name, point, refer_list @ childs) + member this.defines() = point + override this.makeNew (n: string) (d: IDomUnit option) (cs: IDomUnit list): PageAccess = + SlicePage(n, d, cs) end @@ -133,11 +139,11 @@ open System.IO end - type PointRefer(refs: AstImport.PointRef, items: Present.IDomUnit list) = + type FragmentRefer(refs: AstImport.FragmentRef, items: Present.IDomUnit list) = class - inherit Present.Forwards(refs) + inherit Present.AssembleForward(refs) - let ref_signature = $"@{refs.storyRef()}&{refs.sliceRef()}&{refs.pointRef()}" + let ref_signature = $"@{refs.storyRef()}&{refs.sliceRef()}" interface Present.IDomUnit with member this.name(): string = ref_signature @@ -148,41 +154,18 @@ open System.IO member this.append(childs: Present.IDomUnit list): Present.IContainer = failwith "append" end - let refer_assemble (refn: AstImport.PointRef) : PointRefer = + let refer_assemble (refn: AstImport.FragmentRef) : FragmentRefer = let texts = refn.children() |> List.map (fun dom -> TextContent(dom) :> Present.IDomUnit) - PointRefer(refn, texts) + FragmentRefer(refn, texts) - type PointDefine(defs: AstImport.PointDef, items: Present.IDomUnit list) = - class - inherit Present.Forwards(defs) - - interface Present.IDomUnit with - member this.name(): string = defs.name() - member this.object() = defs - - interface Present.IContainer with - member this.children(): Present.IDomUnit list = items - member this.append(childs: Present.IDomUnit list): Present.IContainer = - failwith "append" - end - let point_assemble (defs: AstImport.PointDef) : PointDefine = - let objs = defs.children() |> List.map (fun dom -> - match dom with - | :? AstImport.TextItem as t -> TextContent(t) :> Present.IDomUnit - | :? AstImport.PointRef as r -> refer_assemble(r) - | _ -> failwith "match error" - ) - PointDefine(defs, objs) - - /// 具有回退功能的元素 - type AssembleRefer<'T when - 'T :> Present.Forwards and - 'T :> Present.IDomUnit and - 'T:> Present.IContainer>(item: 'T, refer_anchor: string) = + type AssembleRefer<'T when 'T :> Present.Forward + and 'T :> Present.IDomUnit + and 'T :> Present.IContainer + >(item: 'T, refer_anchor: string) = class - inherit Present.Backwards(item, refer_anchor) + inherit Present.AssembleBackward(item, refer_anchor) interface Present.IDomUnit with member this.name() = refer_anchor @@ -195,8 +178,10 @@ open System.IO end - type SliceDefine(defs: AstImport.SliceDef, items: Present.IDomUnit list) = + type FragmentSlice(defs: AstImport.FragmentSlice, items: Present.IDomUnit list) = class + inherit Present.AssembleForward(defs) + interface Present.IDomUnit with member this.name(): string = defs.name() member this.object() = defs @@ -206,15 +191,15 @@ open System.IO member this.append(childs: Present.IDomUnit list): Present.IContainer = failwith "append" end - let slice_assemble (defs: AstImport.SliceDef) : SliceDefine = + let slice_assemble (defs: AstImport.FragmentSlice) : FragmentSlice = let childs = defs.children() |> List.map(fun data -> match data with - | :? AstImport.PointDef as defs -> point_assemble(defs) + | :? AstImport.FragmentRef as defs -> refer_assemble(defs) | :? AstImport.TextItem as text -> TextContent(text) | _ -> failwith "match error" ) - SliceDefine(defs, childs) + FragmentSlice(defs, childs) type StoryDefine(defs: AstImport.StoryDef, childs: Present.IDomUnit list) = @@ -233,7 +218,7 @@ open System.IO let childs = defs.children() |> List.map(fun data -> match data with - | :? AstImport.SliceDef as defs -> slice_assemble(defs) + | :? AstImport.FragmentSlice as defs -> slice_assemble(defs) | :? AstImport.TextItem as text -> TextContent(text) | _ -> failwith "match error" ) @@ -257,7 +242,7 @@ open System.IO |> List.map(fun data -> match data with | :? AstImport.TextItem as text -> TextContent(text) - | :? AstImport.PointRef as refs -> refer_assemble(refs) + | :? AstImport.FragmentRef as refs -> refer_assemble(refs) | _ -> failwith "match error" ) ArticleDefine(defs, childs) @@ -301,12 +286,10 @@ open System.IO let datas = match obj with | :? AstImport.TextItem as text -> result_nodes@[(refs_depth, TextContent(text) :> Present.IDomUnit)] - | :? AstImport.PointRef as refs -> - result_nodes@[(refs_depth, PointRefer(refs, childs))] - | :? AstImport.PointDef as defs -> - result_nodes@[(refs_depth, PointDefine(defs, childs))] - | :? AstImport.SliceDef as defs -> - result_nodes@[(refs_depth, SliceDefine(defs, childs))] + | :? AstImport.FragmentRef as defs -> + result_nodes@[(refs_depth, FragmentRefer(defs, childs))] + | :? AstImport.FragmentSlice as defs -> + result_nodes@[(refs_depth, FragmentSlice(defs, childs))] | :? AstImport.StoryDef as defs -> result_nodes@[(refs_depth, StoryDefine(defs, childs))] | :? AstImport.ArticleDef as defs -> @@ -341,7 +324,7 @@ open System.IO match nodes.Head with | :? Content.VolumeDefine as vole -> let con: Present.IContainer = vole - Present.VolumePage(page_name_encode(vole), vole, con.children())::volume_page_assemble(nodes.Tail) + Present.VolumePage(page_name_encode(vole), Some(vole), con.children())::volume_page_assemble(nodes.Tail) | _ -> volume_page_assemble(nodes.Tail) /// 构建所有故事线页面 @@ -352,143 +335,100 @@ open System.IO match nodes.Head with | :? Content.StoryDefine as storye -> let con: Present.IContainer = storye - Present.StoryPage(page_name_encode(storye), storye, con.children())::story_page_assemble(nodes.Tail) + Present.StoryPage(page_name_encode(storye), Some(storye), con.children())::story_page_assemble(nodes.Tail) | _ -> story_page_assemble(nodes.Tail) - /// 提取point-define和point-refer - let rec private point_peers_extract(nodes: Present.IDomUnit list):(Present.IDomUnit option*Present.IDomUnit option*Present.IDomUnit option)list = + /// 提取fragment-slice + let rec private slice_extract(nodes: Present.IDomUnit list):(Present.IDomUnit option * Present.IDomUnit)list = match nodes with | [] -> [] | _ -> let head_data = nodes.Head match head_data with - | :? Content.StoryDefine as story_e -> - let con = story_e :> Present.IContainer - let items = point_peers_extract(con.children())@point_peers_extract(nodes.Tail) - items |> List.map( - fun (x, y, z)-> - match x with - | None -> (Some(story_e :> Present.IDomUnit), y, z) - | _ -> (x, y, z) - ) | :? Present.StoryPage as story_e -> let con = story_e :> Present.IContainer - let items = point_peers_extract(con.children())@point_peers_extract(nodes.Tail) + let items = slice_extract(con.children())@slice_extract(nodes.Tail) items |> List.map( - fun (x, y, z)-> + fun (x, y)-> match x with - | None -> (Some(story_e :> Present.IDomUnit), y, z) - | _ -> (x, y, z) + | None -> (Some(story_e :> Present.IDomUnit), y) + | _ -> (x, y) ) - - | :? Content.VolumeDefine as volume_e -> - let con = volume_e :> Present.IContainer - let items = point_peers_extract(con.children())@point_peers_extract(nodes.Tail) - items |> List.map ( - fun (x, y, z) -> - match x with - | None -> (Some(volume_e), y, z) - | _ -> (x, y, z) - ) - | :? Present.VolumePage as volume_e -> - let con = volume_e :> Present.IContainer - let items = point_peers_extract(con.children())@point_peers_extract(nodes.Tail) - items |> List.map ( - fun (x, y, z) -> - match x with - | None -> (Some(volume_e), y, z) - | _ -> (x, y, z) - ) - - | :? Content.SliceDefine as slice_e -> - let con = slice_e :> Present.IContainer - let items = point_peers_extract(con.children())@point_peers_extract(nodes.Tail) - items |> List.map( - fun (x, y, z) -> - match y with - | None -> (x, Some(slice_e:> Present.IDomUnit), z) - | _ -> (x, y, z) - ) - - | :? Content.ArticleDefine as article_e -> - let con = article_e :> Present.IContainer - let items = point_peers_extract(con.children())@point_peers_extract(nodes.Tail) - items |> List.map( - fun (x, y, z) -> + | :? Content.FragmentSlice as slice_e -> + (None, slice_e)::slice_extract(nodes.Tail) + | _ -> slice_extract(nodes.Tail) + + /// 提取fragment-refer + let rec private refers_extract(nodes: Present.IDomUnit list):(Present.IDomUnit option * Present.IDomUnit option * Present.IDomUnit) list = + match nodes with + | [] -> [] + | _ -> + let head_node = nodes.Head + match head_node with + | :? Content.FragmentRefer as refer_e -> + (None, None, refer_e)::refers_extract(nodes.Tail) + | :? Content.TextContent -> + refers_extract(nodes.Tail) + | :? Present.PageAccess -> + let s = head_node :?> Present.IContainer + let items = refers_extract(s.children())@refers_extract(nodes.Tail) + items |> List.map(fun (x, y, z)-> + match x with + | None -> (Some(head_node), y, z) + | _ -> (x, y, z) + ) + | :? Present.IContainer as con -> + let rst = refers_extract(con.children())@refers_extract(nodes.Tail) + rst |> List.map(fun (x, y, z) -> match y with - | None -> (x, Some(article_e), z) + | None -> (x, Some(head_node), z) | _ -> (x, y, z) ) - - | :? Content.PointRefer as refer_e -> - let ast_obj = refer_e :> Present.IDomUnit - let refer = ast_obj.object() :?> AstImport.PointRef - (None, None, Some(refer_e :> Present.IDomUnit))::point_peers_extract(nodes.Tail) - | :? Content.PointDefine as define_e -> - let ast_obj = define_e :> Present.IDomUnit - (None, None, Some(define_e))::point_peers_extract(nodes.Tail) - | _ -> point_peers_extract(nodes.Tail) + + | _ -> failwith "refer-extract mismatch" + /// 构建节点汇总页面 /// param nodes volume-pages@story-pages - let rec point_page_assemble(pages: Present.IDomUnit list) = - let checked_list = pages |> List.filter( - fun it -> - match it with - | :? Present.PageAccess -> true - | _ -> false - ) + let rec slice_page_assemble(pages: Present.IDomUnit list) = + let checked_list = pages |> List.filter(fun it -> it :? Present.PageAccess) if checked_list.Length <> pages.Length then failwith "传入的参数pages必须是PageAccess的子类集合" - let points_about= point_peers_extract(pages) + let refers_forward = refers_extract(pages) // 所有的节点关联定义页面 - points_about |> List.iter ( - fun (page, midx, deref) -> - match deref.Value with - | :? Present.Forwards as forwards_elm -> + refers_forward |> List.iter (fun (page, _, deref) -> + match deref with + | :? Present.Forward as forwards_elm -> let page_def = page.Value :?> Present.PageAccess forwards_elm.setDefines(page_def) | _ -> failwith "point_peers_extract结果类型错误" ) - let refer_nodes = points_about |> List.filter( - fun (_, _, n) -> - match n.Value with - | :? Content.PointRefer -> true - | _ -> false - ) - |> List.map( - fun (page_defs, mid_defs, point_refs) -> - let refn = point_refs.Value.object() :?> AstImport.PointRef + let refers_backward = refers_forward |> List.map(fun (page_defs, mid_defs, point_refs) -> + let refn = point_refs.object() :?> AstImport.FragmentRef let refer_name = $"{page_defs.Value.name()}&{mid_defs.Value.name()}@" - let refs = point_refs.Value :?> Content.PointRefer - $"{refn.storyRef()}&{refn.sliceRef()}&{refn.pointRef()}", Content.AssembleRefer(refs, refer_name) + let refs = point_refs :?> Content.FragmentRefer + $"{refn.storyRef()}&{refn.sliceRef()}", Content.AssembleRefer(refs, refer_name) ) + let slices_forward = slice_extract(pages) // 构建节点汇集页面 - let pages = points_about |> List.filter( - fun (_, _, n) -> - match n.Value with - | :? Content.PointDefine -> true - | _ -> false - ) - |> List.map ( - fun (page_defs, slice_defs, point_defs) -> - let defs = point_defs.Value :?> Content.PointDefine - let name_seqs = $"{page_defs.Value.name()}&{slice_defs.Value.name()}&{point_defs.Value.name()}" - let refer_point = Content.AssembleRefer(defs, name_seqs) - let page_assemble = Present.PointPage(page_name_encode(defs), refer_point) - defs.setAssemble(page_assemble) + let slices_backward = slices_forward |> List.map (fun (page_defs, slice_defs) -> + let defs = slice_defs :?> Content.FragmentSlice + let name_seqs = $"{page_defs.Value.name()}&{slice_defs.name()}" + let refer_point = Content.AssembleRefer(defs, name_seqs) + let page_assemble = Present.SlicePage(page_name_encode(defs), Some(refer_point)) + let insf = defs :> Present.Forward + insf.setAssemble(page_assemble) + insf.setDefines(page_defs.Value :?> Present.PageAccess) name_seqs,page_assemble ) - - pages |> List.map( - fun (key, page_one) -> + slices_backward |> List.map(fun (key, page_one) -> let page_old = page_one :> Present.IContainer let page_dom = page_one :> Present.IDomUnit - let nodes = refer_nodes |> List.filter(fun (k, _) -> k = key) - nodes |> List.iter (fun (_, data) -> data.defsElement().setAssemble(page_one)) + let nodes = refers_backward |> List.filter(fun (k, _) -> k = key) + nodes |> List.iter (fun (_, data) -> (data:>Present.Backward).defsElement().setAssemble(page_one)) let p = page_old.append(page_dom::(nodes |> List.map(fun (_, x)->x :> Present.IDomUnit))) p :?> Present.IDomUnit ) @@ -499,10 +439,7 @@ open System.IO abstract member getHtmlText:unit -> string end - type PageMaker<'T when - 'T :> Present.PageAccess and - 'T :> Present.IDomUnit and - 'T :> Present.IContainer>(page: 'T) = + type PageMaker(page: Present.PageAccess) = class member this.getHtmlDocument(): XmlDocument = let doc = XmlDocument() @@ -517,10 +454,12 @@ open System.IO head.AppendChild(charset) |> ignore let title = doc.CreateElement("title") - title.AppendChild(doc.CreateTextNode(page.name())) |> ignore + let page_dom = page :> Present.IDomUnit + title.AppendChild(doc.CreateTextNode(page_dom.name())) |> ignore head.AppendChild(title) |> ignore let style = doc.CreateElement("style") + style.AppendChild(doc.CreateTextNode("""body{ background-color:lightgray; } @@ -571,6 +510,7 @@ open System.IO max-width:100%; } """)) |> ignore + head.AppendChild(style) |> ignore html.AppendChild(head) |> ignore @@ -580,7 +520,7 @@ open System.IO html.AppendChild(body) |> ignore let h1 = doc.CreateElement("h1") - h1.AppendChild(doc.CreateTextNode(page.name())) |> ignore + h1.AppendChild(doc.CreateTextNode(page_dom.name())) |> ignore body.AppendChild(h1) |> ignore let div_outline = doc.CreateElement("div") @@ -596,42 +536,60 @@ open System.IO div_content.SetAttribute("id", "content") div_content.SetAttribute("class", "content") div_outline.AppendChild(div_content) |> ignore - this.contentAppend(div_content, page.children()) + + let page_set = page :> Present.IContainer + this.contentAppend(div_content, page_set.children()) doc member this.initNavigate(nav: XmlElement):XmlElement = - let rec nav_items_expand(nav: XmlElement, items: (Present.IDomUnit option*Present.IDomUnit option*Present.IDomUnit option) list) = + /// 导航栏生成 + let rec nav_items_expand(nav: XmlElement, items: Present.IDomUnit list) = match items with | [] -> () | _ -> let doc_o = nav.OwnerDocument - let (_, _, head) = items.Head - match head.Value with - | :? Present.Forwards as fx -> + let head = items.Head + match head with + | :? Present.Forward as fx -> let p = doc_o.CreateElement("p") let a = doc_o.CreateElement("a") a.SetAttribute("href", $"#{fx.elementID()}") - a.AppendChild(doc_o.CreateTextNode(head.Value.name())) |> ignore + a.AppendChild(doc_o.CreateTextNode(head.name())) |> ignore p.AppendChild(a) |> ignore nav.AppendChild(p) |> ignore - | :? Present.Backwards as bx -> + | :? Present.Backward as bx -> let p = doc_o.CreateElement("p") let a = doc_o.CreateElement("a") a.SetAttribute("href", $"#{bx.elementID()}") - a.AppendChild(doc_o.CreateTextNode(head.Value.name())) |> ignore + a.AppendChild(doc_o.CreateTextNode(head.name())) |> ignore p.AppendChild(a) |> ignore nav.AppendChild(p) |> ignore | _ -> () nav_items_expand(nav, items.Tail) - let objp = page :> obj - let point_peers = if (objp :? Present.PointPage) then - (objp :?>Present.PointPage).defines()::page.children() |> List.map(fun x-> None, None, Some(x)) - else - point_peers_extract(page.children()) + /// 导航条目提取 + let rec nav_items_extract(items: Present.IDomUnit list) : Present.IDomUnit list = + match items with + | [] -> [] + | _ -> + let head = items.Head + match head with + | :? Present.Forward -> + let s = head :?> Present.IContainer + head::nav_items_extract(s.children())@nav_items_extract(items.Tail) + + | :? Present.Backward as bx-> + let s = head :?> Present.IContainer + head::nav_items_extract(s.children())@nav_items_extract(items.Tail) + | :? Present.IContainer as set-> + nav_items_extract(set.children())@nav_items_extract(items.Tail) + | _ -> nav_items_extract(items.Tail) + + + let point_peers = nav_items_extract [page] match point_peers with | [] -> let empty = nav.OwnerDocument.CreateElement("p") @@ -667,18 +625,6 @@ open System.IO pnode.AppendChild(p) |> ignore this.contentAppend(pnode, List.skip one_line.Length contents) - | :? Content.SliceDefine as slice_defs-> - let div_slice = vdoc.CreateElement("div") - div_slice.SetAttribute("data-type", "slice") - div_slice.SetAttribute("class", "content") - let slice_title = vdoc.CreateElement("h3") - slice_title.AppendChild(vdoc.CreateTextNode(contents.Head.name())) |> ignore - div_slice.AppendChild(slice_title) |> ignore - pnode.AppendChild(div_slice) |> ignore - let slice_con = slice_defs :> Present.IContainer - this.contentAppend(div_slice, slice_con.children()) - this.contentAppend(pnode, contents.Tail) - | :? Content.ArticleDefine as article_defs -> let div_article = vdoc.CreateElement("div") div_article.SetAttribute("data-type", "article") @@ -691,16 +637,15 @@ open System.IO this.contentAppend(div_article, article_con.children()) this.contentAppend(pnode, contents.Tail) - | :? Present.PointPage as page_point -> - let page_defs = page_point.defines() :?> Content.AssembleRefer + | :? Present.SlicePage as page_point -> + let page_defs = page_point.defines().Value :?> Content.AssembleRefer this.contentAppend(pnode, [page_defs]) this.contentAppend(pnode, contents.Tail) - - | :? Present.Forwards as object_defs -> + | :? Present.Forward as object_defs -> let type_name = match object_defs with - | :? Content.PointDefine -> "point" - | :? Content.PointRefer -> "refer" + | :? Content.FragmentSlice -> "slice" + | :? Content.FragmentRefer -> "refer" | _ -> failwith "type mismatch" let div_forwards = vdoc.CreateElement("div") @@ -721,7 +666,7 @@ open System.IO this.contentAppend(div_forwards, point_con.children()) this.contentAppend(pnode, contents.Tail) - | :? Present.Backwards as object_backs -> + | :? Present.Backward as object_backs -> let div_backwards = vdoc.CreateElement("div") div_backwards.SetAttribute("data-type", "assemble") div_backwards.SetAttribute("class", "content") @@ -741,7 +686,7 @@ open System.IO this.contentAppend(pnode, contents.Tail) | _ -> () - + interface PageText with member this.bindPage():obj = page @@ -759,7 +704,7 @@ open System.IO type IndexPage(name: string, childs: Present.IDomUnit list) = class - inherit Present.PageAccess("index") + inherit Present.PageAccess("index", None, childs) new(name) = IndexPage(name, []) member this.append(arg: Present.IDomUnit list) = @@ -976,225 +921,220 @@ open System.IO 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) + |> 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) = + member private this.nodedefs_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) + let list_a = this.nodedefs_collect(story.children()) + (list_a|> List.map(fun (_, b) -> Some(story), b))@this.nodedefs_collect(objs.Tail) + | :? AstImport.FragmentSlice as slice -> + (None, slice)::this.nodedefs_collect(objs.Tail) + | _ -> this.nodedefs_collect(objs.Tail) - member this.getGraphCode(): string = - let node_about = this.node_collect(lines|> List.map(fun d -> d :> AstImport.AstObject)) + member this.getGraphCode(): string = "" + //let slice_refers = 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 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 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_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 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 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 - | [] -> slice_combine(items.Tail) - | _ -> - (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}""" - ) - |> 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 + // | [] -> slice_combine(items.Tail) + // | _ -> + // (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}""" + // ) + // |> List.reduce(fun a b -> a + "\n" + b) - $"""digraph node_relates{{ - rankdir=LR - label="{gname}" - {nodes_decl} - {slice_relates} - {refer_arrows} - {story_arrows} - }}""" + // $"""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) + //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()) + // 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 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 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 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) + // 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} }}""" + // $"""graph{{ label="{gname}" {clusters_desc} {refer_arrows} }}""" - end \ No newline at end of file + // end \ No newline at end of file diff --git a/AstConv/Program.fs b/AstConv/Program.fs index b29a61b..93f9ff9 100644 --- a/AstConv/Program.fs +++ b/AstConv/Program.fs @@ -39,18 +39,18 @@ entry.visitWith(visitor) |> ignore let volume_pages = volume_page_assemble(visitor.contents()) |> List.map (fun x->x) let story_pages = story_page_assemble(visitor.contents()) |> List.map (fun x->x) -let point_pages = point_page_assemble(volume_pages @ story_pages) +let point_pages = slice_page_assemble(volume_pages @ story_pages) 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 - | :? PointPage as point -> - PageMaker(point) :> PageText + | :? SlicePage as point -> + PageMaker(point) :> PageText | :? VolumePage as vol -> - PageMaker(vol) + PageMaker(vol) | :? StoryPage as story -> - PageMaker(story) + PageMaker(story) | _ -> failwith "" ) @@ -63,17 +63,17 @@ for refs in makers do let file_path = (refs.bindPage() :?> PageAccess).pageURL() File.WriteAllLines(file_path, [refs.getHtmlText()]) -let graph = StorylineGraphMake("故事线网络", story_pages|> List.map(fun x -> x :?> PageAccess)) -let graph_code = graph.getGraphCode() +//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 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 +//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 diff --git a/CoreTest/syntax_example.txt b/CoreTest/syntax_example.txt index 1595d4a..23a0d0b 100644 --- a/CoreTest/syntax_example.txt +++ b/CoreTest/syntax_example.txt @@ -16,81 +16,51 @@ {故事 故事名称5 故事介绍段落 aldkfjl flwief - {剧情 剧情名称} + {情节 情节名称} } {故事 故事名称6 故事介绍段落 aldkfjl flwief - {剧情 剧情名称 剧情介绍} + {情节 情节名称 情节介绍} } {故事 故事名称7 故事介绍段落 aldkfjl flwief - {剧情 剧情名称 - 剧情介绍 + {情节 情节名称 + 情节介绍 + {@情节 故事名称6&情节名称} } } {故事 故事名称8 故事介绍段落 aldkfjl flwief - {剧情 剧情名称 - 剧情介绍 - {节点 节点名称} + {情节 情节名称 + 情节介绍 + {@情节 故事名称6&情节名称 引用简介} } } {故事 故事名称9 故事介绍段落 aldkfjl flwief - {剧情 剧情名称 - 剧情介绍 - {节点 节点名称 - 奥龙订饭;爱领克 非两爱看扥} + {情节 情节名称 + 情节介绍 + {@情节 故事名称6&情节名称 + 引用简介 + } } } {故事 故事名称10 故事介绍段落 aldkfjl flwief - {剧情 剧情名称 - 剧情介绍 - {节点 节点名称 - 奥龙订饭;爱领克 非两爱看扥 - } - } -} - -{故事 故事名称11 - 故事介绍段落 aldkfjl flwief - {剧情 剧情名称 - 剧情介绍 - {节点 节点名称 - 奥龙订饭;爱领克 非两爱看扥 - {@节点 故事名称10&剧情名称&节点名称} - } - } -} - -{故事 故事名称4 - 故事介绍段落 aldkfjl flwief - {剧情 剧情名称 - 剧情介绍 - {节点 节点名称 - 奥龙订饭;爱领克 非两爱看扥 - {@节点 故事名称10&剧情名称&节点名称 - asldkfj 来看房莱肯} - } - } -} - -{故事 故事名称4 - 故事介绍段落 aldkfjl flwief - {剧情 剧情名称 - 剧情介绍 - {节点 节点名称 - 奥龙订饭;爱领克 非两爱看扥 - {@节点 故事名称10&剧情名称&节点名称 - asldkfj 来看房莱肯 - } - } + {情节 情节名称 + 情节介绍 + {@情节 故事名称6&情节名称 + 引用简介 + } + + {@情节 故事名称8&情节名称 + 引用简介 + } } } @@ -116,14 +86,14 @@ {分卷 卷宗名称 拉开茯苓领赛季发啦肯 lakdjf;alfj {章节 章节名称 昂来看申领发 - {@节点 故事名称10&剧情名称&节点名称} + {@情节 故事名称7&情节名称} } } {分卷 卷宗名称 拉开茯苓领赛季发啦肯 lakdjf;alfj {章节 章节名称 昂来看申领发 - {@节点 故事名称10&剧情名称&节点名称 - 森铃但凡拉动垦局} - } + {@情节 故事名称7&情节名称 + 森铃但凡拉动垦局} + } } \ No newline at end of file diff --git a/WsNovelParser/htmlprint.cpp b/WsNovelParser/htmlprint.cpp index 0c6b19c..cea06a4 100644 --- a/WsNovelParser/htmlprint.cpp +++ b/WsNovelParser/htmlprint.cpp @@ -55,7 +55,7 @@ bool printer::AstGenerate::visit(std::shared_ptr s { decltype(this->element_stack) temp_stack; std::copy_if(element_stack.begin(), element_stack.end(), - std::back_inserter(temp_stack), [=](std::pair ep){ return ep.first < depth; }); + std::back_inserter(temp_stack), [=](std::pair ep) { return ep.first < depth; }); this->element_stack = temp_stack; auto current_ast = element_stack.last(); @@ -87,25 +87,6 @@ bool printer::AstGenerate::visit(std::shared_ptr s dom_slice.setAttribute("name", slice_node->name()); dom_slice.setAttribute("address", (qulonglong) slice_node.get()); }break; - case NovelNode::PointDefines: - { - decltype(this->element_stack) temp_stack; - std::copy_if(element_stack.begin(), element_stack.end(), - std::back_inserter(temp_stack), [=](std::pair ep) { return ep.first < depth; }); - this->element_stack = temp_stack; - - auto current_slice = element_stack.last(); - auto point_node = std::dynamic_pointer_cast(syntax_element->element()); - auto dom_point = doc.createElement("point"); - current_slice.second.appendChild(dom_point); - element_stack.append(std::make_pair(depth, dom_point)); - - dom_point.setAttribute("name", point_node->name()); - dom_point.setAttribute("address", (qulonglong) point_node.get()); - dom_point.setAttribute("file-path", src_root.relativeFilePath(point_node->filePath())); - - append_tokens(dom_point, point_node); - }break; case NovelNode::TextSection: { decltype(this->element_stack) temp_stack; @@ -123,7 +104,7 @@ bool printer::AstGenerate::visit(std::shared_ptr s append_tokens(dom_text, text_node); }break; - case NovelNode::PointRefers: + case NovelNode::FragmentRefers: { decltype(this->element_stack) temp_stack; std::copy_if(element_stack.begin(), element_stack.end(), @@ -131,14 +112,13 @@ bool printer::AstGenerate::visit(std::shared_ptr s this->element_stack = temp_stack; auto current_pnode = element_stack.last(); - auto refer_node = std::dynamic_pointer_cast(syntax_element->element()); + auto refer_node = std::dynamic_pointer_cast(syntax_element->element()); auto dom_refer = doc.createElement("refer"); current_pnode.second.appendChild(dom_refer); element_stack.append(std::make_pair(depth, dom_refer)); dom_refer.setAttribute("story", refer_node->storyRefer()); dom_refer.setAttribute("slice", refer_node->sliceRefer()); - dom_refer.setAttribute("point", refer_node->pointRefer()); dom_refer.setAttribute("file-path", src_root.relativeFilePath(refer_node->filePath())); append_tokens(dom_refer, refer_node); diff --git a/WsNovelParser/main.cpp b/WsNovelParser/main.cpp index 2a8fd52..c7614a3 100644 --- a/WsNovelParser/main.cpp +++ b/WsNovelParser/main.cpp @@ -51,7 +51,7 @@ int main(int argc, char* argv[]) { auto source_dir = QDir(src_dir->value().toString()); if (!source_dir.exists()) { - cout << "%编译指定的源代码目录不存在!" << endl; + qDebug() << "%编译指定的源代码目录不存在!" << source_dir.absolutePath() << endl; exit(0); } auto destination_dir = QDir::current(); @@ -60,7 +60,7 @@ int main(int argc, char* argv[]) { destination_dir = QDir(target_output.toString()); } else { - cout << "%编译指定的生成目录不存在,重置为:" << destination_dir.absolutePath().toLocal8Bit().data() << endl; + qDebug() << "%编译指定的生成目录不存在,重置为:" << destination_dir.absolutePath().toLocal8Bit().data() << endl; } auto files = source_dir.entryInfoList(QStringList() << "*.story"); diff --git a/libParse/parse_novel.cpp b/libParse/parse_novel.cpp index 1ace7fb..5b2b402 100644 --- a/libParse/parse_novel.cpp +++ b/libParse/parse_novel.cpp @@ -19,7 +19,7 @@ void ElementsCache::clearCache() { std::shared_ptr ElementsCache::appendToCache(std::shared_ptr named_node) { auto mixed_key = QString("%1<%2>").arg(named_node->signature()).arg(named_node->typeMark()); if (node_cache.contains(mixed_key)) - return node_cache[mixed_key]; + throw new CheckException(QString("节点命名重复:%1!").arg(mixed_key)); node_cache[mixed_key] = named_node; return nullptr; } @@ -40,12 +40,12 @@ void example_novel::FragmentExistsCheck::nodes_regist(std::shared_ptr root, std::shared_ptr target) const { - if (target->element()->typeMark() == (int) NovelNode::PointRefers) { - auto refer = std::dynamic_pointer_cast(target->element()); - auto signature = refer->storyRefer() + "&" + refer->sliceRefer() + "&" + refer->pointRefer(); - if (!root->getNamedNodeBy((int) NovelNode::PointDefines, signature)) + if (target->element()->typeMark() == (int) NovelNode::FragmentRefers) { + auto refer = std::dynamic_pointer_cast(target->element()); + auto signature = refer->storyRefer() + "&" + refer->sliceRefer(); + if (!root->getNamedNodeBy((int) NovelNode::FragmentSlice, signature)) throw new SyntaxException(QString("CheckError[0x0005]系统中不包含指定签名的节点:%1{%3:(%4)}") - .arg(signature).arg((int) NovelNode::PointDefines).arg(refer->signature()).arg(refer->filePath())); + .arg(signature).arg((int) NovelNode::FragmentRefers).arg(refer->signature()).arg(refer->filePath())); } for (auto& xit : target->children()) { @@ -152,7 +152,7 @@ void PointGraphCheck::validCheck(std::shared_ptr root) cons auto story_children = story->children(); for (auto ins : story_children) { switch (ins->element()->typeMark()) { - case (int) NovelNode::PointDefines: + case (int) NovelNode::FragmentSlice: return_temp << ins; break; default: @@ -171,7 +171,7 @@ void PointGraphCheck::validCheck(std::shared_ptr root) cons auto x_children = defs->children(); for (auto ins : x_children) { switch (ins->element()->typeMark()) { - case (int) NovelNode::PointRefers: + case (int) NovelNode::FragmentRefers: return_temp << ins; break; default: @@ -191,7 +191,7 @@ void PointGraphCheck::validCheck(std::shared_ptr root) cons // 构建情节节点列表 for (auto point_primitive : point_items) { - auto target_node = std::dynamic_pointer_cast(point_primitive->element()); + auto target_node = std::dynamic_pointer_cast(point_primitive->element()); auto finst = std::make_shared(target_node); self->setElement(finst); } @@ -200,12 +200,12 @@ void PointGraphCheck::validCheck(std::shared_ptr root) cons // 获取绑定节点名称 auto get_name = [](std::shared_ptr node)->QString { switch (node->element()->typeMark()) { - case (int) NovelNode::PointDefines: { - auto def_node = std::dynamic_pointer_cast(node->element()); + case (int) NovelNode::FragmentSlice: { + auto def_node = std::dynamic_pointer_cast(node->element()); return def_node->signature(); }break; - case (int) NovelNode::PointRefers: { - auto ref_node = std::dynamic_pointer_cast(node->element()); + case (int) NovelNode::FragmentRefers: { + auto ref_node = std::dynamic_pointer_cast(node->element()); return ref_node->referSignature(); }break; } @@ -275,9 +275,9 @@ QString PointGraphCheck::name() const { return "情节网络有效性检查器"; } -PointGraphHelper::PointGraphHelper(std::shared_ptr node) : node_peer(node) { } +PointGraphHelper::PointGraphHelper(std::shared_ptr node) : node_peer(node) { } -std::shared_ptr PointGraphHelper::nodePeer() const { +std::shared_ptr PointGraphHelper::nodePeer() const { return this->node_peer; } diff --git a/libParse/parse_novel.h b/libParse/parse_novel.h index c5d8f45..a2c3c71 100644 --- a/libParse/parse_novel.h +++ b/libParse/parse_novel.h @@ -74,14 +74,14 @@ namespace example_novel { class PointGraphHelper : public std::enable_shared_from_this { private: - std::shared_ptr node_peer; + std::shared_ptr node_peer; QList> next_nodes; uint indegree = 0; public: - PointGraphHelper(std::shared_ptr node); + PointGraphHelper(std::shared_ptr node); - std::shared_ptr nodePeer() const; + std::shared_ptr nodePeer() const; void appendNext(std::shared_ptr node); QList> nextList() const; diff --git a/libSyntax/ast_novel.cpp b/libSyntax/ast_novel.cpp index d1c1662..621536d 100644 --- a/libSyntax/ast_novel.cpp +++ b/libSyntax/ast_novel.cpp @@ -22,59 +22,34 @@ QString TextSection::signature() const { return parent().lock()->signature() + "&::section"; } -PointRefers::PointRefers(std::shared_ptr rule_bind) +FragmentRefers::FragmentRefers(std::shared_ptr rule_bind) : AbstractImpl(rule_bind) { } -QString PointRefers::storyRefer() const { +QString FragmentRefers::storyRefer() const { return story_refs; } -void PointRefers::setStoryRefer(const QString& refer) { +void FragmentRefers::setStoryRefer(const QString& refer) { this->story_refs = refer; } -QString PointRefers::sliceRefer() const { +QString FragmentRefers::sliceRefer() const { return slice_ref; } -void PointRefers::setSliceRefer(const QString& refer) { +void FragmentRefers::setSliceRefer(const QString& refer) { slice_ref = refer; } -QString PointRefers::pointRefer() const { - return point_ref; +QString FragmentRefers::referSignature() const { + return storyRefer() + "&" + sliceRefer(); } -void PointRefers::setPointRefer(const QString& refer) { - this->point_ref = refer; -} - -QString PointRefers::referSignature() const { - return storyRefer() + "&" + sliceRefer() + "&" + pointRefer(); -} - -QString PointRefers::signature() const { +QString FragmentRefers::signature() const { QString signature = "@" + referSignature(); return parent().lock()->signature() + "&" + signature; } - -PointDefines::PointDefines(std::shared_ptr rule_bind) - : AbstractImpl(rule_bind) { } - -QString PointDefines::name() const { - return name_store; -} - -void PointDefines::setName(const QString& nm) { - this->name_store = nm; -} - -QString PointDefines::signature() const { - return parent().lock()->signature() + "&" + name(); -} - - StoryDefine::StoryDefine(std::shared_ptr rule_bind) : AbstractImpl(rule_bind), sort_index(0) { } diff --git a/libSyntax/ast_novel.h b/libSyntax/ast_novel.h index 88111ab..c71259f 100644 --- a/libSyntax/ast_novel.h +++ b/libSyntax/ast_novel.h @@ -105,14 +105,13 @@ namespace example_novel { enum class NovelNode { GlobalElement = 0, TextSection = 1, - PointRefers = 2, - PointDefines = 3, + FragmentRefers = 2, + FragmentSlice = 3, StoryDefine = 4, Document = 5, ArticleDefine = 6, VolumeDefine = 7, RankDeclaration = 8, - FragmentSlice = 9, }; /* @@ -123,15 +122,13 @@ namespace example_novel { | |-TextSection | \-FragmentSlice | |-TextSection - | |-PointDefines - | | \-TextSection - | \-PointRefers + | \-FragmentRefers | \-TextSection \-VolumeDefine |-TextSection \-ArticleDefine |-TextSection - \-PointRefers + \-FragmentRefers \-TextSection */ @@ -189,7 +186,7 @@ namespace example_novel { }; /** - * @brief 故事情节 + * @brief 故事情节定义 */ class LIBSYNTAX_EXPORT FragmentSlice : public AbstractImpl { private: @@ -206,14 +203,14 @@ namespace example_novel { }; /** - * @brief 节点引用定义 + * @brief 情节引用定义 */ - class LIBSYNTAX_EXPORT PointRefers : public AbstractImpl { + class LIBSYNTAX_EXPORT FragmentRefers : public AbstractImpl { private: - QString story_refs, slice_ref, point_ref; + QString story_refs, slice_ref; public: - PointRefers(std::shared_ptr rule_bind); + FragmentRefers(std::shared_ptr rule_bind); QString storyRefer() const; void setStoryRefer(const QString& refer); @@ -221,31 +218,12 @@ namespace example_novel { QString sliceRefer() const; void setSliceRefer(const QString& refer); - QString pointRefer() const; - void setPointRefer(const QString& refer); - QString referSignature() const; // 通过 AbstractImpl 继承 virtual QString signature() const override; }; - /** - * @brief 节点定义 - */ - class LIBSYNTAX_EXPORT PointDefines : public AbstractImpl { - private: - QString name_store; - - public: - PointDefines(std::shared_ptr rule_bind); - - QString name() const; - void setName(const QString& nm); - - // 通过 AbstractImpl 继承 - virtual QString signature() const override; - }; /** * @brief 章节定义 diff --git a/libSyntax/syntax_novel.cpp b/libSyntax/syntax_novel.cpp index be71c50..41ccd1d 100644 --- a/libSyntax/syntax_novel.cpp +++ b/libSyntax/syntax_novel.cpp @@ -12,22 +12,14 @@ using namespace std; #include "syntax_templets.h" using namespace lib_composit; -void point_nm_set(std::shared_ptr inst, std::shared_ptr token) { - inst->addToken(token); - inst->setName(token->content()); -} -void ref_story_set(std::shared_ptr inst, std::shared_ptr token) { +void ref_story_set(std::shared_ptr inst, std::shared_ptr token) { inst->addToken(token); inst->setStoryRefer(token->content()); } -void ref_slice_set(std::shared_ptr inst, std::shared_ptr token) { +void ref_slice_set(std::shared_ptr inst, std::shared_ptr token) { inst->addToken(token); inst->setSliceRefer(token->content()); } -void ref_point_set(std::shared_ptr inst, std::shared_ptr token) { - inst->addToken(token); - inst->setPointRefer(token->content()); -} void slice_nm_set(std::shared_ptr inst, std::shared_ptr token) { inst->addToken(token); inst->setName(token->content()); @@ -136,12 +128,12 @@ public: }; -using ReferSyntaxDef = lib_composit::Seqs, Match, Match, Action, Match, Action, Match, Action, +using ReferSyntaxDef = lib_composit::Seqs, Match, Match, Action, Match, Action, OptMulti, Match>; -class ReferSyntax : public ElementRule { +class ReferSyntax : public ElementRule { public: - ReferSyntax() : ElementRule("point_refer") { } + ReferSyntax() : ElementRule("fragment_refer") { } // 通过 ElementRule 继承 QList> expr_rule_parse(std::shared_ptr cursor) const override { @@ -150,27 +142,12 @@ public: }; -using PointSyntaxDef = lib_composit::Seqs, Match, Action, - OptMulti>, - Match>; -class PointSyntax : public ElementRule { -public: - PointSyntax() : ElementRule("point_define") { } - - // 通过 ElementRule 继承 - QList> expr_rule_parse(std::shared_ptr cursor) const override { - return _children_store->parse(cursor); - } -}; - - - using SliceSyntaxDef = lib_composit::Seqs, Match, Action, - lib_composit::OptMulti>, + lib_composit::OptMulti>, Match>; class SliceSyntax : public ElementRule { public: - SliceSyntax() : ElementRule("slice_define") { } + SliceSyntax() : ElementRule("fragment_define") { } // 通过 ElementRule 继承 QList> expr_rule_parse(std::shared_ptr cursor) const override { @@ -179,7 +156,6 @@ public: }; - using StorySyntaxDef = lib_composit::Seqs, Match, Action, lib_composit::OptMulti>, Match>; diff --git a/libSyntax/tokens_novel.cpp b/libSyntax/tokens_novel.cpp index fd4c303..4ed2571 100644 --- a/libSyntax/tokens_novel.cpp +++ b/libSyntax/tokens_novel.cpp @@ -219,9 +219,7 @@ inline example_novel::RankWord::RankWord() : __keywords("排序", 0xAEu) { } inline example_novel::StoryWord::StoryWord() : __keywords("故事", 0xAAu) { } -inline example_novel::SliceWord::SliceWord() : __keywords("剧情", 0xAFu) { } - -inline example_novel::PointWord::PointWord() : __keywords("节点", 0xABu) { } +inline example_novel::SliceWord::SliceWord() : __keywords("情节", 0xAFu) { } inline example_novel::VolumeWord::VolumeWord() : __keywords("分卷", 0xACu) { } diff --git a/libSyntax/tokens_novel.h b/libSyntax/tokens_novel.h index c1d1fd7..28dacb2 100644 --- a/libSyntax/tokens_novel.h +++ b/libSyntax/tokens_novel.h @@ -66,10 +66,6 @@ namespace example_novel { public: SliceWord(); }; - class LIBSYNTAX_EXPORT PointWord : public __keywords { - public: - PointWord(); - }; class LIBSYNTAX_EXPORT VolumeWord : public __keywords { public: VolumeWord();