File: sass_util.cpp

package info (click to toggle)
golang-github-wellington-go-libsass 0.9.2%2Bgit20181130.4ef5b9d-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 2,128 kB
  • sloc: cpp: 28,607; ansic: 839; makefile: 44
file content (149 lines) | stat: -rw-r--r-- 4,111 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include "sass.hpp"
#include "node.hpp"

namespace Sass {


  /*
    # This is the equivalent of ruby's Sass::Util.paths.
    #
    # Return an array of all possible paths through the given arrays.
    #
    # @param arrs [NodeCollection<NodeCollection<Node>>]
    # @return [NodeCollection<NodeCollection<Node>>]
    #
    # @example
    #   paths([[1, 2], [3, 4], [5]]) #=>
    #     # [[1, 3, 5],
    #     #  [2, 3, 5],
    #     #  [1, 4, 5],
    #     #  [2, 4, 5]]

   The following is the modified version of the ruby code that was more portable to C++. You
   should be able to drop it into ruby 3.2.19 and get the same results from ruby sass.

    def paths(arrs)
        // I changed the inject and maps to an iterative approach to make it easier to implement in C++
      loopStart = [[]]

      for arr in arrs do
        permutations = []
        for e in arr do
          for path in loopStart do
            permutations.push(path + [e])
          end
        end
        loopStart = permutations
      end
    end
  */
  Node paths(const Node& arrs) {

    Node loopStart = Node::createCollection();
    loopStart.collection()->push_back(Node::createCollection());

    for (NodeDeque::iterator arrsIter = arrs.collection()->begin(), arrsEndIter = arrs.collection()->end();
    	arrsIter != arrsEndIter; ++arrsIter) {

      Node& arr = *arrsIter;

      Node permutations = Node::createCollection();

      for (NodeDeque::iterator arrIter = arr.collection()->begin(), arrIterEnd = arr.collection()->end();
      	arrIter != arrIterEnd; ++arrIter) {

        Node& e = *arrIter;

        for (NodeDeque::iterator loopStartIter = loopStart.collection()->begin(), loopStartIterEnd = loopStart.collection()->end();
          loopStartIter != loopStartIterEnd; ++loopStartIter) {

          Node& path = *loopStartIter;

          Node newPermutation = Node::createCollection();
          newPermutation.got_line_feed = arr.got_line_feed;
          newPermutation.plus(path);
          newPermutation.collection()->push_back(e);

          permutations.collection()->push_back(newPermutation);
        }
      }

      loopStart = permutations;
    }

    return loopStart;
  }


  /*
  This is the equivalent of ruby sass' Sass::Util.flatten and [].flatten.
  Sass::Util.flatten requires the number of levels to flatten, while
  [].flatten doesn't and will flatten the entire array. This function
  supports both.

  # Flattens the first `n` nested arrays. If n == -1, all arrays will be flattened
  #
  # @param arr [NodeCollection] The array to flatten
  # @param n [int] The number of levels to flatten
  # @return [NodeCollection] The flattened array

  The following is the modified version of the ruby code that was more portable to C++. You
  should be able to drop it into ruby 3.2.19 and get the same results from ruby sass.

  def flatten(arr, n = -1)
    if n != -1 and n == 0 then
      return arr
    end

    flattened = []

    for e in arr do
      if e.is_a?(Array) then
        flattened.concat(flatten(e, n - 1))
      else
        flattened << e
      end
    end

    return flattened
  end
  */
  Node flatten(Node& arr, int n) {
    if (n != -1 && n == 0) {
      return arr;
    }

    Node flattened = Node::createCollection();
    if (arr.got_line_feed) flattened.got_line_feed = true;

    for (NodeDeque::iterator iter = arr.collection()->begin(), iterEnd = arr.collection()->end();
    	iter != iterEnd; iter++) {
    	Node& e = *iter;

      // e has the lf set
      if (e.isCollection()) {

      	// e.collection().got_line_feed = e.got_line_feed;
      	Node recurseFlattened = flatten(e, n - 1);

      	if(e.got_line_feed) {
      		 flattened.got_line_feed = e.got_line_feed;
      	  recurseFlattened.got_line_feed = e.got_line_feed;
      	}

      	for(auto i : (*recurseFlattened.collection())) {
          if (recurseFlattened.got_line_feed) {

            i.got_line_feed = true;
          }
          flattened.collection()->push_back(i);
      	}

      } else {
      	flattened.collection()->push_back(e);
      }
    }

    return flattened;
  }
}