ritsu 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. data/README.md +95 -95
  2. data/bin/define_cpp_string +54 -54
  3. data/bin/ritsu +31 -31
  4. data/lib/ritsu.rb +16 -16
  5. data/lib/ritsu/block.rb +258 -258
  6. data/lib/ritsu/ext/cuda.rb +5 -5
  7. data/lib/ritsu/ext/cuda/external_library.rb +15 -15
  8. data/lib/ritsu/ext/cuda/project.rb +31 -31
  9. data/lib/ritsu/ext/cuda/src_files/cu_file.rb +46 -46
  10. data/lib/ritsu/ext/cuda/src_files/target_cmake_lists.rb +110 -110
  11. data/lib/ritsu/ext/cuda/target.rb +16 -16
  12. data/lib/ritsu/ext/cuda/targets/library.rb +16 -16
  13. data/lib/ritsu/ext/fake_install.rb +2 -2
  14. data/lib/ritsu/ext/fake_install/project.rb +16 -16
  15. data/lib/ritsu/ext/fake_install/src_files/project_cmake_lists.rb +45 -45
  16. data/lib/ritsu/ext/glsl.rb +1 -1
  17. data/lib/ritsu/ext/glsl/src_files/frag_file.rb +70 -70
  18. data/lib/ritsu/ext/glsl/src_files/vert_file.rb +70 -70
  19. data/lib/ritsu/ext/qt.rb +4 -4
  20. data/lib/ritsu/ext/qt/project.rb +47 -47
  21. data/lib/ritsu/ext/qt/src_files/header_file.rb +60 -60
  22. data/lib/ritsu/ext/qt/src_files/target_cmake_lists.rb +106 -106
  23. data/lib/ritsu/ext/qt/src_files/ui_file.rb +46 -46
  24. data/lib/ritsu/ext/test_case.rb +19 -19
  25. data/lib/ritsu/external_library.rb +46 -46
  26. data/lib/ritsu/project.rb +93 -93
  27. data/lib/ritsu/project_generator.rb +33 -33
  28. data/lib/ritsu/project_generators/default_generator.rb +72 -72
  29. data/lib/ritsu/project_generators/default_generator_files/Thorfile.erb +8 -8
  30. data/lib/ritsu/project_generators/default_generator_files/meta/project.rb.erb +10 -10
  31. data/lib/ritsu/src_file.rb +79 -79
  32. data/lib/ritsu/src_files.rb +12 -12
  33. data/lib/ritsu/src_files/cpp_file.rb +43 -43
  34. data/lib/ritsu/src_files/executable_cmake_lists.rb +39 -39
  35. data/lib/ritsu/src_files/header_file.rb +60 -60
  36. data/lib/ritsu/src_files/project_cmake_lists.rb +133 -133
  37. data/lib/ritsu/src_files/project_config_header_file.rb +14 -14
  38. data/lib/ritsu/src_files/project_config_header_template_file.rb +44 -44
  39. data/lib/ritsu/src_files/shared_library_cmake_lists.rb +39 -39
  40. data/lib/ritsu/src_files/static_library_cmake_lists.rb +39 -39
  41. data/lib/ritsu/src_files/target_cmake_lists.rb +189 -189
  42. data/lib/ritsu/src_files/templated_src_file.rb +47 -47
  43. data/lib/ritsu/src_files/unit.rb +32 -32
  44. data/lib/ritsu/target.rb +154 -154
  45. data/lib/ritsu/targets.rb +3 -3
  46. data/lib/ritsu/targets/executable.rb +44 -44
  47. data/lib/ritsu/targets/library.rb +29 -29
  48. data/lib/ritsu/targets/shared_library.rb +38 -38
  49. data/lib/ritsu/targets/static_library.rb +32 -32
  50. data/lib/ritsu/template.rb +68 -68
  51. data/lib/ritsu/template_policies.rb +132 -132
  52. data/lib/ritsu/test_helpers.rb +123 -123
  53. data/lib/ritsu/thors/default_thor.rb +1 -1
  54. data/lib/ritsu/utility.rb +7 -7
  55. data/lib/ritsu/utility/accessors.rb +29 -29
  56. data/lib/ritsu/utility/check_upon_add_set.rb +34 -34
  57. data/lib/ritsu/utility/file_robot.rb +128 -128
  58. data/lib/ritsu/utility/files.rb +12 -12
  59. data/lib/ritsu/utility/instance_dependencies.rb +112 -112
  60. data/lib/ritsu/utility/instance_set.rb +28 -28
  61. data/lib/ritsu/utility/platform.rb +20 -20
  62. data/lib/ritsu/utility/simple_io.rb +64 -64
  63. data/lib/ritsu/utility/single_instance.rb +33 -33
  64. data/lib/ritsu/utility/strings.rb +40 -40
  65. data/test/ritsu/block_test.rb +196 -196
  66. data/test/ritsu/ext/cuda/src_files/cuda_static_library_cmake_lists_test.rb +63 -63
  67. data/test/ritsu/external_library_test.rb +41 -41
  68. data/test/ritsu/project_generators/default_generator_test.rb +34 -34
  69. data/test/ritsu/project_test.rb +127 -127
  70. data/test/ritsu/src_file_test.rb +69 -69
  71. data/test/ritsu/src_files/cpp_file_test.rb +42 -42
  72. data/test/ritsu/src_files/executable_cmake_lists_test.rb +92 -92
  73. data/test/ritsu/src_files/header_file_test.rb +57 -57
  74. data/test/ritsu/src_files/project_cmake_lists_test.rb +159 -159
  75. data/test/ritsu/src_files/shared_library_cmake_lists_test.rb +54 -54
  76. data/test/ritsu/src_files/static_library_cmake_lists_test.rb +54 -54
  77. data/test/ritsu/src_files/target_cmake_lists_test.rb +15 -15
  78. data/test/ritsu/target_test.rb +105 -105
  79. data/test/ritsu/targets/executable_test.rb +10 -10
  80. data/test/ritsu/targets/shared_library_test.rb +10 -10
  81. data/test/ritsu/targets/static_library_test.rb +10 -10
  82. data/test/ritsu/utility/accessors_test.rb +14 -14
  83. data/test/ritsu/utility/check_upon_add_set_test.rb +31 -31
  84. data/test/ritsu/utility/file_robot_test.rb +175 -175
  85. data/test/ritsu/utility/strings_test.rb +28 -28
  86. data/test/test_helpers.rb +3 -3
  87. metadata +72 -124
  88. data/Thorfile +0 -104
  89. data/VERSION +0 -1
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/targets/executable')
2
- require File.expand_path(File.dirname(__FILE__) + '/targets/library')
3
- require File.expand_path(File.dirname(__FILE__) + '/targets/static_library')
1
+ require File.expand_path(File.dirname(__FILE__) + '/targets/executable')
2
+ require File.expand_path(File.dirname(__FILE__) + '/targets/library')
3
+ require File.expand_path(File.dirname(__FILE__) + '/targets/static_library')
4
4
  require File.expand_path(File.dirname(__FILE__) + '/targets/shared_library')
