Home / Function/ process() — tailwindcss Function Reference

process() — tailwindcss Function Reference

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

Entity Profile

Dependency Diagram

graph TD
  df07b2ab_5c7f_0413_879f_f42437b5101e["process()"]
  ffc5693d_f72e_53c2_3a9f_e796ab1c4070["skip_indented_block()"]
  df07b2ab_5c7f_0413_879f_f42437b5101e -->|calls| ffc5693d_f72e_53c2_3a9f_e796ab1c4070
  07207bb0_f195_4067_2024_eb12d4800851["advance_twice()"]
  df07b2ab_5c7f_0413_879f_f42437b5101e -->|calls| 07207bb0_f195_4067_2024_eb12d4800851
  435a321a_a1e2_cb4f_7579_0ca15cb86434["advance()"]
  df07b2ab_5c7f_0413_879f_f42437b5101e -->|calls| 435a321a_a1e2_cb4f_7579_0ca15cb86434
  style df07b2ab_5c7f_0413_879f_f42437b5101e fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

crates/oxide/src/extractor/pre_processors/haml.rs lines 13–236

    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();

        // Haml Comments: -#
        // https://haml.info/docs/yardoc/file.REFERENCE.html#ruby-evaluation
        //
        // > The hyphen followed immediately by the pound sign signifies a silent comment. Any text
        // > following this isn’t rendered in the resulting document at all.
        //
        // ```haml
        // %p foo
        // -# This is a comment
        // %p bar
        // ```
        //
        // > You can also nest text beneath a silent comment. None of this text will be rendered.
        //
        // ```haml
        // %p foo
        // -#
        //   This won't be displayed
        //     Nor will this
        //                    Nor will this.
        // %p bar
        // ```
        //
        // Ruby Evaluation
        // https://haml.info/docs/yardoc/file.REFERENCE.html#ruby-evaluation
        //
        // When any of the following characters are the first non-whitespace character on the line,
        // then the line is treated as Ruby code:
        //
        // - Inserting Ruby: =
        //   https://haml.info/docs/yardoc/file.REFERENCE.html#inserting_ruby
        //
        //   ```haml
        //   %p
        //     = ['hi', 'there', 'reader!'].join " "
        //     = "yo"
        //   ```
        //
        // - Running Ruby: -
        //   https://haml.info/docs/yardoc/file.REFERENCE.html#running-ruby--
        //
        //   ```haml
        //   - foo = "hello"
        //   - foo << " there"
        //   - foo << " you!"
        //   %p= foo
        //   ```
        //
        // - Whitespace Preservation: ~
        //   https://haml.info/docs/yardoc/file.REFERENCE.html#tilde
        //
        //   > ~ works just like =, except that it runs Haml::Helpers.preserve on its input.
        //
        //   ```haml
        //   ~ "Foo\n<pre>Bar\nBaz</pre>"
        //   ```
        //
        // Important note:
        //
        // > A line of Ruby code can be stretched over multiple lines as long as each line but the
        // > last ends with a comma.
        //
        // ```haml
        // - links = {:home => "/",
        //   :docs => "/docs",
        //   :about => "/about"}
        // ```
        //
        // Ruby Blocks:
        // https://haml.info/docs/yardoc/file.REFERENCE.html#ruby-blocks
        //
        // > Ruby blocks, like XHTML tags, don’t need to be explicitly closed in Haml. Rather,
        // > they’re automatically closed, based on indentation. A block begins whenever the
        // > indentation is increased after a Ruby evaluation command. It ends when the indentation
        // > decreases (as long as it’s not an else clause or something similar).
        //
        // ```haml
        // - (42...47).each do |i|
        //   %p= i
        // %p See, I can count!
        // ```
        //
        let mut last_newline_position = 0;

        while cursor.pos < len {
            match cursor.curr {
                // Escape the next character
                b'\\' => {
                    cursor.advance_twice();
                    continue;
                }

                // Track the last newline position
                b'\n' => {
                    last_newline_position = cursor.pos;
                    cursor.advance();
                    continue;
                }

                // Skip HAML comments. `-#`
                b'-' if cursor.input[last_newline_position..cursor.pos]
                    .iter()
                    .all(u8::is_ascii_whitespace)
                    && matches!(cursor.next, b'#') =>
                {
                    // Just consume the comment
                    let updated_last_newline_position =
                        self.skip_indented_block(&mut cursor, last_newline_position);

                    // Override the last known newline position
                    last_newline_position = updated_last_newline_position;
                }

                // Skip HTML comments. `/`
                b'/' if cursor.input[last_newline_position..cursor.pos]
                    .iter()
                    .all(u8::is_ascii_whitespace) =>
                {
                    // Just consume the comment
                    let updated_last_newline_position =
                        self.skip_indented_block(&mut cursor, last_newline_position);

                    // Override the last known newline position
                    last_newline_position = updated_last_newline_position;
                }

                // Ruby evaluation
                b'-' | b'=' | b'~'
                    if cursor.input[last_newline_position..cursor.pos]
                        .iter()
                        .all(u8::is_ascii_whitespace) =>
                {
                    let mut start = cursor.pos;
                    let end = self.skip_indented_block(&mut cursor, last_newline_position);

                    // Increment start with 1 character to skip the `=` or `-` character
                    start += 1;

                    let ruby_code = &cursor.input[start..end];

                    // Override the last known newline position
                    last_newline_position = end;

                    let replaced = pre_process_input(ruby_code, "rb");
                    result.replace_range(start..end, replaced);
                }

                // 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' ';
                    }
                }

                // Replace following characters with spaces if they are not inside of brackets
                b'#' | b'=' if bracket_stack.is_empty() => {
                    result[cursor.pos] = b' ';
                }

                b'(' | b'[' | b'{' => {
                    // Replace first bracket with a space
                    if bracket_stack.is_empty() {
                        result[cursor.pos] = b' ';
                    }
                    bracket_stack.push(cursor.curr);
                }

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

                    // Replace closing bracket with a space
                    if bracket_stack.is_empty() {
                        result[cursor.pos] = b' ';
                    }
                }

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

            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 3 function(s): advance, advance_twice, skip_indented_block.

Analyze Your Own Codebase

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

Try Supermodel Free