Ver Fonte

записал простой текст

kpmy há 10 anos atrás
pai
commit
3402f4caaf
8 ficheiros alterados com 124 adições e 8 exclusões
  1. 4 4
      generators/gen.go
  2. 71 0
      mappers/fmt.go
  3. 15 0
      model/stub/simple_nodes.go
  4. 7 4
      model/stub/simple_tree.go
  5. 1 0
      model/tree.go
  6. 12 0
      odf_test.go
  7. 0 0
      xmlns/office/o.go
  8. 14 0
      xmlns/text/t.go

+ 4 - 4
generators/gen.go

@@ -26,9 +26,10 @@ type Manifest struct {
 	Entries []Entry `xml:"manifest:file-entry"`
 }
 
-func (m *Manifest) init() {
+func (m *Manifest) init(mimetype xmlns.Mime) {
 	m.XMLName.Local = "manifest:manifest"
 	m.NS = urn.Manifest
+	m.Entries = append(m.Entries, Entry{MediaType: string(mimetype), FullPath: "/"})
 }
 
 func docParts(m model.Model) (ret Parts) {
@@ -57,13 +58,12 @@ func docParts(m model.Model) (ret Parts) {
 
 func Generate(m model.Model, out io.Writer, mimetype xmlns.Mime) {
 	z := zip.NewWriter(out)
-	mime := &zip.FileHeader{Name: xmlns.Mimetype, Method: zip.Store}
+	mime := &zip.FileHeader{Name: xmlns.Mimetype, Method: zip.Store} //файл mimetype не надо сжимать, режим Store
 	if w, err := z.CreateHeader(mime); err == nil {
 		bytes.NewBufferString(string(mimetype)).WriteTo(w)
 	}
 	manifest := &Manifest{}
-	manifest.init()
-	manifest.Entries = append(manifest.Entries, Entry{MediaType: string(mimetype), FullPath: "/"})
+	manifest.init(mimetype)
 	for k, v := range docParts(m) {
 		if w, err := z.Create(k); err == nil {
 			v.WriteTo(w)

+ 71 - 0
mappers/fmt.go

@@ -4,6 +4,7 @@ import (
 	"odf/model"
 	"odf/xmlns"
 	"odf/xmlns/office"
+	"odf/xmlns/text"
 	"ypk/assert"
 )
 
@@ -42,6 +43,76 @@ func (f *Formatter) Init() {
 	f.ready = true
 }
 
+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.Paragraph {
+		f.rider.Pos(f.text)
+	}
+	f.rider.WritePos(New(text.Paragraph))
+	f.writeAttr()
+	f.WriteString(s)
+}
+
+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()
+			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.Paragraph {
+		f.WritePara(_s)
+	} else {
+		f.writeAttr()
+		s := []rune(_s)
+		br := false
+		for pos := 0; pos < len(s) && s[pos] != 0; {
+			switch s[pos] {
+			case ' ':
+				count++
+			default:
+				if count > 1 {
+					flush(true)
+				} else if count == 1 {
+					buf = append(buf, ' ')
+				}
+				count = 0
+				buf = append(buf, s[pos])
+			}
+			pos++
+		}
+		if !br {
+			grow()
+		}
+	}
+}
+
 func init() {
 	New = model.LeafFactory
 }

+ 15 - 0
model/stub/simple_nodes.go

@@ -33,6 +33,14 @@ func (r *root) NofChild() int {
 	return r.inner.NofChild()
 }
 
+type text struct {
+	data string
+}
+
+func (t *text) Name() model.LeafName { panic(100) }
+
+func (t *text) Attr(model.AttrName, ...model.Attribute) model.Attribute { panic(100) }
+
 func (r *root) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
 	start.Name.Local = string(r.inner.Name())
 
@@ -79,6 +87,13 @@ func lf() func(x model.LeafName) model.Leaf {
 	}
 }
 
+func tf() func(s string) model.Leaf {
+	return func(s string) model.Leaf {
+		return &text{data: s}
+	}
+}
+
 func init() {
 	model.LeafFactory = lf()
+	model.Text = tf()
 }

+ 7 - 4
model/stub/simple_tree.go

@@ -6,7 +6,6 @@ package stub
 
 import (
 	"encoding/xml"
-	"fmt"
 	"odf/model"
 	"ypk/assert"
 )
@@ -55,7 +54,6 @@ func (n *sn) init() {
 }
 
 func (n *sn) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
-	fmt.Println(n.name)
 	start.Name.Local = string(n.name)
 	for k, v := range n.attr {
 		a, err := v.(xml.MarshalerAttr).MarshalXMLAttr(xml.Name{Local: string(k)})
@@ -63,8 +61,13 @@ func (n *sn) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
 		start.Attr = append(start.Attr, a)
 	}
 	e.EncodeToken(start)
-	for _, v := range n.children {
-		err = e.EncodeElement(v, xml.StartElement{Name: xml.Name{Local: string(v.Name())}})
+	for _, _v := range n.children {
+		switch v := _v.(type) {
+		case *text:
+			err = e.EncodeToken(xml.CharData(v.data))
+		default:
+			err = e.EncodeElement(v, xml.StartElement{Name: xml.Name{Local: string(v.Name())}})
+		}
 		assert.For(err == nil, 30, err)
 	}
 	err = e.EncodeToken(start.End())

+ 1 - 0
model/tree.go

@@ -40,3 +40,4 @@ type Writer interface {
 }
 
 var ModelFactory func() Model
+var Text func(s string) Leaf

+ 12 - 0
odf_test.go

@@ -39,3 +39,15 @@ func TestGenerators(t *testing.T) {
 	generators.Generate(m, output, fm.MimeType)
 	output.Close()
 }
+
+func TestStructure(t *testing.T) {
+	output, _ := os.OpenFile("test0.odf", os.O_CREATE|os.O_WRONLY, 0666)
+	m := model.ModelFactory()
+	fm := &mappers.Formatter{}
+	fm.ConnectTo(m)
+	fm.MimeType = xmlns.MimeText
+	fm.Init()
+	fm.WriteString(`Hello, World!`)
+	generators.Generate(m, output, fm.MimeType)
+	output.Close()
+}

+ 0 - 0
xmlns/office/office.go → xmlns/office/o.go


+ 14 - 0
xmlns/text/t.go

@@ -0,0 +1,14 @@
+package text
+
+import (
+	"odf/model"
+)
+
+const (
+	Paragraph model.LeafName = "text:p"
+	S         model.LeafName = "text:s"
+)
+
+const (
+	C model.AttrName = "text:c"
+)