Przeglądaj źródła

текст в таблицах и слияние ячеек

kpmy 10 lat temu
rodzic
commit
3ec246aa68
5 zmienionych plików z 150 dodań i 101 usunięć
  1. 11 95
      mappers/fmt.go
  2. 109 0
      mappers/para.go
  3. 19 5
      mappers/table.go
  4. 2 0
      odf_test.go
  5. 9 1
      xmlns/table/t.go

+ 11 - 95
mappers/fmt.go

@@ -5,7 +5,6 @@ import (
 	"odf/model"
 	"odf/xmlns"
 	"odf/xmlns/office"
-	"odf/xmlns/text"
 	"reflect"
 	"ypk/assert"
 	"ypk/halt"
@@ -14,18 +13,17 @@ import (
 var New func(name model.LeafName) model.Leaf
 
 type Formatter struct {
-	m        model.Model
-	rider    model.Writer
-	MimeType xmlns.Mime
-	attr     *Attr
-	root     model.Node //root of document content, not model
-	ready    bool
+	m                 model.Model
+	MimeType          xmlns.Mime
+	attr              *Attr
+	root              model.Node //root of document content, not model
+	ready             bool
+	defaultParaMapper *ParaMapper
 }
 
 func (f *Formatter) ConnectTo(m model.Model) {
 	assert.For(m.Root().NofChild() == 0, 20, "only new documents for now")
 	f.m = m
-	f.rider = f.m.NewWriter()
 	f.attr = &Attr{}
 	f.ready = false
 }
@@ -49,7 +47,8 @@ func (f *Formatter) Init() {
 	default:
 		halt.As(100, f.MimeType)
 	}
-	f.rider.Pos(f.root)
+	f.defaultParaMapper = new(ParaMapper)
+	f.defaultParaMapper.ConnectTo(f)
 	f.ready = true
 }
 
@@ -61,95 +60,12 @@ func (f *Formatter) writeAttr() {
 
 func (f *Formatter) WritePara(s string) {
 	assert.For(f.ready, 20)
-	assert.For(f.MimeType == xmlns.MimeText, 21)
-	if pos := f.rider.Pos(); pos.Name() != office.Text || pos.Name() == text.P {
-		f.rider.Pos(f.root)
-	}
-	f.rider.WritePos(New(text.P))
-	f.writeAttr()
-	if a := f.attr.Fit(text.P); a != nil {
-		f.rider.Attr(text.StyleName, a.Name())
-	}
-	f.WriteString(s)
+	f.defaultParaMapper.WritePara(s)
 }
 
-func (f *Formatter) WriteString(_s string) {
+func (f *Formatter) WriteString(s string) {
 	assert.For(f.ready, 20)
-
-	buf := make([]rune, 0)
-	count := 0
-
-	flush := func(space bool) {
-		f.rider.Write(model.Text(string(buf)))
-		buf = make([]rune, 0)
-		if space && count > 1 {
-			w := f.m.NewWriter(f.rider)
-			w.WritePos(New(text.S))
-			w.Attr(text.C, count)
-		}
-	}
-
-	grow := func() {
-		if count > 1 {
-			flush(true)
-		} else if count == 1 {
-			buf = append(buf, ' ')
-		}
-		if len(buf) > 0 {
-			flush(false)
-		}
-		count = 0
-	}
-
-	if f.rider.Pos().Name() != text.P {
-		f.WritePara(_s)
-	} else {
-		f.writeAttr()
-		if a := f.attr.Fit(text.Span); a != nil {
-			f.rider.WritePos(New(text.Span))
-			f.rider.Attr(text.StyleName, a.Name())
-		}
-		s := []rune(_s)
-		br := false
-		for pos := 0; pos < len(s) && s[pos] != 0; {
-			switch s[pos] {
-			case ' ':
-				count++
-			case '\n':
-				grow()
-				f.rider.Write(New(text.LineBreak))
-			case '\r':
-				grow()
-				if f.attr.Fit(text.Span) != nil {
-					f.rider.Pos(f.rider.Pos().Parent())
-				}
-				for pos = pos + 1; pos < len(s); pos++ {
-					buf = append(buf, s[pos])
-				}
-				f.WritePara(string(buf))
-				pos--
-				br = true
-			case '\t':
-				grow()
-				f.rider.Write(New(text.Tab))
-			default:
-				if count > 1 {
-					flush(true)
-				} else if count == 1 {
-					buf = append(buf, ' ')
-				}
-				count = 0
-				buf = append(buf, s[pos])
-			}
-			pos++
-		}
-		if !br {
-			grow()
-			if f.attr.Fit(text.Span) != nil {
-				f.rider.Pos(f.rider.Pos().Parent())
-			}
-		}
-	}
+	f.defaultParaMapper.WriteString(s)
 }
 
 func (f *Formatter) SetAttr(a attr.Attributes) {

+ 109 - 0
mappers/para.go

@@ -0,0 +1,109 @@
+package mappers
+
+import (
+	"odf/model"
+	"odf/xmlns/text"
+	"ypk/assert"
+)
+
+type ParaMapper struct {
+	fm    *Formatter
+	rider model.Writer
+}
+
+func (p *ParaMapper) ConnectTo(fm *Formatter) {
+	p.fm = fm
+	p.rider = fm.m.NewWriter()
+	p.rider.Pos(fm.root)
+}
+
+func (p *ParaMapper) WritePara(s string) {
+	if pos := p.rider.Pos(); pos.Name() == text.P {
+		p.rider.Pos(pos.Parent())
+	}
+	p.rider.WritePos(New(text.P))
+	p.fm.writeAttr()
+	if a := p.fm.attr.Fit(text.P); a != nil {
+		p.rider.Attr(text.StyleName, a.Name())
+	}
+	p.WriteString(s)
+
+}
+func (p *ParaMapper) WriteString(_s string) {
+	assert.For(p.fm.ready, 20)
+
+	buf := make([]rune, 0)
+	count := 0
+
+	flush := func(space bool) {
+		p.rider.Write(model.Text(string(buf)))
+		buf = make([]rune, 0)
+		if space && count > 1 {
+			w := p.fm.m.NewWriter(p.rider)
+			w.WritePos(New(text.S))
+			w.Attr(text.C, count)
+		}
+	}
+
+	grow := func() {
+		if count > 1 {
+			flush(true)
+		} else if count == 1 {
+			buf = append(buf, ' ')
+		}
+		if len(buf) > 0 {
+			flush(false)
+		}
+		count = 0
+	}
+
+	if p.rider.Pos().Name() != text.P {
+		p.WritePara(_s)
+	} else {
+		p.fm.writeAttr()
+		if a := p.fm.attr.Fit(text.Span); a != nil {
+			p.rider.WritePos(New(text.Span))
+			p.rider.Attr(text.StyleName, a.Name())
+		}
+		s := []rune(_s)
+		br := false
+		for pos := 0; pos < len(s) && s[pos] != 0; {
+			switch s[pos] {
+			case ' ':
+				count++
+			case '\n':
+				grow()
+				p.rider.Write(New(text.LineBreak))
+			case '\r':
+				grow()
+				if p.fm.attr.Fit(text.Span) != nil {
+					p.rider.Pos(p.rider.Pos().Parent())
+				}
+				for pos = pos + 1; pos < len(s); pos++ {
+					buf = append(buf, s[pos])
+				}
+				p.WritePara(string(buf))
+				pos--
+				br = true
+			case '\t':
+				grow()
+				p.rider.Write(New(text.Tab))
+			default:
+				if count > 1 {
+					flush(true)
+				} else if count == 1 {
+					buf = append(buf, ' ')
+				}
+				count = 0
+				buf = append(buf, s[pos])
+			}
+			pos++
+		}
+		if !br {
+			grow()
+			if p.fm.attr.Fit(text.Span) != nil {
+				p.rider.Pos(p.rider.Pos().Parent())
+			}
+		}
+	}
+}

+ 19 - 5
mappers/table.go

@@ -23,10 +23,6 @@ func (t *TableMapper) Ready() bool {
 	return t.fm != nil && t.fm.ready
 }
 
-func (t *TableMapper) rider() model.Writer {
-	return t.fm.rider
-}
-
 func (t *TableMapper) newWriter(old ...model.Writer) model.Writer {
 	return t.fm.m.NewWriter(old...)
 }
@@ -42,7 +38,8 @@ func (t *TableMapper) Write(name string, rows, cols int) {
 	t.fm.writeAttr()
 	this := &Table{Rows: rows, Columns: cols}
 	t.List[name] = this
-	wr := t.newWriter(t.rider())
+	wr := t.newWriter()
+	wr.Pos(t.fm.root)
 	this.Root = wr.WritePos(New(table.Table))
 	wr.Attr(table.Name, name)
 	for i := 0; i < this.Columns; i++ {
@@ -112,3 +109,20 @@ func (t *TableMapper) WriteCells(this *Table, _row int, cells int) {
 		wr.Write(cell)
 	}
 }
+
+func (t *TableMapper) Span(this *Table, row, col int, rowspan, colspan int) {
+	assert.For(t.Ready(), 20)
+	assert.For(rowspan > 0, 21)
+	assert.For(colspan > 0, 22)
+	wr := t.newWriter()
+	wr.Pos(this.cellCache[row][col])
+	wr.Attr(table.NumberRowsSpanned, rowspan)
+	wr.Attr(table.NumberColumnsSpanned, colspan)
+}
+
+func (t *TableMapper) Pos(this *Table, row, col int) *ParaMapper {
+	ret := new(ParaMapper)
+	ret.ConnectTo(t.fm)
+	ret.rider.Pos(this.cellCache[row][col])
+	return ret
+}

+ 2 - 0
odf_test.go

@@ -88,6 +88,8 @@ func TestTables(t *testing.T) {
 		tt := tm.List["test"]
 		tm.WriteColumns(tt, 4)
 		tm.WriteRows(tt, 3)
+		tm.Span(tt, 0, 0, 1, 3)
+		tm.Pos(tt, 0, 0).WritePara("Hello, table world!")
 	}
 	{
 		output, _ := os.OpenFile("test3.odf", os.O_CREATE|os.O_WRONLY, 0666)

+ 9 - 1
xmlns/table/t.go

@@ -2,6 +2,7 @@ package table
 
 import (
 	"odf/model"
+	"odf/xmlns"
 )
 
 const (
@@ -12,5 +13,12 @@ const (
 )
 
 const (
-	Name model.AttrName = "table:name"
+	Name                 model.AttrName = "table:name"
+	NumberColumnsSpanned                = "table:number-columns-spanned"
+	NumberRowsSpanned                   = "table:number-rows-spanned"
 )
+
+func init() {
+	xmlns.Typed[NumberColumnsSpanned] = xmlns.INT
+	xmlns.Typed[NumberRowsSpanned] = xmlns.INT
+}