构建格式化程序
This commit is contained in:
parent
764e1bbb82
commit
5e58c924a8
|
@ -8,6 +8,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="AstImport.fs" />
|
<Compile Include="AstImport.fs" />
|
||||||
<Compile Include="HtmlStruct.fs" />
|
<Compile Include="HtmlStruct.fs" />
|
||||||
|
<Compile Include="FmtStruct.fs" />
|
||||||
<Compile Include="Program.fs" />
|
<Compile Include="Program.fs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,19 @@ open System.Linq
|
||||||
|
|
||||||
module AstImport =
|
module AstImport =
|
||||||
/// 带有地址的对象
|
/// 带有地址的对象
|
||||||
type AstObject() =
|
type AstObject(bind: XmlElement) =
|
||||||
class
|
class
|
||||||
|
member this.astXML() = bind
|
||||||
|
member this.rows() =
|
||||||
|
let xmle = bind.SelectSingleNode("tokens/token") :?> XmlElement
|
||||||
|
int(xmle.GetAttribute "row")
|
||||||
|
|
||||||
abstract member address:unit -> string
|
abstract member address:unit -> string
|
||||||
default this.address():string = "mem_" + string(this.GetHashCode ())
|
default this.address():string = "mem_" + string(this.GetHashCode ())
|
||||||
|
|
||||||
|
abstract member filePath:unit -> string
|
||||||
|
default this.filePath():string = ""
|
||||||
|
|
||||||
abstract member members:unit -> AstObject list
|
abstract member members:unit -> AstObject list
|
||||||
default this.members(): AstObject list = []
|
default this.members(): AstObject list = []
|
||||||
end
|
end
|
||||||
|
@ -34,7 +42,7 @@ open System.Linq
|
||||||
/// TextWord
|
/// TextWord
|
||||||
type TextItem(bind: XmlElement) =
|
type TextItem(bind: XmlElement) =
|
||||||
class
|
class
|
||||||
inherit AstObject()
|
inherit AstObject(bind)
|
||||||
member this.content():string =
|
member this.content():string =
|
||||||
bind.GetAttribute "text"
|
bind.GetAttribute "text"
|
||||||
|
|
||||||
|
@ -54,7 +62,7 @@ open System.Linq
|
||||||
/// 引用节点
|
/// 引用节点
|
||||||
type FragmentRef(bind: XmlElement, texts: TextItem list) =
|
type FragmentRef(bind: XmlElement, texts: TextItem list) =
|
||||||
class
|
class
|
||||||
inherit AstObject()
|
inherit AstObject(bind)
|
||||||
new(bind: XmlElement) = FragmentRef(bind, [])
|
new(bind: XmlElement) = FragmentRef(bind, [])
|
||||||
|
|
||||||
member this.sliceRef() =
|
member this.sliceRef() =
|
||||||
|
@ -89,7 +97,7 @@ open System.Linq
|
||||||
/// 情节节点
|
/// 情节节点
|
||||||
type FragmentSlice(bind: XmlElement, objs: AstObject list) =
|
type FragmentSlice(bind: XmlElement, objs: AstObject list) =
|
||||||
class
|
class
|
||||||
inherit AstObject()
|
inherit AstObject(bind)
|
||||||
new(bind: XmlElement) = FragmentSlice(bind, [])
|
new(bind: XmlElement) = FragmentSlice(bind, [])
|
||||||
|
|
||||||
member this.name() =
|
member this.name() =
|
||||||
|
@ -134,7 +142,7 @@ open System.Linq
|
||||||
/// 故事节点
|
/// 故事节点
|
||||||
type StoryDef(bind: XmlElement, objs: AstObject list) =
|
type StoryDef(bind: XmlElement, objs: AstObject list) =
|
||||||
class
|
class
|
||||||
inherit AstObject()
|
inherit AstObject(bind)
|
||||||
new(bind: XmlElement) = StoryDef(bind, [])
|
new(bind: XmlElement) = StoryDef(bind, [])
|
||||||
|
|
||||||
member this.name() =
|
member this.name() =
|
||||||
|
@ -150,6 +158,8 @@ open System.Linq
|
||||||
override this.members(): AstObject list = objs
|
override this.members(): AstObject list = objs
|
||||||
override this.address (): string =
|
override this.address (): string =
|
||||||
bind.GetAttribute "address"
|
bind.GetAttribute "address"
|
||||||
|
override this.filePath (): string =
|
||||||
|
bind.GetAttribute "file-path"
|
||||||
|
|
||||||
static member GenerateFromChildSibling(child: XmlNode): StoryChildType list =
|
static member GenerateFromChildSibling(child: XmlNode): StoryChildType list =
|
||||||
match child with
|
match child with
|
||||||
|
@ -181,7 +191,7 @@ open System.Linq
|
||||||
/// 章节节点
|
/// 章节节点
|
||||||
type ArticleDef(bind: XmlElement, objs: AstObject list) =
|
type ArticleDef(bind: XmlElement, objs: AstObject list) =
|
||||||
class
|
class
|
||||||
inherit AstObject()
|
inherit AstObject(bind)
|
||||||
new(bind: XmlElement) = ArticleDef(bind, [])
|
new(bind: XmlElement) = ArticleDef(bind, [])
|
||||||
|
|
||||||
member this.name() =
|
member this.name() =
|
||||||
|
@ -226,7 +236,7 @@ open System.Linq
|
||||||
/// 卷宗节点
|
/// 卷宗节点
|
||||||
type VolumeDef(bind: XmlElement, objs: AstObject list) =
|
type VolumeDef(bind: XmlElement, objs: AstObject list) =
|
||||||
class
|
class
|
||||||
inherit AstObject()
|
inherit AstObject(bind)
|
||||||
new(bind: XmlElement) = VolumeDef(bind, [])
|
new(bind: XmlElement) = VolumeDef(bind, [])
|
||||||
|
|
||||||
member this.name() =
|
member this.name() =
|
||||||
|
@ -244,6 +254,8 @@ open System.Linq
|
||||||
override this.members(): AstObject list = objs
|
override this.members(): AstObject list = objs
|
||||||
override this.address (): string =
|
override this.address (): string =
|
||||||
bind.GetAttribute "address"
|
bind.GetAttribute "address"
|
||||||
|
override this.filePath (): string =
|
||||||
|
bind.GetAttribute "file-path"
|
||||||
|
|
||||||
static member GenerateFromChildSibling(child: XmlNode): VolumeChildType list =
|
static member GenerateFromChildSibling(child: XmlNode): VolumeChildType list =
|
||||||
match child with
|
match child with
|
||||||
|
@ -270,11 +282,21 @@ open System.Linq
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
type ProgramChildType = |Volume of VolumeDef |Story of StoryDef
|
type RankDef(bind: XmlElement) =
|
||||||
|
class
|
||||||
|
inherit AstObject(bind)
|
||||||
|
|
||||||
|
member this.sort():int32 =
|
||||||
|
int32(bind.GetAttribute "rank")
|
||||||
|
override this.filePath (): string =
|
||||||
|
bind.GetAttribute "doc-path"
|
||||||
|
end
|
||||||
|
|
||||||
|
type ProgramChildType = |Volume of VolumeDef |Story of StoryDef |Rank of RankDef
|
||||||
/// 程序节点
|
/// 程序节点
|
||||||
type Program(bind: XmlElement, objs: AstObject list) =
|
type Program(bind: XmlElement, objs: AstObject list) =
|
||||||
class
|
class
|
||||||
inherit AstObject()
|
inherit AstObject(bind)
|
||||||
new(bind: XmlElement) = Program(bind, [])
|
new(bind: XmlElement) = Program(bind, [])
|
||||||
|
|
||||||
member this.time() =
|
member this.time() =
|
||||||
|
@ -285,6 +307,7 @@ open System.Linq
|
||||||
match it with
|
match it with
|
||||||
|Story s -> s :> AstObject
|
|Story s -> s :> AstObject
|
||||||
|Volume v -> v :> AstObject
|
|Volume v -> v :> AstObject
|
||||||
|
|Rank r -> r:> AstObject
|
||||||
)
|
)
|
||||||
Program(bind, objs @items)
|
Program(bind, objs @items)
|
||||||
|
|
||||||
|
@ -297,6 +320,7 @@ open System.Linq
|
||||||
let d = match child.Name with
|
let d = match child.Name with
|
||||||
| "volume" -> Some(Volume(VolumeDef.GenerateVolumeDef(child).Value))
|
| "volume" -> Some(Volume(VolumeDef.GenerateVolumeDef(child).Value))
|
||||||
| "story" -> Some(Story(StoryDef.GenerateStoryDef(child).Value))
|
| "story" -> Some(Story(StoryDef.GenerateStoryDef(child).Value))
|
||||||
|
| "rank" -> Some(Rank(RankDef(child :?> XmlElement)))
|
||||||
| _ -> None
|
| _ -> None
|
||||||
match d with
|
match d with
|
||||||
|Some value -> value::Program.GenerateFromChildSibling(child.NextSibling)
|
|Some value -> value::Program.GenerateFromChildSibling(child.NextSibling)
|
||||||
|
@ -309,6 +333,7 @@ open System.Linq
|
||||||
let conv data = match data with
|
let conv data = match data with
|
||||||
|Volume d -> d:>AstObject
|
|Volume d -> d:>AstObject
|
||||||
|Story d -> d :> AstObject
|
|Story d -> d :> AstObject
|
||||||
|
|Rank d -> d:> AstObject
|
||||||
Program(ast, mbrs |> List.map conv)
|
Program(ast, mbrs |> List.map conv)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,222 @@
|
||||||
|
namespace FmtStruct
|
||||||
|
|
||||||
|
open AstAccess
|
||||||
|
open HtmlStruct
|
||||||
|
|
||||||
|
module FmtEntry =
|
||||||
|
// rank反序列化
|
||||||
|
let rank_fmt(node: AstImport.AstObject): string =
|
||||||
|
let domx = node :?> AstImport.RankDef
|
||||||
|
$"#排序 {domx.sort()}\n"
|
||||||
|
|
||||||
|
// 提取相同的类型元素
|
||||||
|
let rec same_collect<'T when 'T:>Present.IDomUnit>
|
||||||
|
(nodes: Present.IDomUnit list): Present.IDomUnit list * Present.IDomUnit list =
|
||||||
|
|
||||||
|
if nodes.Length = 0 then
|
||||||
|
[], []
|
||||||
|
else
|
||||||
|
match nodes.Head with
|
||||||
|
| :? 'T ->
|
||||||
|
let tn, rest = same_collect<'T>(nodes.Tail)
|
||||||
|
nodes.Head::tn, rest
|
||||||
|
| _ -> [], nodes
|
||||||
|
|
||||||
|
|
||||||
|
// 分类两种不同的类型元素
|
||||||
|
let rec same_fold<'T1,'T2 when 'T1:> Present.IDomUnit and 'T2:> Present.IDomUnit>
|
||||||
|
(nodes: Present.IDomUnit list): Present.IDomUnit list list =
|
||||||
|
let first_list, rest_0 = same_collect<'T1>(nodes)
|
||||||
|
let second_list, rest_1 = same_collect<'T2>(rest_0)
|
||||||
|
|
||||||
|
let list = match rest_1 with
|
||||||
|
|[] -> first_list::[second_list]
|
||||||
|
| _ -> first_list::[second_list]@same_fold<'T1, 'T2>(rest_1)
|
||||||
|
list |> List.filter(fun slist -> slist.Length > 0)
|
||||||
|
|
||||||
|
// 字符串格式化
|
||||||
|
let rec text_fmt(prefix:string)(line_prev: int32)(nodes: Content.TextContent list): string =
|
||||||
|
match nodes with
|
||||||
|
| [] -> ""
|
||||||
|
| _ ->
|
||||||
|
let obj_text = (nodes.Head :> Present.IDomUnit).object()
|
||||||
|
let this_text = (obj_text :?> AstImport.TextItem).content()
|
||||||
|
if obj_text.rows() = line_prev then
|
||||||
|
" " + this_text + text_fmt prefix line_prev nodes.Tail
|
||||||
|
else
|
||||||
|
$"\n{prefix}" + this_text + text_fmt prefix (obj_text.rows()) nodes.Tail
|
||||||
|
|
||||||
|
|
||||||
|
// 格式化Refer:Node
|
||||||
|
let slice_ref_fmt(prefix:string)(node: Content.FragmentRefer): string =
|
||||||
|
let objref = (node:> Present.IDomUnit).object():?> AstImport.FragmentRef
|
||||||
|
|
||||||
|
let childs = (node:> Present.IContainer).children()
|
||||||
|
let text_childs, rest = same_collect<Content.TextContent>(childs)
|
||||||
|
assert(rest.Length = 0)
|
||||||
|
|
||||||
|
let text_type_childs = text_childs|> List.map(fun n-> n:?> Content.TextContent)
|
||||||
|
let sections = text_fmt (prefix+" ") (objref.rows()) text_type_childs
|
||||||
|
|
||||||
|
$"{prefix}{{@情节 {objref.storyRef()}&{objref.sliceRef()}{sections}}}"
|
||||||
|
|
||||||
|
|
||||||
|
// 格式化Slice:Node
|
||||||
|
let slice_def_fmt(prefix:string)(node: Content.FragmentSlice): string =
|
||||||
|
let obj_def = (node:> Present.IDomUnit).object():?> AstImport.FragmentSlice
|
||||||
|
|
||||||
|
let childs = (node:> Present.IContainer).children()
|
||||||
|
let same_groups_set = same_fold<Content.TextContent, Content.FragmentRefer>(childs)
|
||||||
|
let contents = same_groups_set |> List.map(fun same_set ->
|
||||||
|
if same_set.Length = 0 then
|
||||||
|
""
|
||||||
|
else
|
||||||
|
match same_set.Head with
|
||||||
|
| :? Content.FragmentRefer ->
|
||||||
|
let strx = same_set|> List.map(fun n ->
|
||||||
|
slice_ref_fmt (prefix+" ") (n:?> Content.FragmentRefer)
|
||||||
|
)
|
||||||
|
strx |> List.reduce(fun a b -> a + "\n" + b)
|
||||||
|
| :? Content.TextContent ->
|
||||||
|
let typed_set = same_set|>List.map(fun fn->fn:?>Content.TextContent)
|
||||||
|
text_fmt (prefix+" ") (obj_def.rows()) typed_set
|
||||||
|
| _ -> failwith "mismatch"
|
||||||
|
)
|
||||||
|
let subs = match contents with
|
||||||
|
| [] -> ""
|
||||||
|
| _ -> contents|> List.reduce(fun a b -> a + "\n" + b)
|
||||||
|
$"{prefix}{{情节 {obj_def.name()}{subs}\n{prefix}}}"
|
||||||
|
|
||||||
|
|
||||||
|
// 格式化Story:Node
|
||||||
|
let story_def_fmt(node: Content.StoryDefine): string =
|
||||||
|
let obj_story = (node:> Present.IDomUnit).object():?> AstImport.StoryDef
|
||||||
|
|
||||||
|
let childs = (node:> Present.IContainer).children()
|
||||||
|
let same_groups_set = same_fold<Content.TextContent, Content.FragmentSlice>(childs)
|
||||||
|
let contents = same_groups_set |> List.map(fun same_set ->
|
||||||
|
if same_set.Length = 0 then
|
||||||
|
""
|
||||||
|
else
|
||||||
|
match same_set.Head with
|
||||||
|
| :? Content.FragmentSlice ->
|
||||||
|
let strx = same_set|> List.map(fun n ->
|
||||||
|
slice_def_fmt " " (n:?> Content.FragmentSlice)
|
||||||
|
)
|
||||||
|
strx |> List.reduce(fun a b -> a + "\n" + b)
|
||||||
|
| :? Content.TextContent ->
|
||||||
|
let typed_set = same_set|>List.map(fun fn->fn:?>Content.TextContent)
|
||||||
|
text_fmt " " (obj_story.rows()) typed_set
|
||||||
|
| _ -> failwith "mismatch-storydef"
|
||||||
|
)
|
||||||
|
let subs = match contents with
|
||||||
|
| [] -> ""
|
||||||
|
| _ -> contents|> List.reduce(fun a b -> a + "\n" + b)
|
||||||
|
$"{{故事 {obj_story.name()}{subs}\n}}"
|
||||||
|
|
||||||
|
|
||||||
|
// 格式化Article:Node
|
||||||
|
let article_def_fmt(prefix:string)(node: Content.ArticleDefine): string =
|
||||||
|
let obj_article = (node:> Present.IDomUnit).object():?> AstImport.ArticleDef
|
||||||
|
|
||||||
|
let childs = (node:> Present.IContainer).children()
|
||||||
|
let same_groups_set = same_fold<Content.TextContent, Content.FragmentRefer>(childs)
|
||||||
|
let contents = same_groups_set |> List.map(fun same_set ->
|
||||||
|
if same_set.Length = 0 then
|
||||||
|
""
|
||||||
|
else
|
||||||
|
match same_set.Head with
|
||||||
|
| :? Content.FragmentRefer ->
|
||||||
|
let strx = same_set|> List.map(fun n ->
|
||||||
|
slice_ref_fmt (prefix+" ") (n:?> Content.FragmentRefer)
|
||||||
|
)
|
||||||
|
strx |> List.reduce(fun a b -> a + "\n" + b)
|
||||||
|
| :? Content.TextContent ->
|
||||||
|
let typed_set = same_set|>List.map(fun fn->fn:?>Content.TextContent)
|
||||||
|
text_fmt (prefix+" ") (obj_article.rows()) typed_set
|
||||||
|
| _ -> failwith "mismatch"
|
||||||
|
)
|
||||||
|
let subs = match contents with
|
||||||
|
| [] -> ""
|
||||||
|
| _ -> contents|> List.reduce(fun a b -> a + "\n" + b)
|
||||||
|
$"{prefix}{{章节 {obj_article.name()}{subs}\n{prefix}}}"
|
||||||
|
|
||||||
|
|
||||||
|
// 格式化Volume:Node
|
||||||
|
let volume_def_fmt(node: Content.VolumeDefine): string =
|
||||||
|
let obj_volume = (node:> Present.IDomUnit).object():?> AstImport.VolumeDef
|
||||||
|
|
||||||
|
let childs = (node:> Present.IContainer).children()
|
||||||
|
let same_groups_set = same_fold<Content.TextContent, Content.ArticleDefine>(childs)
|
||||||
|
let contents = same_groups_set |> List.map(fun same_set ->
|
||||||
|
if same_set.Length = 0 then
|
||||||
|
""
|
||||||
|
else
|
||||||
|
match same_set.Head with
|
||||||
|
| :? Content.ArticleDefine ->
|
||||||
|
let strx = same_set|> List.map(fun n ->
|
||||||
|
article_def_fmt " " (n:?> Content.ArticleDefine)
|
||||||
|
)
|
||||||
|
strx |> List.reduce(fun a b -> a + "\n" + b)
|
||||||
|
| :? Content.TextContent ->
|
||||||
|
let typed_set = same_set |> List.map(fun fn->fn:?>Content.TextContent)
|
||||||
|
text_fmt " " (obj_volume.rows()) typed_set
|
||||||
|
| _ -> failwith "mismatch-volumedef"
|
||||||
|
)
|
||||||
|
let subs = match contents with
|
||||||
|
| [] -> ""
|
||||||
|
| _ -> contents|> List.reduce(fun a b -> a + "\n" + b)
|
||||||
|
$"{{分卷 {obj_volume.name()}{subs}\n}}"
|
||||||
|
|
||||||
|
|
||||||
|
let document_def_fmt(path:string)(nodes: Present.IDomUnit list):string =
|
||||||
|
let head_str, rest_nodes=match nodes.Head with
|
||||||
|
| :? Content.RankDefine ->
|
||||||
|
rank_fmt(nodes.Head.object()), nodes.Tail
|
||||||
|
| _ -> "", nodes
|
||||||
|
let sorted_nodes = rest_nodes|> List.sortBy (fun a->a.object().rows())
|
||||||
|
let nodes_str = sorted_nodes|> List.map(fun nx ->
|
||||||
|
match nx with
|
||||||
|
| :? Content.VolumeDefine as vdef ->
|
||||||
|
volume_def_fmt vdef
|
||||||
|
| :? Content.StoryDefine as sdef->
|
||||||
|
story_def_fmt sdef
|
||||||
|
| _ -> failwith "error-doc-child"
|
||||||
|
)
|
||||||
|
head_str + (nodes_str|> List.reduce(fun a b -> a + "\n" + b))
|
||||||
|
|
||||||
|
|
||||||
|
let program_def_fmt(nodes: Present.IDomUnit list):string list =
|
||||||
|
let ranks = nodes|> List.filter(fun n -> n:?Content.RankDefine)
|
||||||
|
|
||||||
|
let content_with_rank = ranks|> List.map(fun rankn ->
|
||||||
|
let rank_o = rankn.object() :?> AstImport.RankDef
|
||||||
|
let file_path = rank_o.filePath()
|
||||||
|
|
||||||
|
let nodes_within = nodes|> List.filter(fun n ->
|
||||||
|
match n with
|
||||||
|
| :? Content.StoryDefine ->
|
||||||
|
n.object().filePath() = file_path
|
||||||
|
| :? Content.VolumeDefine ->
|
||||||
|
n.object().filePath() = file_path
|
||||||
|
| _ -> false)
|
||||||
|
document_def_fmt file_path (rankn::nodes_within)
|
||||||
|
)
|
||||||
|
|
||||||
|
let nodes_hangout = nodes|> List.filter(fun n ->
|
||||||
|
let rank_paths = ranks|> List.map(fun n -> n.object().filePath())
|
||||||
|
match n with
|
||||||
|
| :? Content.VolumeDefine ->
|
||||||
|
not(List.contains (n.object().filePath()) rank_paths)
|
||||||
|
| _ -> false
|
||||||
|
)
|
||||||
|
|
||||||
|
let path_hangout = nodes_hangout|> List.map(fun n -> n.object().filePath())
|
||||||
|
|> List.distinct
|
||||||
|
|
||||||
|
let content_without_rank = path_hangout |> List.map(fun path ->
|
||||||
|
let nodes_within = nodes_hangout|> List.filter(fun n -> n.object().filePath() = path)
|
||||||
|
document_def_fmt path nodes_within
|
||||||
|
)
|
||||||
|
|
||||||
|
content_with_rank@content_without_rank
|
|
@ -269,6 +269,13 @@ open System.IO
|
||||||
)
|
)
|
||||||
VolumeDefine(defs, childs)
|
VolumeDefine(defs, childs)
|
||||||
|
|
||||||
|
type RankDefine(defs: AstImport.RankDef) =
|
||||||
|
class
|
||||||
|
interface Present.IDomUnit with
|
||||||
|
member this.name(): string =
|
||||||
|
raise (System.NotImplementedException())
|
||||||
|
member this.object(): AstImport.AstObject = defs
|
||||||
|
end
|
||||||
|
|
||||||
type UnitGenerate(root: AstImport.AstObject) =
|
type UnitGenerate(root: AstImport.AstObject) =
|
||||||
class
|
class
|
||||||
|
@ -296,6 +303,8 @@ open System.IO
|
||||||
result_nodes@[(refs_depth, ArticleDefine(defs, childs))]
|
result_nodes@[(refs_depth, ArticleDefine(defs, childs))]
|
||||||
| :? AstImport.VolumeDef as defs ->
|
| :? AstImport.VolumeDef as defs ->
|
||||||
result_nodes@[(refs_depth, VolumeDefine(defs, childs))]
|
result_nodes@[(refs_depth, VolumeDefine(defs, childs))]
|
||||||
|
| :? AstImport.RankDef as defs ->
|
||||||
|
result_nodes@[refs_depth, RankDefine(defs)]
|
||||||
| :? AstImport.Program -> result_nodes
|
| :? AstImport.Program -> result_nodes
|
||||||
| _ -> failwith "match error"
|
| _ -> failwith "match error"
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,9 @@ open HtmlStruct.Present
|
||||||
open System.IO
|
open System.IO
|
||||||
open System
|
open System
|
||||||
open System.Diagnostics
|
open System.Diagnostics
|
||||||
|
open FmtStruct.FmtEntry
|
||||||
|
|
||||||
let html_generate (file_in:FileInfo) (dir_o:DirectoryInfo) =
|
let html_generate (file_in:FileInfo) (dir_o:DirectoryInfo): unit =
|
||||||
let out_dir = Uri(dir_o.FullName)
|
let out_dir = Uri(dir_o.FullName)
|
||||||
|
|
||||||
let doc = XmlDocument()
|
let doc = XmlDocument()
|
||||||
|
@ -59,9 +60,24 @@ let html_generate (file_in:FileInfo) (dir_o:DirectoryInfo) =
|
||||||
stream2.Flush()
|
stream2.Flush()
|
||||||
Process.Start("dot", $"""-Tsvg -o{Path.Combine(dir_o.FullName, "volume_display.svg")} {Path.Combine(dir_o.FullName, "volume_display.dot")}""") |> ignore
|
Process.Start("dot", $"""-Tsvg -o{Path.Combine(dir_o.FullName, "volume_display.svg")} {Path.Combine(dir_o.FullName, "volume_display.dot")}""") |> ignore
|
||||||
|
|
||||||
|
let source_format (file_in:FileInfo): unit =
|
||||||
|
let doc = XmlDocument()
|
||||||
|
doc.Load(file_in.FullName)
|
||||||
|
|
||||||
|
let prog = Program.GenerateFrom(doc)
|
||||||
|
let entry = AstVisitEntry(prog)
|
||||||
|
let visitor = UnitGenerate(prog)
|
||||||
|
entry.visitWith(visitor) |> ignore
|
||||||
|
|
||||||
|
// 获取内容节点
|
||||||
|
let nodes = visitor.contents()
|
||||||
|
let strings = program_def_fmt nodes
|
||||||
|
for it in strings do
|
||||||
|
printfn $"{it}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let args = System.Environment.GetCommandLineArgs()|> Array.toList
|
let args = System.Environment.GetCommandLineArgs()|> Array.toList
|
||||||
|
|
||||||
|
|
||||||
// 参数校验
|
// 参数校验
|
||||||
match args.Length with
|
match args.Length with
|
||||||
| 2 when args.Item(1) = "--help" ->
|
| 2 when args.Item(1) = "--help" ->
|
||||||
|
@ -71,7 +87,10 @@ match args.Length with
|
||||||
|
|
||||||
// 格式化
|
// 格式化
|
||||||
| 4 when args.Item(1) = "--file" && args.Item(3) = "--format" ->
|
| 4 when args.Item(1) = "--file" && args.Item(3) = "--format" ->
|
||||||
printfn "开发中"
|
if not(FileInfo(args.Item 2).Exists) then
|
||||||
|
printfn "Arguments-Error:指定xast文件不存在"
|
||||||
|
exit 0
|
||||||
|
source_format(FileInfo(args.Item 2)) |> ignore
|
||||||
|
|
||||||
// html生成
|
// html生成
|
||||||
| 5 when args.Item(1) = "--file" && args.Item(3) = "--html" ->
|
| 5 when args.Item(1) = "--file" && args.Item(3) = "--html" ->
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"AstConv": {
|
"AstConv": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"commandLineArgs": "-file \"E:/storyline.xast\" -odir \"E:/\""
|
"commandLineArgs": "--file \"E:/storyline.xast\" --format"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
// For more information see https://aka.ms/fsharp-console-apps
|
||||||
|
|
||||||
|
type MarkX() =
|
||||||
|
class
|
||||||
|
abstract member some:unit-> unit
|
||||||
|
default this.some() =
|
||||||
|
printfn "Hello World!"
|
||||||
|
end
|
||||||
|
|
||||||
|
type SubMark() =
|
||||||
|
class
|
||||||
|
inherit MarkX()
|
||||||
|
|
||||||
|
override this.some (): unit =
|
||||||
|
printfn "Substract"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
let code = SubMark()
|
||||||
|
code.some()
|
|
@ -0,0 +1,12 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Program.fs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -40,6 +40,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CoreTest", "CoreTest\CoreTe
|
||||||
EndProject
|
EndProject
|
||||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AstConv", "AstConv\AstConv.fsproj", "{0C77216C-6484-4C94-BE06-D5D9FF18EA81}"
|
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AstConv", "AstConv\AstConv.fsproj", "{0C77216C-6484-4C94-BE06-D5D9FF18EA81}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "TestProject", "TestProject\TestProject.fsproj", "{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -134,6 +136,18 @@ Global
|
||||||
{0C77216C-6484-4C94-BE06-D5D9FF18EA81}.Release|x64.Build.0 = Release|Any CPU
|
{0C77216C-6484-4C94-BE06-D5D9FF18EA81}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{0C77216C-6484-4C94-BE06-D5D9FF18EA81}.Release|x86.ActiveCfg = Release|Any CPU
|
{0C77216C-6484-4C94-BE06-D5D9FF18EA81}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{0C77216C-6484-4C94-BE06-D5D9FF18EA81}.Release|x86.Build.0 = Release|Any CPU
|
{0C77216C-6484-4C94-BE06-D5D9FF18EA81}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{08F9F7F7-CDB4-4644-92A3-99C41A77CD90}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -113,12 +113,12 @@
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="htmlprint.cpp" />
|
<ClCompile Include="astprint.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="novelparser.cpp" />
|
<ClCompile Include="novelparser.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="htmlprint.h" />
|
<ClInclude Include="astprint.h" />
|
||||||
<ClInclude Include="novelparser.h" />
|
<ClInclude Include="novelparser.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
<ClCompile Include="novelparser.cpp">
|
<ClCompile Include="novelparser.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="htmlprint.cpp">
|
<ClCompile Include="astprint.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
<ClInclude Include="novelparser.h">
|
<ClInclude Include="novelparser.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="htmlprint.h">
|
<ClInclude Include="astprint.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "htmlprint.h"
|
#include "astprint.h"
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDomElement>
|
#include <QDomElement>
|
||||||
|
|
||||||
|
@ -86,6 +86,8 @@ bool printer::AstGenerate::visit(std::shared_ptr<const ast_gen::ElementAccess> s
|
||||||
|
|
||||||
dom_slice.setAttribute("name", slice_node->name());
|
dom_slice.setAttribute("name", slice_node->name());
|
||||||
dom_slice.setAttribute("address", (qulonglong) slice_node.get());
|
dom_slice.setAttribute("address", (qulonglong) slice_node.get());
|
||||||
|
|
||||||
|
append_tokens(dom_slice, slice_node);
|
||||||
}break;
|
}break;
|
||||||
case NovelNode::TextSection:
|
case NovelNode::TextSection:
|
||||||
{
|
{
|
|
@ -14,7 +14,7 @@
|
||||||
#include <argsparser.h>
|
#include <argsparser.h>
|
||||||
|
|
||||||
#include "novelparser.h"
|
#include "novelparser.h"
|
||||||
#include "htmlprint.h"
|
#include "astprint.h"
|
||||||
|
|
||||||
using namespace example_novel;
|
using namespace example_novel;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
Loading…
Reference in New Issue