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