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
Source
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