@@ -1,45 +1,45 @@
1
- require 'rubygems'
2
- require 'active_support'
3
- require File.expand_path(File.dirname(__FILE__) + '/../target')
4
- require File.expand_path(File.dirname(__FILE__) + '/../utility/instance_set')
5
- require File.expand_path(File.dirname(__FILE__) + '/../src_files/executable_cmake_lists')
6
-
7
- module Ritsu::Targets
8
- class Executable < Ritsu::Target
9
- attr_reader :cmake_lists
10
-
11
- def initialize(name, options={})
12
- super(name, options)
13
- @cmake_lists = Ritsu::SrcFiles::ExecutableCmakeLists.new(self)
14
- end
15
-
16
- def can_be_depended_on?
17
- false
18
- end
19
-
20
- def executable?
21
- true
22
- end
23
-
24
- def shared_library?
25
- false
26
- end
27
-
28
- def static_library?
29
- false
30
- end
31
-
32
- def library?
33
- false
34
- end
35
- end
36
- end
37
-
38
- module Ritsu
39
- class Project
40
- def add_executable(name)
41
- executable = Ritsu::Targets::Executable.new(name, :project=>self)
42
- yield executable if block_given?
43
- end
44
- end
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require File.expand_path(File.dirname(__FILE__) + '/../target')
4
+ require File.expand_path(File.dirname(__FILE__) + '/../utility/instance_set')
5
+ require File.expand_path(File.dirname(__FILE__) + '/../src_files/executable_cmake_lists')
6
+
7
+ module Ritsu::Targets
8
+ class Executable < Ritsu::Target
9
+ attr_reader :cmake_lists
10
+
11
+ def initialize(name, options={})
12
+ super(name, options)
13
+ @cmake_lists = Ritsu::SrcFiles::ExecutableCmakeLists.new(self)
14
+ end
15
+
16
+ def can_be_depended_on?
17
+ false
18
+ end
19
+
20
+ def executable?
21
+ true
22
+ end
23
+
24
+ def shared_library?
25
+ false
26
+ end
27
+
28
+ def static_library?
29
+ false
30
+ end
31
+
32
+ def library?
33
+ false
34
+ end
35
+ end
36
+ end
37
+
38
+ module Ritsu
39
+ class Project
40
+ def add_executable(name)
41
+ executable = Ritsu::Targets::Executable.new(name, :project=>self)
42
+ yield executable if block_given?
43
+ end
44
+ end
45
45
  end
