Home / Function/ process() — tailwindcss Function Reference

process() — tailwindcss Function Reference

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

Entity Profile

Dependency Diagram

graph TD
  f9471ccc_2fad_6cca_3b80_f2d80b367f8a["process()"]
  35b2adf8_a27b_5aee_3865_21fb048c97fb["advance()"]
  f9471ccc_2fad_6cca_3b80_f2d80b367f8a -->|calls| 35b2adf8_a27b_5aee_3865_21fb048c97fb
  a342bcc5_aaba_6cba_f921_8c94c0d956ac["advance_twice()"]
  f9471ccc_2fad_6cca_3b80_f2d80b367f8a -->|calls| a342bcc5_aaba_6cba_f921_8c94c0d956ac
  31342787_2ca0_5a41_9122_4a6eabae23a7["reset()"]
  f9471ccc_2fad_6cca_3b80_f2d80b367f8a -->|calls| 31342787_2ca0_5a41_9122_4a6eabae23a7
  0d2f4bc0_2b1b_fd72_0ffc_954eed604d0a["push()"]
  f9471ccc_2fad_6cca_3b80_f2d80b367f8a -->|calls| 0d2f4bc0_2b1b_fd72_0ffc_954eed604d0a
  137d4a53_4b6e_09a1_8799_98b67760e503["is_empty()"]
  f9471ccc_2fad_6cca_3b80_f2d80b367f8a -->|calls| 137d4a53_4b6e_09a1_8799_98b67760e503
  6b9684e1_5d48_c752_bd3e_50b21816b836["pop()"]
  f9471ccc_2fad_6cca_3b80_f2d80b367f8a -->|calls| 6b9684e1_5d48_c752_bd3e_50b21816b836
  style f9471ccc_2fad_6cca_3b80_f2d80b367f8a fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

crates/oxide/src/extractor/pre_processors/ruby.rs lines 29–222

    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 = bracket_stack::BracketStack::default();

        // Extract embedded template languages
        // https://viewcomponent.org/guide/templates.html#interpolations
        let content_as_str = std::str::from_utf8(content).unwrap();

        let starts = TEMPLATE_START_REGEX
            .captures_iter(content_as_str)
            .collect::<Vec<_>>();
        let ends = TEMPLATE_END_REGEX
            .captures_iter(content_as_str)
            .collect::<Vec<_>>();

        for start in starts.iter() {
            // The language for this block
            let lang = start.get(1).unwrap().as_str();

            // The HEREDOC delimiter
            let delimiter_start = start.get(2).unwrap().as_str();

            // Where the "body" starts for the HEREDOC block
            let body_start = start.get(0).unwrap().end();

            // Look through all of the ends to find a matching language
            for end in ends.iter() {
                // 1. This must appear after the start
                let body_end = end.get(0).unwrap().start();
                if body_end < body_start {
                    continue;
                }

                // The languages must match otherwise we haven't found the end
                let delimiter_end = end.get(1).unwrap().as_str();
                if delimiter_end != delimiter_start {
                    continue;
                }

                let body = &content_as_str[body_start..body_end];
                let replaced = pre_process_input(body.as_bytes(), &lang.to_ascii_lowercase());

                result.replace_range(body_start..body_end, replaced);
                break;
            }
        }

        // Ruby extraction
        while cursor.pos < len {
            match cursor.curr {
                b'"' => {
                    cursor.advance();

                    while cursor.pos < len {
                        match cursor.curr {
                            // Escaped character, skip ahead to the next character
                            b'\\' => cursor.advance_twice(),

                            // End of the string
                            b'"' => break,

                            // Everything else is valid
                            _ => cursor.advance(),
                        };
                    }

                    cursor.advance();
                    continue;
                }

                b'\'' => {
                    cursor.advance();

                    while cursor.pos < len {
                        match cursor.curr {
                            // Escaped character, skip ahead to the next character
                            b'\\' => cursor.advance_twice(),

                            // End of the string
                            b'\'' => break,

                            // Everything else is valid
                            _ => cursor.advance(),
                        };
                    }

                    cursor.advance();
                    continue;
                }

                // Replace comments in Ruby files
                //
                // Except for strict locals, these are defined in a `<%# locals: … %>`. Checking if
                // the comment is preceded by a `%` should be enough without having to perform more
                // parsing logic. Worst case we _do_ scan a few comments.
                b'#' if !matches!(cursor.prev, b'%') => {
                    result[cursor.pos] = b' ';
                    cursor.advance();

                    while cursor.pos < len {
                        match cursor.curr {
                            // End of the comment
                            b'\n' => break,

                            // Everything else is part of the comment and replaced
                            _ => {
                                result[cursor.pos] = b' ';
                                cursor.advance();
                            }
                        };
                    }

                    cursor.advance();
                    continue;
                }

                _ => {}
            }

            // Looking for `%w`, `%W`, or `%p`
            if cursor.curr != b'%' || !matches!(cursor.next, b'w' | b'W' | b'p') {
                cursor.advance();
                continue;
            }

            cursor.advance_twice();

            // Boundary character
            let boundary = match cursor.curr {
                b'[' => b']',
                b'(' => b')',
                b'{' => b'}',
                b'#' => b'#',
                b' ' => b'\n',
                _ => {
                    cursor.advance();
                    continue;
                }
            };

            bracket_stack.reset();

            // Replace the current character with a space
            result[cursor.pos] = b' ';

            // Skip the boundary character
            cursor.advance();

            while cursor.pos < len {
                match cursor.curr {
                    // Skip escaped characters
                    b'\\' => {
                        // Use backslash to embed spaces in the strings.
                        if cursor.next == b' ' {
                            result[cursor.pos] = b' ';
                        }

                        cursor.advance();
                    }

                    // Start of a nested bracket
                    b'[' | b'(' | b'{' => {
                        bracket_stack.push(cursor.curr);
                    }

                    // End of a nested bracket
                    b']' | b')' | b'}' if !bracket_stack.is_empty() => {
                        if !bracket_stack.pop(cursor.curr) {
                            // Unbalanced
                            cursor.advance();
                        }
                    }

                    // End of the pattern, replace the boundary character with a space
                    _ if cursor.curr == boundary => {
                        if boundary != b'\n' {
                            result[cursor.pos] = b' ';
                        }

                        break;
                    }

                    // Everything else is valid
                    _ => {}
                }

                cursor.advance();
            }
        }

        result
    }

Domain

Subdomains

Frequently Asked Questions

What does process() do?
process() is a function in the tailwindcss codebase.
What does process() call?
process() calls 6 function(s): advance, advance_twice, is_empty, pop, push, reset.

Analyze Your Own Codebase

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

Try Supermodel Free