diff --git a/core/wiki/chart.go b/core/wiki/chart.go index b736847f..20e33f46 100644 --- a/core/wiki/chart.go +++ b/core/wiki/chart.go @@ -9,6 +9,7 @@ import ( // 图形接口 type Chart interface { Init(*ice.Message, ...string) Chart + Data(*ice.Message, interface{}) Chart Draw(*ice.Message, int, int) Chart GetWidth(...string) int @@ -18,14 +19,12 @@ type Chart interface { // 图形基类 type Block struct { Text string + FontSize int FontColor string - FontFamily string BackGround string - FontSize int - LineSize int - Padding int - Margin int + Padding int + Margin int Width, Height int @@ -35,31 +34,41 @@ type Block struct { func (b *Block) Init(m *ice.Message, arg ...string) Chart { b.Text = kit.Select(b.Text, arg, 0) - b.FontColor = kit.Select("white", kit.Select(b.FontColor, arg, 1)) - b.BackGround = kit.Select("red", kit.Select(b.BackGround, arg, 2)) - b.FontSize = kit.Int(kit.Select("24", kit.Select(kit.Format(b.FontSize), arg, 3))) - b.LineSize = kit.Int(kit.Select("12", kit.Select(kit.Format(b.LineSize), arg, 4))) + b.FontSize = kit.Int(kit.Select(m.Option("font-size"), kit.Select(kit.Format(b.FontSize), arg, 1))) + b.FontColor = kit.Select(m.Option("stroke"), kit.Select(b.FontColor, arg, 2)) + b.BackGround = kit.Select(m.Option("fill"), kit.Select(b.BackGround, arg, 3)) + b.Padding = kit.Int(kit.Select(m.Option("padding"), kit.Select(kit.Format(b.Padding), arg, 4))) + b.Margin = kit.Int(kit.Select(m.Option("margin"), kit.Select(kit.Format(b.Margin), arg, 5))) + return b +} +func (b *Block) Data(m *ice.Message, root interface{}) Chart { + b.Text = kit.Select(b.Text, kit.Value(root, "text")) + kit.Fetch(root, func(key string, value string) { + switch key { + case "fg": + b.TextData += kit.Format("%s='%s' ", "fill", value) + case "bg": + b.RectData += kit.Format("%s='%s' ", "fill", value) + } + }) + kit.Fetch(kit.Value(root, "data"), func(key string, value string) { + b.TextData += kit.Format("%s='%s' ", key, value) + }) + kit.Fetch(kit.Value(root, "rect"), func(key string, value string) { + b.RectData += kit.Format("%s='%s' ", key, value) + }) return b } func (b *Block) Draw(m *ice.Message, x, y int) Chart { - m.Echo(``, - x+b.Margin/2, y+b.Margin/2, b.GetWidth(), b.GetHeight(), b.BackGround, b.RectData) + m.Echo(``, + x+b.Margin/2, y+b.Margin/2, b.GetWidth(), b.GetHeight(), b.RectData) m.Echo("\n") - m.Echo(`%v`, - x+b.GetWidths()/2, y+b.GetHeights()/2, b.FontSize, b.FontColor, b.TextData, b.Text) + m.Echo(`%v`, + x+b.GetWidths()/2, y+b.GetHeights()/2, b.FontColor, b.TextData, b.Text) m.Echo("\n") return b } -func (b *Block) Data(root interface{}) { - kit.Fetch(kit.Value(root, "data"), func(key string, value string) { - b.TextData += key + "='" + value + "' " - }) - kit.Fetch(kit.Value(root, "rect"), func(key string, value string) { - b.RectData += key + "='" + value + "' " - }) - b.FontColor = kit.Select(b.FontColor, kit.Value(root, "fg")) - b.BackGround = kit.Select(b.BackGround, kit.Value(root, "bg")) -} + func (b *Block) GetWidth(str ...string) int { if b.Width != 0 { return b.Width @@ -90,9 +99,10 @@ type Label struct { } func (b *Label) Init(m *ice.Message, arg ...string) Chart { - b.FontSize = kit.Int(kit.Select("24", arg, 1)) - b.Padding = kit.Int(kit.Select("16", arg, 6)) - b.Margin = kit.Int(kit.Select("8", arg, 7)) + b.Text = kit.Select(b.Text, arg, 0) + b.FontSize = kit.Int(m.Option("font-size")) + b.Padding = kit.Int(m.Option("padding")) + b.Margin = kit.Int(m.Option("margin")) // 解析数据 b.max = map[int]int{} @@ -112,45 +122,46 @@ func (b *Label) Init(m *ice.Message, arg ...string) Chart { } // 计算尺寸 - width := 0 for _, v := range b.max { - width += v + b.Margin + b.Width += v + b.Margin } - b.Width = width b.Height = len(b.data) * b.GetHeights() return b } func (b *Label) Draw(m *ice.Message, x, y int) Chart { - b.Width, b.Height = 0, 0 top := y for _, line := range b.data { left := x for i, text := range line { + + // 数据 + item := &Block{ + FontSize: b.FontSize, + Padding: b.Padding, + Margin: b.Margin, + } switch data := kit.Parse(nil, "", kit.Split(text)...).(type) { case map[string]interface{}: - text = kit.Select(text, data["text"]) - } - b.Text = text - - width := b.max[i] - if m.Option("compact") == "true" { - width = b.GetWidth() + item.Init(m, kit.Select(text, data["text"])).Data(m, data) + default: + item.Init(m, text) } - m.Echo(``, - left, top, width, b.GetHeight()) - m.Echo("\n") - m.Echo(`%v`, - left+width/2, top+b.GetHeight()/2, m.Option("stroke"), text) - m.Echo("\n") - left += width + b.Margin + // 输出 + if m.Option("compact") != "true" { + item.Width = b.max[i] + } + item.Draw(m, left, top) + + left += item.GetWidth() + item.Margin + b.Height = item.GetHeight() } - top += b.GetHeights() + top += b.Height + b.Margin } return b } -// 树 +// 链 type Chain struct { data map[string]interface{} max map[int]int @@ -158,33 +169,28 @@ type Chain struct { } func (b *Chain) Init(m *ice.Message, arg ...string) Chart { - // 解数据 + b.FontSize = kit.Int(m.Option("font-size")) + b.Padding = kit.Int(m.Option("padding")) + b.Margin = kit.Int(m.Option("margin")) + + // 解析数据 b.data = kit.Parse(nil, "", b.show(m, arg[0])...).(map[string]interface{}) - b.FontColor = kit.Select("white", arg, 1) - b.BackGround = kit.Select("red", arg, 2) - b.FontSize = kit.Int(kit.Select("24", arg, 3)) - b.LineSize = kit.Int(kit.Select("12", arg, 4)) - b.Padding = kit.Int(kit.Select("8", arg, 5)) - b.Margin = kit.Int(kit.Select("8", arg, 6)) // 计算尺寸 b.max = map[int]int{} b.Height = b.size(m, b.data, 0, b.max) * b.GetHeights() - width := 0 for _, v := range b.max { - width += b.GetWidths(strings.Repeat(" ", v)) + b.Width += v } - b.Width = width - // m.Log("info", "data %v", kit.Formats(b.data)) return b } func (b *Chain) Draw(m *ice.Message, x, y int) Chart { - return b.draw(m, b.data, 0, b.max, x, y, &Block{}) + b.draw(m, b.data, 0, b.max, x, y, &Block{}) + return b } func (b *Chain) show(m *ice.Message, str string) (res []string) { miss := []int{} - list := kit.Split(str, "\n") - for _, line := range list { + for _, line := range kit.Split(str, "\n") { // 计算缩进 dep := 0 loop: @@ -231,9 +237,8 @@ func (b *Chain) size(m *ice.Message, root map[string]interface{}, depth int, wid meta := root[kit.MDB_META].(map[string]interface{}) // 最大宽度 - text := kit.Format(meta["text"]) - if len(text) > width[depth] { - width[depth] = len(text) + if w := b.GetWidths(kit.Format(meta["text"])); w > width[depth] { + width[depth] = w } // 计算高度 @@ -249,32 +254,34 @@ func (b *Chain) size(m *ice.Message, root map[string]interface{}, depth int, wid meta["height"] = height return height } -func (b *Chain) draw(m *ice.Message, root map[string]interface{}, depth int, width map[int]int, x, y int, p *Block) Chart { +func (b *Chain) draw(m *ice.Message, root map[string]interface{}, depth int, width map[int]int, x, y int, p *Block) int { meta := root[kit.MDB_META].(map[string]interface{}) b.Width, b.Height = 0, 0 // 当前节点 - block := &Block{ + item := &Block{ BackGround: kit.Select(b.BackGround, kit.Select(p.BackGround, meta["bg"])), FontColor: kit.Select(b.FontColor, kit.Select(p.FontColor, meta["fg"])), FontSize: b.FontSize, - LineSize: b.LineSize, Padding: b.Padding, Margin: b.Margin, - Width: b.GetWidth(strings.Repeat(" ", width[depth])), } - - block.Data(root[kit.MDB_META]) - block.Init(m, kit.Format(meta["text"])).Draw(m, x, y+(kit.Int(meta["height"])-1)*b.GetHeights()/2) + item.Init(m, kit.Format(meta["text"])).Data(m, meta) + item.Draw(m, x, y+(kit.Int(meta["height"])-1)*b.GetHeights()/2) // 递归节点 + h := 0 + x += item.GetWidths() kit.Fetch(root[kit.MDB_LIST], func(index int, value map[string]interface{}) { - b.draw(m, value, depth+1, width, x+b.GetWidths(strings.Repeat(" ", width[depth])), y, block) - y += kit.Int(kit.Value(value, "meta.height")) * b.GetHeights() + h += b.draw(m, value, depth+1, width, x, y+h, item) }) - return b + if h == 0 { + return item.GetHeights() + } + return h } +// 栈 func Stack(m *ice.Message, name string, level int, data interface{}) { style := []string{} kit.Fetch(kit.Value(data, "meta"), func(key string, value string) { diff --git a/core/wiki/wiki.go b/core/wiki/wiki.go index 1f341d17..e66da68d 100644 --- a/core/wiki/wiki.go +++ b/core/wiki/wiki.go @@ -7,8 +7,8 @@ import ( "github.com/shylinux/icebergs/base/web" "github.com/shylinux/toolkits" - "bytes" "fmt" + "io/ioutil" "os" "path" "strings" @@ -18,17 +18,7 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ "note": {Name: "note", Help: "笔记", Value: kit.Data( - "path", "", "temp", "var/tmp/file", - "head", "time size line path", - "alias", map[string]interface{}{ - "label": []interface{}{"chart", "label"}, - "chain": []interface{}{"chart", "chain"}, - - "section": []interface{}{"title", "section"}, - "chapter": []interface{}{"title", "chapter"}, - "endmenu": []interface{}{"title", "endmenu"}, - "premenu": []interface{}{"title", "premenu"}, - }, + "path", "", "head", "time size line path", )}, "title": {Name: "title", Help: "标题", Value: kit.Data("template", title)}, @@ -41,11 +31,21 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", "order": {Name: "order", Help: "列表", Value: kit.Data("template", order)}, "table": {Name: "table", Help: "表格", Value: kit.Data("template", table)}, "stack": {Name: "stack", Help: "结构", Value: kit.Data("template", stack)}, - "chart": {Name: "chart", Help: "绘图", Value: kit.Data("prefix", prefix, "suffix", ``)}, + "chart": {Name: "chart", Help: "绘图", Value: kit.Data("template", prefix, "suffix", ``)}, - "draw": {Name: "draw", Help: "思维导图", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.svg", "prefix", ``, "suffix", ``)}, - "word": {Name: "word", Help: "语言文字", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.shy")}, + "word": {Name: "word", Help: "语言文字", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.shy", + "alias", map[string]interface{}{ + "label": []interface{}{"chart", "label"}, + "chain": []interface{}{"chart", "chain"}, + + "section": []interface{}{"title", "section"}, + "chapter": []interface{}{"title", "chapter"}, + "endmenu": []interface{}{"title", "endmenu"}, + "premenu": []interface{}{"title", "premenu"}, + }, + )}, "data": {Name: "data", Help: "数据表格", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.csv")}, + "draw": {Name: "draw", Help: "思维导图", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.svg", "prefix", ``, "suffix", ``)}, "feel": {Name: "feel", Help: "影音媒体", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.(png|JPG|MOV|m4v)")}, "walk": {Name: "walk", Help: "走遍世界", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.csv")}, }, @@ -57,68 +57,26 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", m.Save("feel") }}, - "note": {Name: "note file", Help: "笔记", Meta: kit.Dict("remote", "you", "display", "inner"), List: kit.List( - kit.MDB_INPUT, "text", "name", "path", "value", "README.md", + "note": {Name: "note file", Help: "文档", Meta: kit.Dict("remote", "you", "display", "inner"), List: kit.List( + kit.MDB_INPUT, "text", "name", "path", "value", "README.md", "action", "auto", kit.MDB_INPUT, "button", "name", "执行", "action", "auto", kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) > 1 { - switch arg[1] { - case "运行": - switch arg[2] { - case "shell": - m.Cmdy(ice.CLI_SYSTEM, "sh", "-c", arg[4]) - } - - case "favor": - m.Cmdy(ice.WEB_FAVOR, kit.Select("story", m.Option("hot")), arg[2:]) - case "share": - m.Cmdy(ice.WEB_SHARE, "add", arg[2:]) - default: - m.Cmdy(arg) - } - return - } if len(arg) > 0 && strings.HasSuffix(arg[0], ".md") { arg[0] = path.Join(m.Conf("note", "meta.path"), arg[0]) } m.Cmdy(kit.Select("_tree", "_text", len(arg) > 0 && strings.HasSuffix(arg[0], ".md")), arg) }}, - "_tree": {Name: "_tree path", Help: "文库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - // m.Option("dir_deep", "true") + "_tree": {Name: "_tree [path [true]]", Help: "文库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Option("dir_reg", ".*\\.md") + m.Option("dir_deep", kit.Select("", arg, 1)) m.Cmdy("nfs.dir", kit.Select(m.Conf("note", "meta.path"), arg, 0), m.Conf("note", "meta.head")) }}, "_text": {Name: "_text file", Help: "文章", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(ice.WEB_TMPL, "raw") - m.Optionv("title", map[string]int{}) - m.Optionv("menu", map[string]interface{}{"list": []interface{}{}}) - if strings.HasSuffix(arg[0], ".shy") { - m.Optionv(ice.MSG_ALIAS, m.Confv("note", "meta.alias")) - m.Cmdy("ssh.scan", arg[0], arg[0], arg[0]) - return + if b, e := ioutil.ReadFile(arg[0]); m.Assert(e) { + data := markdown.ToHTML(b, nil, nil) + m.Echo(string(data)) } - - // 生成文章 - buffer := bytes.NewBuffer([]byte{}) - f := m.Target().Server().(*web.Frame) - tmpl := f.HandleCGI(m, m.Confm("note", "meta.alias"), arg[0]) - m.Assert(tmpl.ExecuteTemplate(buffer, m.Option("filename", path.Base(arg[0])), m)) - - // 缓存文章 - if f, p, e := kit.Create(path.Join(m.Conf("note", "meta.temp"), arg[0])); e == nil { - defer f.Close() - if n, e := f.Write(buffer.Bytes()); e == nil { - m.Log("info", "save %d %v", n, p) - } - } - - // 生成网页 - data := buffer.Bytes() - // if strings.HasSuffix(arg[0], ".md") { - data = markdown.ToHTML(buffer.Bytes(), nil, nil) - // } - m.Echo(string(data)) }}, "title": {Name: "title [chapter|section|endmenu|premenu] text", Help: "标题", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { @@ -317,75 +275,41 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", arg[1] = strings.TrimSpace(arg[1]) arg[2] = strings.TrimSpace(arg[2]) - // 构造数据 + // 基本参数 m.Option(kit.MDB_TYPE, arg[0]) m.Option(kit.MDB_NAME, arg[1]) m.Option(kit.MDB_TEXT, arg[2]) - m.Option("font-size", kit.Select("16", arg, 3)) + m.Option("font-size", kit.Select("24", arg, 3)) m.Option("stroke", kit.Select("yellow", arg, 4)) m.Option("fill", kit.Select("purple", arg, 5)) + // 扩展参数 m.Option("style", "") m.Option("compact", "false") m.Option("stroke-width", "2") + m.Option("padding", "10") + m.Option("margin", "10") m.Option("font-family", kit.Select("", "monospace", len(arg[2]) == len([]rune(arg[2])))) for i := 6; i < len(arg)-1; i++ { m.Option(arg[i], arg[i+1]) } + // 计算尺寸 chart.Init(m, arg[2:]...) m.Option("width", chart.GetWidth()) m.Option("height", chart.GetHeight()) - // 生成网页 - m.Render(m.Conf("chart", "meta.prefix")) - chart.Draw(m, 4, 4) + // 渲染绘图 + m.Render(m.Conf("chart", "meta.template")) + chart.Draw(m, 0, 0) m.Render(m.Conf("chart", "meta.suffix")) }}, - "draw": {Name: "draw", Help: "思维导图", Meta: kit.Dict("display", "wiki/draw"), List: kit.List( - kit.MDB_INPUT, "text", "name", "name", "value", "what/he.svg", - kit.MDB_INPUT, "button", "name", "执行", "action", "auto", - kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", - kit.MDB_INPUT, "button", "name", "上传", "cb", "upload", - ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) > 0 && arg[0] == "action" { - switch arg[1] { - case "保存": - m.Cmd("nfs.save", path.Join(m.Conf(cmd, "meta.path"), arg[2]), arg[3:]) - } - return - } - - // 文件列表 - m.Option("dir_root", m.Conf(cmd, "meta.path")) - m.Option("dir_reg", m.Conf(cmd, "meta.regs")) - m.Cmdy("nfs.dir", kit.Select("./", arg, 0)) - m.Sort("time", "time_r") - - if len(arg) == 0 || strings.HasSuffix(arg[0], "/") { - // 目录列表 - m.Option("dir_reg", "") - m.Option("dir_type", "dir") - m.Cmdy("nfs.dir", kit.Select("./", arg, 0)) - } - }}, "word": {Name: "word", Help: "语言文字", Meta: kit.Dict("remote", "pod", "display", "wiki/word"), List: kit.List( kit.MDB_INPUT, "text", "name", "name", "value", "自然/编程/hi.shy", kit.MDB_INPUT, "button", "name", "执行", "action", "auto", kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", - kit.MDB_INPUT, "button", "name", "上传", "cb", "upload", ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if m.Option("_action") == "上传" { - if len(arg) == 0 { - arg = append(arg, "/") - } - m.Cmdy(ice.WEB_STORY, "upload") - m.Cmd(ice.WEB_STORY, ice.STORY_WATCH, m.Append("data"), - path.Join(m.Conf(cmd, "meta.path"), arg[0], kit.Select("", m.Append("name"), strings.HasSuffix(arg[0], "/")))) - return - } - if len(arg) > 0 && arg[0] == "action" { switch arg[1] { case "追加": @@ -425,6 +349,7 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", m.Option("dir_reg", m.Conf(cmd, "meta.regs")) m.Cmdy("nfs.dir", kit.Select("./", arg, 0)) m.Sort("time", "time_r") + if len(arg) == 0 || strings.HasSuffix(arg[0], "/") { // 目录列表 m.Option("dir_reg", "") @@ -437,7 +362,7 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", m.Option(ice.WEB_TMPL, "raw") m.Optionv("title", map[string]int{}) m.Optionv("menu", map[string]interface{}{"list": []interface{}{}}) - m.Optionv(ice.MSG_ALIAS, m.Confv("note", "meta.alias")) + m.Optionv(ice.MSG_ALIAS, m.Confv("word", "meta.alias")) m.Set("result").Cmdy("ssh.scan", arg[0], arg[0], path.Join(m.Conf(cmd, "meta.path"), arg[0])) }}, "data": {Name: "data", Help: "数据表格", Meta: kit.Dict("display", "wiki/data"), List: kit.List( @@ -473,6 +398,33 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", } m.CSV(m.Result()) }}, + "draw": {Name: "draw", Help: "思维导图", Meta: kit.Dict("display", "wiki/draw"), List: kit.List( + kit.MDB_INPUT, "text", "name", "name", "value", "what/he.svg", + kit.MDB_INPUT, "button", "name", "执行", "action", "auto", + kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", + kit.MDB_INPUT, "button", "name", "上传", "cb", "upload", + ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) > 0 && arg[0] == "action" { + switch arg[1] { + case "保存": + m.Cmd("nfs.save", path.Join(m.Conf(cmd, "meta.path"), arg[2]), arg[3:]) + } + return + } + + // 文件列表 + m.Option("dir_root", m.Conf(cmd, "meta.path")) + m.Option("dir_reg", m.Conf(cmd, "meta.regs")) + m.Cmdy("nfs.dir", kit.Select("./", arg, 0)) + m.Sort("time", "time_r") + + if len(arg) == 0 || strings.HasSuffix(arg[0], "/") { + // 目录列表 + m.Option("dir_reg", "") + m.Option("dir_type", "dir") + m.Cmdy("nfs.dir", kit.Select("./", arg, 0)) + } + }}, "feel": {Name: "feel", Help: "影音媒体", Meta: kit.Dict("display", "wiki/feel", "detail", []string{"标签", "删除"}), List: kit.List( kit.MDB_INPUT, "text", "name", "name", kit.MDB_INPUT, "button", "name", "执行",