@@ -1,29 +1,29 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../target")
2
- require File.expand_path(File.dirname(__FILE__) + "/../utility/accessors")
3
-
4
- module Ritsu::Targets
5
- class Library < Ritsu::Target
6
- include Ritsu::Utility::Accessors
7
-
8
- attr_accessor :cmake_depend_script
9
- attr_method :cmake_depend_script
10
-
11
- def initialize(name, options={})
12
- options = {:cmake_depend_script => ""}.merge(options)
13
- super(name, options)
14
- @cmake_depend_script = options[:cmake_depend_script]
15
- end
16
-
17
- def can_be_depended_on?
18
- true
19
- end
20
-
21
- def executable?
22
- false
23
- end
24
-
25
- def library?
26
- true
27
- end
28
- end
29
- end
1
+ require File.expand_path(File.dirname(__FILE__) + "/../target")
2
+ require File.expand_path(File.dirname(__FILE__) + "/../utility/accessors")
3
+
4
+ module Ritsu::Targets
5
+ class Library < Ritsu::Target
6
+ include Ritsu::Utility::Accessors
7
+
8
+ attr_accessor :cmake_depend_script
9
+ attr_method :cmake_depend_script
10
+
11
+ def initialize(name, options={})
12
+ options = {:cmake_depend_script => ""}.merge(options)
13
+ super(name, options)
14
+ @cmake_depend_script = options[:cmake_depend_script]
15
+ end
16
+
17
+ def can_be_depended_on?
18
+ true
19
+ end
20
+
21
+ def executable?
22
+ false
23
+ end
24
+
25
+ def library?
26
+ true
27
+ end
28
+ end
29
+ end
@@ -1,39 +1,39 @@
1
- require 'rubygems'
2
- require 'active_support'
3
- require File.expand_path(File.dirname(__FILE__) + '/library')
4
- require File.expand_path(File.dirname(__FILE__) + '/../utility/instance_set')
5
- require File.expand_path(File.dirname(__FILE__) + '/../src_files/shared_library_cmake_lists')
6
-
7
- module Ritsu::Targets
8
- class SharedLibrary < Ritsu::Targets::Library
9
- attr_reader :cmake_lists
10
-
11
- def initialize(name, options={})
12
- super(name, options)
13
- initialize_cmake_lists
14
- end
15
-
16
- protected
17
- def initialize_cmake_lists
18
- @cmake_lists = Ritsu::SrcFiles::SharedLibraryCmakeLists.new(self)
19
- end
20
-
21
- public
22
- def shared_library?
23
- true
24
- end
25
-
26
- def static_library?
27
- false
28
- end
29
- end
30
- end
31
-
32
- module Ritsu
33
- class Project
34
- def add_shared_library(name)
35
- shared_library = Ritsu::Targets::SharedLibrary.new(name, :project=>self)
36
- yield shared_library if block_given?
37
- end
38
- end
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require File.expand_path(File.dirname(__FILE__) + '/library')
4
+ require File.expand_path(File.dirname(__FILE__) + '/../utility/instance_set')
5
+ require File.expand_path(File.dirname(__FILE__) + '/../src_files/shared_library_cmake_lists')
6
+
7
+ module Ritsu::Targets
8
+ class SharedLibrary < Ritsu::Targets::Library
9
+ attr_reader :cmake_lists
10
+
11
+ def initialize(name, options={})
12
+ super(name, options)
13
+ initialize_cmake_lists
14
+ end
15
+
16
+ protected
17
+ def initialize_cmake_lists
18
+ @cmake_lists = Ritsu::SrcFiles::SharedLibraryCmakeLists.new(self)
19
+ end
20
+
21
+ public
22
+ def shared_library?
23
+ true
24
+ end
25
+
26
+ def static_library?
27
+ false
28
+ end
29
+ end
30
+ end
31
+
32
+ module Ritsu
33
+ class Project
34
+ def add_shared_library(name)
35
+ shared_library = Ritsu::Targets::SharedLibrary.new(name, :project=>self)
36
+ yield shared_library if block_given?
37
+ end
38
+ end
39
39
  end
