Home / Function/ process() — tailwindcss Function Reference

process() — tailwindcss Function Reference

Architecture documentation for the process() function in slim.rs from the tailwindcss codebase.

Entity Profile

Dependency Diagram

graph TD
  dd2a534f_9e3f_5734_d908_4dfbbfec4407["process()"]
  435a321a_a1e2_cb4f_7579_0ca15cb86434["advance()"]
  dd2a534f_9e3f_5734_d908_4dfbbfec4407 -->|calls| 435a321a_a1e2_cb4f_7579_0ca15cb86434
  style dd2a534f_9e3f_5734_d908_4dfbbfec4407 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

crates/oxide/src/extractor/pre_processors/slim.rs lines 11–138

    fn process(&self, content: &[u8]) -> Vec<u8> {
        let len = content.len();
        let mut result = content.to_vec();
        let mut cursor = cursor::Cursor::new(content);
        let mut bracket_stack = BracketStack::default();

        while cursor.pos < len {
            match cursor.curr {
                // Only replace `.` with a space if it's not surrounded by numbers. E.g.:
                //
                // ```diff
                // - .flex.items-center
                // +  flex items-center
                // ```
                //
                // But with numbers, it's allowed:
                //
                // ```diff
                // - px-2.5
                // + px-2.5
                // ```
                b'.' => {
                    // Don't replace dots with spaces when inside of any type of brackets, because
                    // this could be part of arbitrary values. E.g.: `bg-[url(https://example.com)]`
                    //                                                                       ^
                    if !bracket_stack.is_empty() {
                        cursor.advance();
                        continue;
                    }

                    // If the dot is surrounded by digits, we want to keep it. E.g.: `px-2.5`
                    // EXCEPT if it's followed by a valid variant that happens to start with a
                    // digit.
                    // E.g.: `bg-red-500.2xl:flex`
                    //                 ^^^
                    if cursor.prev.is_ascii_digit() && cursor.next.is_ascii_digit() {
                        let mut next_cursor = cursor.clone();
                        next_cursor.advance();

                        let mut variant_machine = VariantMachine::default();
                        if let MachineState::Done(_) = variant_machine.next(&mut next_cursor) {
                            result[cursor.pos] = b' ';
                        }
                    } else {
                        result[cursor.pos] = b' ';
                    }
                }

                // Handle Ruby syntax with `%w[]` arrays embedded in Slim directly.
                //
                // E.g.:
                //
                // ```
                // div [
                //   class=%w[bg-blue-500 w-10 h-10]
                // ]
                // ```
                b'%' if matches!(cursor.next, b'w' | b'W')
                    && matches!(cursor.input.get(cursor.pos + 2), Some(b'[' | b'(' | b'{')) =>
                {
                    result[cursor.pos] = b' '; // Replace `%`
                    cursor.advance();
                    result[cursor.pos] = b' '; // Replace `w`
                    cursor.advance();
                    result[cursor.pos] = b' '; // Replace `[` or `(` or `{`
                    bracket_stack.push(cursor.curr);
                    cursor.advance(); // Move past the bracket
                    continue;
                }

                // Any `[` preceded by an alphanumeric value will not be part of a candidate.
                //
                // E.g.:
                //
                // ```
                //  .text-xl.text-red-600[
                //                       ^ not part of the `text-red-600` candidate
                //    data-foo="bar"
                //  ]
                //    | This line should be red
                // ```
                //
                // We know that `-[` is valid for an arbitrary value and that `:[` is valid as a
                // variant. However `[color:red]` is also valid, in this case `[` will be preceded
                // by nothing or a boundary character.
                // Instead of listing all boundary characters, let's list the characters we know
                // will be invalid instead.
                b'[' if bracket_stack.is_empty()
                    && matches!(cursor.prev, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9') =>
                {
                    result[cursor.pos] = b' ';
                    bracket_stack.push(cursor.curr);
                }

                // In Slim the class name shorthand can be followed by a parenthesis. E.g.:
                //
                // ```slim
                // body.border-t-4.p-8(attr=value)
                //                    ^ Not part of the p-8 class
                // ```
                //
                // This means that we need to replace all these `(` and `)` with spaces to make
                // sure that we can extract the `p-8`.
                //
                // However, we also need to make sure that we keep the parens that are part of the
                // utility class. E.g.: `bg-(--my-color)`.
                b'(' if bracket_stack.is_empty() && !matches!(cursor.prev, b'-' | b'/') => {
                    result[cursor.pos] = b' ';
                    bracket_stack.push(cursor.curr);
                }

                b'(' | b'[' | b'{' => {
                    bracket_stack.push(cursor.curr);
                }

                b')' | b']' | b'}' if !bracket_stack.is_empty() => {
                    bracket_stack.pop(cursor.curr);
                }

                // Consume everything else
                _ => {}
            };

            cursor.advance();
        }

        result
    }

Domain

Subdomains

Calls

Frequently Asked Questions

What does process() do?
process() is a function in the tailwindcss codebase.
What does process() call?
process() calls 1 function(s): advance.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free