mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
This PR introduces a new `source(…)` argument and improves on the
existing `@source`. The goal of this PR is to make the automatic source
detection configurable, let's dig in.
By default, we will perform automatic source detection starting at the
current working directory. Auto source detection will find plain text
files (no binaries, images, ...) and will ignore git-ignored files.
If you want to start from a different directory, you can use the new
`source(…)` next to the `@import "tailwindcss/utilities"
layer(utilities) source(…)`.
E.g.:
```css
/* ./src/styles/index.css */
@import 'tailwindcss/utilities' layer(utilities) source('../../');
```
Most people won't split their source files, and will just use the simple
`@import "tailwindcss";`, because of this reason, you can use
`source(…)` on the import as well:
E.g.:
```css
/* ./src/styles/index.css */
@import 'tailwindcss' source('../../');
```
Sometimes, you want to rely on auto source detection, but also want to
look in another directory for source files. In this case, yuo can use
the `@source` directive:
```css
/* ./src/index.css */
@import 'tailwindcss';
/* Look for `blade.php` files in `../resources/views` */
@source '../resources/views/**/*.blade.php';
```
However, you don't need to specify the extension, instead you can just
point the directory and all the same automatic source detection rules
will apply.
```css
/* ./src/index.css */
@import 'tailwindcss';
@source '../resources/views';
```
If, for whatever reason, you want to disable the default source
detection feature entirely, and only want to rely on very specific glob
patterns you define, then you can disable it via `source(none)`.
```css
/* Completely disable the default auto source detection */
@import 'tailwindcss' source(none);
/* Only look at .blade.php files, nothing else */
@source "../resources/views/**/*.blade.php";
```
Note: even with `source(none)`, if your `@source` points to a directory,
then auto source detection will still be performed in that directory. If
you don't want that, then you can simply add explicit files in the globs
as seen in the previous example.
```css
/* Completely disable the default auto source detection */
@import 'tailwindcss' source(none);
/* Run auto source detection in `../resources/views` */
@source "../resources/views";
```
---------
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
95 lines
2.0 KiB
Rust
95 lines
2.0 KiB
Rust
/// The `IndexConverter` is used to convert UTF-8 *BYTE* indexes to UTF-16
|
|
/// *character* indexes
|
|
#[derive(Clone)]
|
|
pub struct IndexConverter<'a> {
|
|
input: &'a str,
|
|
curr_utf8: usize,
|
|
curr_utf16: usize,
|
|
}
|
|
|
|
impl<'a> IndexConverter<'a> {
|
|
pub fn new(input: &'a str) -> Self {
|
|
Self {
|
|
input,
|
|
curr_utf8: 0,
|
|
curr_utf16: 0,
|
|
}
|
|
}
|
|
|
|
pub fn get(&mut self, pos: usize) -> i64 {
|
|
#[cfg(debug_assertions)]
|
|
if self.curr_utf8 > self.input.len() {
|
|
panic!("curr_utf8 points past the end of the input string");
|
|
}
|
|
|
|
if pos < self.curr_utf8 {
|
|
self.curr_utf8 = 0;
|
|
self.curr_utf16 = 0;
|
|
}
|
|
|
|
// SAFETY: No matter what `pos` is passed into this function `curr_utf8`
|
|
// will only ever be incremented up to the length of the input string.
|
|
//
|
|
// This eliminates a "potential" panic that cannot actually happen
|
|
let slice = unsafe { self.input.get_unchecked(self.curr_utf8..) };
|
|
|
|
for c in slice.chars() {
|
|
if self.curr_utf8 >= pos {
|
|
break;
|
|
}
|
|
|
|
self.curr_utf8 += c.len_utf8();
|
|
self.curr_utf16 += c.len_utf16();
|
|
}
|
|
|
|
self.curr_utf16 as i64
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::*;
|
|
use std::collections::HashMap;
|
|
|
|
#[test]
|
|
fn test_index_converter() {
|
|
let mut converter = IndexConverter::new("Hello 🔥🥳 world!");
|
|
|
|
let map = HashMap::from([
|
|
// hello<space>
|
|
(0, 0),
|
|
(1, 1),
|
|
(2, 2),
|
|
(3, 3),
|
|
(4, 4),
|
|
(5, 5),
|
|
(6, 6),
|
|
// inside the 🔥
|
|
(7, 8),
|
|
(8, 8),
|
|
(9, 8),
|
|
(10, 8),
|
|
// inside the 🥳
|
|
(11, 10),
|
|
(12, 10),
|
|
(13, 10),
|
|
(14, 10),
|
|
// <space>world!
|
|
(15, 11),
|
|
(16, 12),
|
|
(17, 13),
|
|
(18, 14),
|
|
(19, 15),
|
|
(20, 16),
|
|
(21, 17),
|
|
// Past the end should return the last utf-16 character index
|
|
(22, 17),
|
|
(100, 17),
|
|
]);
|
|
|
|
for (idx_utf8, idx_utf16) in map {
|
|
assert_eq!(converter.get(idx_utf8), idx_utf16);
|
|
}
|
|
}
|
|
}
|