@@ -1,33 +1,33 @@
1
- require 'rubygems'
2
- require 'active_support'
3
- require File.expand_path(File.dirname(__FILE__) + '/library')
4
- require File.expand_path(File.dirname(__FILE__) + '/../utility/instance_set')
5
- require File.expand_path(File.dirname(__FILE__) + '/../src_files/static_library_cmake_lists')
6
-
7
- module Ritsu::Targets
8
- class StaticLibrary < Ritsu::Targets::Library
9
- attr_reader :cmake_lists
10
-
11
- def initialize(name, options={})
12
- super(name, options)
13
- @cmake_lists = Ritsu::SrcFiles::StaticLibraryCmakeLists.new(self)
14
- end
15
-
16
- def shared_library?
17
- false
18
- end
19
-
20
- def static_library?
21
- true
22
- end
23
- end
24
- end
25
-
26
- module Ritsu
27
- class Project
28
- def add_static_library(name)
29
- static_library = Ritsu::Targets::StaticLibrary.new(name, :project=>self)
30
- yield static_library if block_given?
31
- end
32
- end
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require File.expand_path(File.dirname(__FILE__) + '/library')
4
+ require File.expand_path(File.dirname(__FILE__) + '/../utility/instance_set')
5
+ require File.expand_path(File.dirname(__FILE__) + '/../src_files/static_library_cmake_lists')
6
+
7
+ module Ritsu::Targets
8
+ class StaticLibrary < Ritsu::Targets::Library
9
+ attr_reader :cmake_lists
10
+
11
+ def initialize(name, options={})
12
+ super(name, options)
13
+ @cmake_lists = Ritsu::SrcFiles::StaticLibraryCmakeLists.new(self)
14
+ end
15
+
16
+ def shared_library?
17
+ false
18
+ end
19
+
20
+ def static_library?
21
+ true
22
+ end
23
+ end
24
+ end
25
+
26
+ module Ritsu
27
+ class Project
28
+ def add_static_library(name)
29
+ static_library = Ritsu::Targets::StaticLibrary.new(name, :project=>self)
30
+ yield static_library if block_given?
31
+ end
32
+ end
33
33
  end
