segment.ts — tailwindcss Source File
Architecture documentation for segment.ts, a typescript file in the tailwindcss codebase. 0 imports, 27 dependents.
Entity Profile
Dependency Diagram
graph LR ef204000_8998_5a6c_5455_324b37624713["segment.ts"] 764d02dc_895f_8f85_d274_59af948c9ebb["analyze.ts"] 764d02dc_895f_8f85_d274_59af948c9ebb --> ef204000_8998_5a6c_5455_324b37624713 a6ecddee_0a56_f3dd_6fd9_8373ce255940["migrate-at-apply.ts"] a6ecddee_0a56_f3dd_6fd9_8373ce255940 --> ef204000_8998_5a6c_5455_324b37624713 9e4e8a58_fb9b_d663_2880_954972aac787["migrate-at-layer-utilities.ts"] 9e4e8a58_fb9b_d663_2880_954972aac787 --> ef204000_8998_5a6c_5455_324b37624713 7d223813_0df4_dfbe_850e_d5fd9ab81eef["migrate-import.ts"] 7d223813_0df4_dfbe_850e_d5fd9ab81eef --> ef204000_8998_5a6c_5455_324b37624713 22b81643_65c2_ce37_e597_13959f1f8254["migrate-missing-layers.ts"] 22b81643_65c2_ce37_e597_13959f1f8254 --> ef204000_8998_5a6c_5455_324b37624713 29d3e557_c0bc_8d75_94ae_12864625aef4["migrate-legacy-arbitrary-values.ts"] 29d3e557_c0bc_8d75_94ae_12864625aef4 --> ef204000_8998_5a6c_5455_324b37624713 d13948d4_4434_bf78_9916_1ba327123c94["migrate-prefix.ts"] d13948d4_4434_bf78_9916_1ba327123c94 --> ef204000_8998_5a6c_5455_324b37624713 de8dd9be_8c47_4694_db3b_393c549a926a["migrate-theme-to-var.ts"] de8dd9be_8c47_4694_db3b_393c549a926a --> ef204000_8998_5a6c_5455_324b37624713 ca8635ee_31ba_d4fd_68e2_ee9e03168422["apply.ts"] ca8635ee_31ba_d4fd_68e2_ee9e03168422 --> ef204000_8998_5a6c_5455_324b37624713 669e6a28_c71f_3c5e_9c53_915cede7da78["candidate.ts"] 669e6a28_c71f_3c5e_9c53_915cede7da78 --> ef204000_8998_5a6c_5455_324b37624713 7d350d81_5de1_f9f3_5b2c_19ec8fd3c37e["canonicalize-candidates.ts"] 7d350d81_5de1_f9f3_5b2c_19ec8fd3c37e --> ef204000_8998_5a6c_5455_324b37624713 daaadd53_16ee_21c6_12d9_8feaac80a91b["apply-compat-hooks.ts"] daaadd53_16ee_21c6_12d9_8feaac80a91b --> ef204000_8998_5a6c_5455_324b37624713 1b5321a5_0fcc_2351_1f22_0d4bed4c097e["default-theme.ts"] 1b5321a5_0fcc_2351_1f22_0d4bed4c097e --> ef204000_8998_5a6c_5455_324b37624713 13af74f3_f39e_86e7_a3f9_c2738431bca0["legacy-utilities.ts"] 13af74f3_f39e_86e7_a3f9_c2738431bca0 --> ef204000_8998_5a6c_5455_324b37624713 style ef204000_8998_5a6c_5455_324b37624713 fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
const BACKSLASH = 0x5c
const OPEN_CURLY = 0x7b
const CLOSE_CURLY = 0x7d
const OPEN_PAREN = 0x28
const CLOSE_PAREN = 0x29
const OPEN_BRACKET = 0x5b
const CLOSE_BRACKET = 0x5d
const DOUBLE_QUOTE = 0x22
const SINGLE_QUOTE = 0x27
// This is a shared buffer that is used to keep track of the current nesting level
// of parens, brackets, and braces. It is used to determine if a character is at
// the top-level of a string. This is a performance optimization to avoid memory
// allocations on every call to `segment`.
const closingBracketStack = new Uint8Array(256)
/**
* This splits a string on a top-level character.
*
* Regex doesn't support recursion (at least not the JS-flavored version),
* so we have to use a tiny state machine to keep track of paren placement.
*
* Expected behavior using commas:
* var(--a, 0 0 1px rgb(0, 0, 0)), 0 0 1px rgb(0, 0, 0)
* ┬ ┬ ┬ ┬
* x x x ╰──────── Split because top-level
* ╰──────────────┴──┴───────────── Ignored b/c inside >= 1 levels of parens
*/
export function segment(input: string, separator: string) {
// SAFETY: We can use an index into a shared buffer because this function is
// synchronous, non-recursive, and runs in a single-threaded environment.
let stackPos = 0
let parts: string[] = []
let lastPos = 0
let len = input.length
let separatorCode = separator.charCodeAt(0)
for (let idx = 0; idx < len; idx++) {
let char = input.charCodeAt(idx)
if (stackPos === 0 && char === separatorCode) {
parts.push(input.slice(lastPos, idx))
lastPos = idx + 1
continue
}
switch (char) {
case BACKSLASH:
// The next character is escaped, so we skip it.
idx += 1
break
// Strings should be handled as-is until the end of the string. No need to
// worry about balancing parens, brackets, or curlies inside a string.
case SINGLE_QUOTE:
case DOUBLE_QUOTE:
// Ensure we don't go out of bounds.
while (++idx < len) {
let nextChar = input.charCodeAt(idx)
// The next character is escaped, so we skip it.
if (nextChar === BACKSLASH) {
idx += 1
continue
}
if (nextChar === char) {
break
}
}
break
case OPEN_PAREN:
closingBracketStack[stackPos] = CLOSE_PAREN
stackPos++
break
case OPEN_BRACKET:
closingBracketStack[stackPos] = CLOSE_BRACKET
stackPos++
break
case OPEN_CURLY:
closingBracketStack[stackPos] = CLOSE_CURLY
stackPos++
break
case CLOSE_BRACKET:
case CLOSE_CURLY:
case CLOSE_PAREN:
if (stackPos > 0 && char === closingBracketStack[stackPos - 1]) {
// SAFETY: The buffer does not need to be mutated because the stack is
// only ever read from or written to its current position. Its current
// position is only ever incremented after writing to it. Meaning that
// the buffer can be dirty for the next use and still be correct since
// reading/writing always starts at position `0`.
stackPos--
}
break
}
}
parts.push(input.slice(lastPos))
return parts
}
Domain
Subdomains
Functions
Imported By
- packages/@tailwindcss-upgrade/src/codemods/css/analyze.ts
- packages/tailwindcss/src/compat/apply-compat-hooks.ts
- packages/tailwindcss/src/apply.ts
- packages/tailwindcss/src/utils/brace-expansion.ts
- packages/tailwindcss/src/candidate.ts
- packages/tailwindcss/src/canonicalize-candidates.ts
- packages/tailwindcss/src/css-functions.ts
- packages/tailwindcss/src/compat/default-theme.ts
- packages/tailwindcss/src/expand-declaration.ts
- packages/tailwindcss/src/index.ts
- packages/tailwindcss/src/utils/infer-data-type.ts
- packages/tailwindcss/src/compat/legacy-utilities.ts
- packages/@tailwindcss-upgrade/src/codemods/css/migrate-at-apply.ts
- packages/@tailwindcss-upgrade/src/codemods/css/migrate-at-layer-utilities.ts
- packages/@tailwindcss-upgrade/src/codemods/css/migrate-import.ts
- packages/@tailwindcss-upgrade/src/codemods/template/migrate-legacy-arbitrary-values.ts
- packages/@tailwindcss-upgrade/src/codemods/css/migrate-missing-layers.ts
- packages/@tailwindcss-upgrade/src/codemods/template/migrate-prefix.ts
- packages/@tailwindcss-upgrade/src/codemods/template/migrate-theme-to-var.ts
- packages/tailwindcss/src/compat/plugin-api.ts
- packages/tailwindcss/src/utils/replace-shadow-colors.ts
- packages/tailwindcss/src/utils/segment.bench.ts
- packages/tailwindcss/src/utils/segment.test.ts
- packages/tailwindcss/src/utils/to-key-path.ts
- packages/tailwindcss/tests/ui.spec.ts
- packages/tailwindcss/src/utilities.ts
- packages/tailwindcss/src/variants.ts
Source
Frequently Asked Questions
What does segment.ts do?
segment.ts is a source file in the tailwindcss codebase, written in typescript. It belongs to the OxideEngine domain, Scanner subdomain.
What functions are defined in segment.ts?
segment.ts defines 1 function(s): segment.
What files import segment.ts?
segment.ts is imported by 27 file(s): analyze.ts, apply-compat-hooks.ts, apply.ts, brace-expansion.ts, candidate.ts, canonicalize-candidates.ts, css-functions.ts, default-theme.ts, and 19 more.
Where is segment.ts in the architecture?
segment.ts is located at packages/tailwindcss/src/utils/segment.ts (domain: OxideEngine, subdomain: Scanner, directory: packages/tailwindcss/src/utils).
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free