fmt.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package mappers
  2. import (
  3. "github.com/kpmy/odf/mappers/attr"
  4. "github.com/kpmy/odf/model"
  5. "github.com/kpmy/odf/xmlns"
  6. "github.com/kpmy/odf/xmlns/office"
  7. "github.com/kpmy/ypk/assert"
  8. "github.com/kpmy/ypk/halt"
  9. "reflect"
  10. )
  11. //New is shortcut for model.ModelFactory or wrapper
  12. var New func(name model.LeafName) model.Leaf
  13. //Formatter holds model of document and manages attributes and simple text mapper
  14. //Main goal of Formatter conception is setting attributes before writing content. This allows to optimize the real attributes storage in document model
  15. //Anyway, document model can be modified with any other tools, Formatter is my vision of this kind of tools.
  16. //Represents Mapper in CRM pattern
  17. type Formatter struct {
  18. m model.Model
  19. MimeType xmlns.Mime
  20. attr *Attr
  21. root model.Node //root of document content, not model
  22. ready bool
  23. defaultParaMapper *ParaMapper
  24. }
  25. //ConnectTo document model, for now it can be only newly created model, Formatter does not make existing content analise
  26. func (f *Formatter) ConnectTo(m model.Model) {
  27. assert.For(m.Root().NofChild() == 0, 20, "only new documents for now")
  28. f.m = m
  29. f.attr = &Attr{}
  30. f.ready = false
  31. }
  32. //Init document model with empty content basing on MimeType
  33. func (f *Formatter) Init() {
  34. assert.For(f.MimeType != "", 20)
  35. wr := f.m.NewWriter()
  36. wr.Pos(f.m.Root())
  37. wr.Write(New(office.DocumentMeta))
  38. f.attr.Init(f.m)
  39. wr.WritePos(New(office.DocumentContent))
  40. wr.Attr(office.Version, "1.0")
  41. wr.Write(f.attr.ffdc)
  42. wr.Write(f.attr.asc)
  43. wr.WritePos(New(office.Body))
  44. switch f.MimeType {
  45. case xmlns.MimeText:
  46. f.root = wr.WritePos(New(office.Text)).(model.Node)
  47. case xmlns.MimeSpreadsheet:
  48. f.root = wr.WritePos(New(office.Spreadsheet)).(model.Node)
  49. default:
  50. halt.As(100, f.MimeType)
  51. }
  52. f.defaultParaMapper = new(ParaMapper)
  53. f.defaultParaMapper.ConnectTo(f)
  54. f.ready = true
  55. }
  56. //WritePara writes text in new paragraph with the most latest text and paragraph attributes set
  57. func (f *Formatter) WritePara(s string) {
  58. assert.For(f.ready, 20)
  59. f.defaultParaMapper.WritePara(s)
  60. }
  61. //WriteLn writes a line break
  62. func (f *Formatter) WriteLn() {
  63. f.WriteString("\n")
  64. }
  65. //WriteString writes a text within existing paragraph or creates new paragraph if symbol \r met
  66. func (f *Formatter) WriteString(s string) {
  67. assert.For(f.ready, 20)
  68. f.defaultParaMapper.WriteString(s)
  69. }
  70. //SetAttr sets any type of attributes to be used in future, only one instance of any typed attributes supported. Attributes are flushed only when real content is written. SetAttr can accept nil value for dropping all attributes
  71. func (f *Formatter) SetAttr(a attr.Attributes) *Formatter {
  72. assert.For(f.ready, 20)
  73. if a != nil {
  74. n := reflect.TypeOf(a).String()
  75. if old := f.attr.OldAttr(a); old != nil {
  76. f.attr.current[n] = old
  77. } else {
  78. c := f.attr.current[n]
  79. if (c == nil) || !c.Equal(a) {
  80. f.attr.stored = false
  81. f.attr.current[n] = a
  82. }
  83. }
  84. } else {
  85. f.attr.reset()
  86. }
  87. return f
  88. }
  89. //RegisterFont sets the Font Face Declaration item, name later can be used in attr.TextAttributes
  90. func (f *Formatter) RegisterFont(name, fontface string) {
  91. f.attr.RegisterFont(name, fontface)
  92. }
  93. //Sets the default attributes, that will be used by odf consumer to display non-attributed content (after SetAttr(nil))
  94. func (f *Formatter) SetDefaults(a ...attr.Attributes) {
  95. f.attr.SetDefaults(a...)
  96. }
  97. func init() {
  98. New = func(n model.LeafName) model.Leaf {
  99. return model.LeafFactory(n)
  100. }
  101. }