package wiki import ( "strings" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/web/html" kit "shylinux.com/x/toolkits" ) type Item struct { list []string args []ice.Any } func NewItem(str string, args ...ice.Any) *Item { return &Item{[]string{str}, args} } func (item *Item) Push(str string, arg ice.Any) *Item { switch arg := arg.(type) { case string: if arg == "" { return item } case int: if arg == 0 { return item } } item.list, item.args = append(item.list, str), append(item.args, arg) return item } func (item *Item) Echo(str string, arg ...ice.Any) *Item { item.list = append(item.list, kit.Format(str, arg...)) return item } func (item *Item) Dump(m *ice.Message) *ice.Message { return m.Echo(kit.Join(item.list, lex.SP), item.args...).Echo(lex.NL) } type Group struct{ list ice.Messages } func NewGroup(m *ice.Message, arg ...string) *Group { g := &Group{list: ice.Messages{}} kit.For(arg, func(k string) { g.list[k] = m.Spawn() }) return g } func AddGroupOption(m *ice.Message, group string, arg ...string) { kit.For(arg, func(k, v string) { m.Option(kit.Keys(group, k), v) }) } func (g *Group) Option(group string, key string, arg ...ice.Any) string { return g.Get(group).Option(kit.Keys(group, key), arg...) } func (g *Group) Get(group string) *ice.Message { return g.list[group] } func (g *Group) Echo(group string, str string, arg ...ice.Any) *ice.Message { return g.Get(group).Echo(str, arg...) } func (g *Group) EchoRect(group string, height, width, x, y int, arg ...string) *ice.Message { // rx ry return g.Echo(group, "", x, y, height, width, kit.Select("4", arg, 0), kit.Select("4", arg, 1), formatStyle(kit.Slice(arg, 2)...)) } func (g *Group) EchoLine(group string, x1, y1, x2, y2 int, arg ...string) *ice.Message { return g.Echo(group, "", x1, y1, x2, y2, formatStyle(arg...)) } func (g *Group) EchoPath(group string, str string, arg ...ice.Any) *ice.Message { return g.Echo(group, ``, kit.Format(str, arg...)) } func (g *Group) EchoText(group string, x, y int, text string, arg ...string) *ice.Message { m := g.Get(group) offset := kit.Int(kit.Select("8", "4", m.IsMobileUA())) return g.Echo(group, "%s", x, y+offset, formatStyle(arg...), text) } func (g *Group) EchoArrowLine(group string, x1, y1, x2, y2 int, arg ...string) *ice.Message { // marker-end return g.EchoLine(group, x1, y1, x2, y2, "marker-end", kit.Format("url(#%s)", kit.Select("arrowhead", arg, 0))) } func (g *Group) DefsArrow(group string, height, width int, arg ...string) *ice.Message { // name return g.Echo(group, ` `, kit.Select("arrowhead", arg, 0), height, width, height/2, width, height/2, height) } func (g *Group) Dump(m *ice.Message, group string, arg ...string) *Group { item := NewItem("").Dump(m).Copy(g.Get(group)).Echo("") return g } func (g *Group) DumpAll(m *ice.Message, group ...string) { kit.For(group, func(grp string) { g.Dump(m, grp) }) } type Chart interface { Init(*ice.Message, ...string) Chart Draw(*ice.Message, int, int) Chart GetHeight(...string) int GetWidth(...string) int } var chart_list = map[string]func(m *ice.Message) Chart{} func AddChart(name string, hand func(m *ice.Message) Chart) { chart_list[name] = hand } func _chart_show(m *ice.Message, name, text string, arg ...string) { kit.For(arg, func(k, v string) { m.Option(k, v) }) m.Option(FILL, kit.Select(m.Option(FILL), m.Option(BG))) m.Option(STROKE, kit.Select(m.Option(STROKE), m.Option(FG))) chart := chart_list[name](m) chart.Init(m, text) m.OptionDefault(STROKE_WIDTH, "2") m.OptionDefault(FONT_SIZE, kit.Select("24", "13", m.IsMobileUA())) m.Options(HEIGHT, chart.GetHeight(), WIDTH, chart.GetWidth()) _wiki_template(m, "", name, text, arg...) defer m.RenderResult() defer m.Echo("") chart.Draw(m, 0, 0) } func formatStyle(arg ...string) string { return kit.JoinKV(mdb.EQ, lex.SP, kit.TransArgKey(arg, transKey)...) } var transKey = map[string]string{ BG: html.BG_COLOR, FG: html.FG_COLOR, } const ( FG = "fg" BG = "bg" FONT_SIZE = "font-size" FONT_FAMILY = "font-family" STROKE_DASHARRAY = "stroke-dasharray" STROKE_WIDTH = "stroke-width" STROKE = "stroke" FILL = "fill" PADDING = "padding" MARGINX = "marginx" MARGINY = "marginy" HEIGHT = "height" WIDTH = "width" ) const ( LABEL = "label" CHAIN = "chain" SEQUENCE = "sequence" ) const CHART = "chart" func init() { Index.MergeCommands(ice.Commands{ CHART: {Name: "chart type=label,chain,sequence", Help: "图表", Hand: func(m *ice.Message, arg ...string) { _chart_show(m, arg[0], strings.TrimSpace(arg[1]), arg[2:]...) }}, }) }