@@ -1,69 +1,69 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/block')
2
-
3
- module Ritsu
4
- class Template
5
- include BlockMixin
6
-
7
- def initialize(id = nil, options = {})
8
- initialize_block_mixin(id, options)
9
- end
10
-
11
- ##
12
- # @return (Template) the first child template with the given ID.
13
- # nil if there is no such child template.
14
- def child_template_with_id(id)
15
- contents.each do |content|
16
- if content.kind_of?(Template) and content.id == id
17
- return content
18
- end
19
- end
20
- return nil
21
- end
22
-
23
- ##
24
- # @return (Template) the position of the child template with the given ID in the contents array.
25
- # nil if there is no such child template.
26
- def child_template_with_id_position(id)
27
- contents.length.times do |i|
28
- if contents[i].kind_of?(Template) and contents[i].id == id
29
- return i
30
- end
31
- end
32
- return nil
33
- end
34
-
35
- def child_templates
36
- contents.select {|x| x.kind_of?(Template)}
37
- end
38
-
39
- def create_block(options={})
40
- options = {}.merge(options)
41
- options[:local_indentation] = local_indentation
42
- block = Block.new(id, options)
43
- contents.each do |content|
44
- if !content.kind_of?(Template)
45
- block.contents << content
46
- else
47
- block.contents << content.create_block(options)
48
- end
49
- end
50
- block
51
- end
52
-
53
- def update_block(block, options={})
54
- raise NotImplementedError.new
55
- end
56
-
57
- def add_template(template)
58
- add_block_structure(template)
59
- end
60
-
61
- def add_content(content)
62
- if content.kind_of?(Template)
63
- add_template(content)
64
- else
65
- add_line_or_other_content(content)
66
- end
67
- end
68
- end
1
+ require File.expand_path(File.dirname(__FILE__) + '/block')
2
+
3
+ module Ritsu
4
+ class Template
5
+ include BlockMixin
6
+
7
+ def initialize(id = nil, options = {})
8
+ initialize_block_mixin(id, options)
9
+ end
10
+
11
+ ##
12
+ # @return (Template) the first child template with the given ID.
13
+ # nil if there is no such child template.
14
+ def child_template_with_id(id)
15
+ contents.each do |content|
16
+ if content.kind_of?(Template) and content.id == id
17
+ return content
18
+ end
19
+ end
20
+ return nil
21
+ end
22
+
23
+ ##
24
+ # @return (Template) the position of the child template with the given ID in the contents array.
25
+ # nil if there is no such child template.
26
+ def child_template_with_id_position(id)
27
+ contents.length.times do |i|
28
+ if contents[i].kind_of?(Template) and contents[i].id == id
29
+ return i
30
+ end
31
+ end
32
+ return nil
33
+ end
34
+
35
+ def child_templates
36
+ contents.select {|x| x.kind_of?(Template)}
37
+ end
38
+
39
+ def create_block(options={})
40
+ options = {}.merge(options)
41
+ options[:local_indentation] = local_indentation
42
+ block = Block.new(id, options)
43
+ contents.each do |content|
44
+ if !content.kind_of?(Template)
45
+ block.contents << content
46
+ else
47
+ block.contents << content.create_block(options)
48
+ end
49
+ end
50
+ block
51
+ end
52
+
53
+ def update_block(block, options={})
54
+ raise NotImplementedError.new
55
+ end
56
+
57
+ def add_template(template)
58
+ add_block_structure(template)
59
+ end
60
+
61
+ def add_content(content)
62
+ if content.kind_of?(Template)
63
+ add_template(content)
64
+ else
65
+ add_line_or_other_content(content)
66
+ end
67
+ end
68
+ end
69
69
  end
@@ -1,133 +1,133 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/template')
2
-
3
- module Ritsu::TemplatePolicies
4
- module StrictBlockMatchingButLeaveUserTextBe
5
- def update_block(block, options={})
6
- child_blocks = block.child_blocks
7
- index = 0
8
- child_templates.each do |child_template|
9
- while index < child_blocks.length && child_blocks[index].id != child_template.id
10
- index += 1
11
- end
12
- if index >= child_blocks.length
13
- if child_blocks.select {|x| x.id == child_template.id}
14
- raise ArgumentError.new("block with id '#{child_template.id}' appears out of order")
15
- else
16
- raise ArgumentError.new("cannot find block with id '#{child_template.id}'")
17
- end
18
- end
19
- child_template.update_block(child_blocks[index])
20
- index += 1
21
- end
22
- end
23
- end
24
-
25
- module Blank
26
- def update_block(block, options={})
27
- block.contents.clear
28
- end
29
- end
30
-
31
- module DoNotUpdate
32
- def update_block(block, options={})
33
- end
34
- end
35
-
36
- module Overwrite
37
- def overwrite_block(block, options={})
38
- block.clear_contents
39
- contents.each do |content|
40
- if !content.kind_of?(Ritsu::Template)
41
- block.add_content content
42
- else
43
- block.add_content(content.create_block(options))
44
- end
45
- end
46
- end
47
-
48
- def update_block(block, options={})
49
- overwrite_block(block, options)
50
- end
51
- end
52
-
53
- module FlexibleBlockMatching
54
- ##
55
- # @param (Block) a block
56
- # @return (Hash) a hash mapping each child template to a child block with the same id.
57
- # If there is no such child block, the child template is mapped to nil.
58
- def match_child_blocks(block)
59
- child_blocks = block.child_blocks
60
- matching_child_blocks = {}
61
- child_templates.each do |child_template|
62
- matching = nil
63
- child_blocks.each do |child_block|
64
- if child_template.id == child_block.id
65
- matching = child_block
66
- break
67
- end
68
- end
69
- child_blocks.delete(matching) unless matching.nil?
70
- matching_child_blocks[child_template] = matching
71
- end
72
- matching_child_blocks
73
- end
74
- end
75
-
76
- module FlexibleBlockMatchingAndCreateMissingBlocksButIgnoreUserText
77
- include FlexibleBlockMatching
78
-
79
- def update_block(block, options={})
80
- matching_child_blocks = match_child_blocks(block)
81
-
82
- block.contents.clear
83
- contents.each do |content|
84
- if content.kind_of?(Template)
85
- if matching_child_blocks[content].nil?
86
- block.contents << content.create_block(options)
87
- else
88
- matching = matching_child_blocks[content]
89
- content.update_block(matching)
90
- block.contents << matching
91
- end
92
- else
93
- block.contents << content
94
- end
95
- end
96
- end
97
- end
98
-
99
- module FlexibleBlockMatchingAndCreateMissingBlockButLeaveUserTextBe
100
- include FlexibleBlockMatching
101
-
102
- def update_block(block, options={})
103
- options = {:new_line_after_block => true}.merge(options)
104
- matching_child_blocks = match_child_blocks(block)
105
-
106
- child_templates.each do |child_template|
107
- if matching_child_blocks[child_template].nil?
108
- new_block = child_template.create_block(options)
109
-
110
- position = position_to_insert(block, new_block)
111
- if position
112
- block.contents.insert(position, new_block)
113
- if options[:new_line_after_block]
114
- block.contents.insert(position+1, "")
115
- end
116
- else
117
- raise ArgumentError.new("cannot find position to insert '#{new_block.name}'")
118
- end
119
- else
120
- matching = matching_child_blocks[child_template]
121
- child_template.update_block(matching)
122
- end
123
- end
124
- end
125
-
126
- ##
127
- # @return (Integer) the position in block.contents to
128
- # insert the given new block
129
- def position_to_insert(block, new_block)
130
- raise NotImplementedError
131
- end
132
- end
1
+ require File.expand_path(File.dirname(__FILE__) + '/template')
2
+
3
+ module Ritsu::TemplatePolicies
4
+ module StrictBlockMatchingButLeaveUserTextBe
5
+ def update_block(block, options={})
6
+ child_blocks = block.child_blocks
7
+ index = 0
8
+ child_templates.each do |child_template|
9
+ while index < child_blocks.length && child_blocks[index].id != child_template.id
10
+ index += 1
11
+ end
12
+ if index >= child_blocks.length
13
+ if child_blocks.select {|x| x.id == child_template.id}
14
+ raise ArgumentError.new("block with id '#{child_template.id}' appears out of order")
15
+ else
16
+ raise ArgumentError.new("cannot find block with id '#{child_template.id}'")
17
+ end
18
+ end
19
+ child_template.update_block(child_blocks[index])
20
+ index += 1
21
+ end
22
+ end
23
+ end
24
+
25
+ module Blank
26
+ def update_block(block, options={})
27
+ block.contents.clear
28
+ end
29
+ end
30
+
31
+ module DoNotUpdate
32
+ def update_block(block, options={})
33
+ end
34
+ end
35
+
36
+ module Overwrite
37
+ def overwrite_block(block, options={})
38
+ block.clear_contents
39
+ contents.each do |content|
40
+ if !content.kind_of?(Ritsu::Template)
41
+ block.add_content content
42
+ else
43
+ block.add_content(content.create_block(options))
44
+ end
45
+ end
46
+ end
47
+
48
+ def update_block(block, options={})
49
+ overwrite_block(block, options)
50
+ end
51
+ end
52
+
53
+ module FlexibleBlockMatching
54
+ ##
55
+ # @param (Block) a block
56
+ # @return (Hash) a hash mapping each child template to a child block with the same id.
57
+ # If there is no such child block, the child template is mapped to nil.
58
+ def match_child_blocks(block)
59
+ child_blocks = block.child_blocks
60
+ matching_child_blocks = {}
61
+ child_templates.each do |child_template|
62
+ matching = nil
63
+ child_blocks.each do |child_block|
64
+ if child_template.id == child_block.id
65
+ matching = child_block
66
+ break
67
+ end
68
+ end
69
+ child_blocks.delete(matching) unless matching.nil?
70
+ matching_child_blocks[child_template] = matching
71
+ end
72
+ matching_child_blocks
73
+ end
74
+ end
75
+
76
+ module FlexibleBlockMatchingAndCreateMissingBlocksButIgnoreUserText
77
+ include FlexibleBlockMatching
78
+
79
+ def update_block(block, options={})
80
+ matching_child_blocks = match_child_blocks(block)
81
+
82
+ block.contents.clear
83
+ contents.each do |content|
84
+ if content.kind_of?(Template)
85
+ if matching_child_blocks[content].nil?
86
+ block.contents << content.create_block(options)
87
+ else
88
+ matching = matching_child_blocks[content]
89
+ content.update_block(matching)
90
+ block.contents << matching
91
+ end
92
+ else
93
+ block.contents << content
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ module FlexibleBlockMatchingAndCreateMissingBlockButLeaveUserTextBe
100
+ include FlexibleBlockMatching
101
+
102
+ def update_block(block, options={})
103
+ options = {:new_line_after_block => true}.merge(options)
104
+ matching_child_blocks = match_child_blocks(block)
105
+
106
+ child_templates.each do |child_template|
107
+ if matching_child_blocks[child_template].nil?
108
+ new_block = child_template.create_block(options)
109
+
110
+ position = position_to_insert(block, new_block)
111
+ if position
112
+ block.contents.insert(position, new_block)
113
+ if options[:new_line_after_block]
114
+ block.contents.insert(position+1, "")
115
+ end
116
+ else
117
+ raise ArgumentError.new("cannot find position to insert '#{new_block.name}'")
118
+ end
119
+ else
120
+ matching = matching_child_blocks[child_template]
121
+ child_template.update_block(matching)
122
+ end
123
+ end
124
+ end
125
+
126
+ ##
127
+ # @return (Integer) the position in block.contents to
128
+ # insert the given new block
129
+ def position_to_insert(block, new_block)
130
+ raise NotImplementedError
131
+ end
132
+ end
133
133
  end