cataract 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/ext/cataract/cataract.c +108 -2
- data/ext/cataract/cataract.h +4 -0
- data/lib/cataract/pure/serializer.rb +3 -0
- data/lib/cataract/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a1c4727f2f1b3c3aafa117ca105ee0d55a6d6f33b0fed789533af10c24173918
|
|
4
|
+
data.tar.gz: 86c0e96b1a953fb817fa235517e00215b4b363baea7d1225c5fcb2b9643b29c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7282bde75fb5cd81ad2b7f2d7134a6fde2941a8f5320a4de2d463114d25bfc709e80f1639e9479cb69b7f22d685d203a7097fa0cf8c2e952041b733420991080
|
|
7
|
+
data.tar.gz: f8af1d50b389d64c36c5138f431b5b09f95ec3ca8f68b6c342ec280e7e1c84a8fca95ec6c95a81d97f9bced8d0f295acfbf2849ca47939e16cbf1b408544cdbe
|
data/CHANGELOG.md
CHANGED
data/ext/cataract/cataract.c
CHANGED
|
@@ -549,18 +549,34 @@ static void serialize_rule_with_children(VALUE result, VALUE rules_array, long r
|
|
|
549
549
|
|
|
550
550
|
if (formatted) {
|
|
551
551
|
// Formatted output with indentation
|
|
552
|
+
DEBUG_PRINTF("[SERIALIZE_RULE] Formatted mode, indent_level=%d, selector=%s\n", indent_level, RSTRING_PTR(selector));
|
|
552
553
|
rb_str_append(result, selector);
|
|
553
554
|
rb_str_cat2(result, " {\n");
|
|
554
555
|
|
|
556
|
+
// Build indent strings based on indent_level
|
|
557
|
+
// Declarations are inside the rule, so add 1 level (2 spaces per level)
|
|
558
|
+
// Closing brace matches the opening selector level
|
|
559
|
+
char decl_indent[MAX_INDENT_BUFFER];
|
|
560
|
+
char closing_indent[MAX_INDENT_BUFFER];
|
|
561
|
+
int decl_spaces = (indent_level + 1) * 2;
|
|
562
|
+
int closing_spaces = indent_level * 2;
|
|
563
|
+
memset(decl_indent, ' ', decl_spaces);
|
|
564
|
+
decl_indent[decl_spaces] = '\0';
|
|
565
|
+
memset(closing_indent, ' ', closing_spaces);
|
|
566
|
+
closing_indent[closing_spaces] = '\0';
|
|
567
|
+
|
|
555
568
|
// Serialize own declarations with indentation (each on its own line)
|
|
556
569
|
if (!NIL_P(declarations) && RARRAY_LEN(declarations) > 0) {
|
|
557
|
-
|
|
570
|
+
DEBUG_PRINTF("[SERIALIZE_RULE] Serializing %ld declarations with indent='%s' (%d spaces)\n",
|
|
571
|
+
RARRAY_LEN(declarations), decl_indent, decl_spaces);
|
|
572
|
+
serialize_declarations_formatted(result, declarations, decl_indent);
|
|
558
573
|
}
|
|
559
574
|
|
|
560
575
|
// Serialize nested children
|
|
561
576
|
serialize_children_only(result, rules_array, rule_idx, rule_to_media, parent_to_children,
|
|
562
577
|
selector, declarations, formatted, indent_level + 1);
|
|
563
578
|
|
|
579
|
+
rb_str_cat2(result, closing_indent);
|
|
564
580
|
rb_str_cat2(result, "}\n");
|
|
565
581
|
} else {
|
|
566
582
|
// Compact output
|
|
@@ -576,6 +592,9 @@ static void serialize_rule_with_children(VALUE result, VALUE rules_array, long r
|
|
|
576
592
|
|
|
577
593
|
rb_str_cat2(result, " }\n");
|
|
578
594
|
}
|
|
595
|
+
|
|
596
|
+
// Prevent compiler from optimizing away 'rule' before we're done with selector/declarations
|
|
597
|
+
RB_GC_GUARD(rule);
|
|
579
598
|
}
|
|
580
599
|
|
|
581
600
|
// New stylesheet serialization entry point - checks for nesting and delegates
|
|
@@ -626,6 +645,10 @@ static VALUE stylesheet_to_s_new(VALUE self, VALUE rules_array, VALUE media_inde
|
|
|
626
645
|
|
|
627
646
|
DEBUG_PRINTF("[MAP] parent_to_children map: %s\n", RSTRING_PTR(rb_inspect(parent_to_children)));
|
|
628
647
|
|
|
648
|
+
// Track media block state for proper opening/closing
|
|
649
|
+
VALUE current_media = Qnil;
|
|
650
|
+
int in_media_block = 0;
|
|
651
|
+
|
|
629
652
|
// Serialize only top-level rules (parent_rule_id == nil)
|
|
630
653
|
// Children are serialized recursively
|
|
631
654
|
DEBUG_PRINTF("[SERIALIZE] Starting serialization, total_rules=%ld\n", total_rules);
|
|
@@ -643,6 +666,34 @@ static VALUE stylesheet_to_s_new(VALUE self, VALUE rules_array, VALUE media_inde
|
|
|
643
666
|
continue;
|
|
644
667
|
}
|
|
645
668
|
|
|
669
|
+
// Get media for this rule
|
|
670
|
+
VALUE rule_id = rb_struct_aref(rule, INT2FIX(RULE_ID));
|
|
671
|
+
VALUE rule_media = rb_hash_aref(rule_to_media, rule_id);
|
|
672
|
+
|
|
673
|
+
// Handle media block transitions
|
|
674
|
+
if (NIL_P(rule_media)) {
|
|
675
|
+
// Not in media - close any open media block
|
|
676
|
+
if (in_media_block) {
|
|
677
|
+
rb_str_cat2(result, "}\n");
|
|
678
|
+
in_media_block = 0;
|
|
679
|
+
current_media = Qnil;
|
|
680
|
+
}
|
|
681
|
+
} else {
|
|
682
|
+
// In media - check if we need to open/change block
|
|
683
|
+
if (NIL_P(current_media) || !rb_equal(current_media, rule_media)) {
|
|
684
|
+
// Close previous media block if open
|
|
685
|
+
if (in_media_block) {
|
|
686
|
+
rb_str_cat2(result, "}\n");
|
|
687
|
+
}
|
|
688
|
+
// Open new media block
|
|
689
|
+
current_media = rule_media;
|
|
690
|
+
rb_str_cat2(result, "@media ");
|
|
691
|
+
rb_str_append(result, rb_sym2str(rule_media));
|
|
692
|
+
rb_str_cat2(result, " {\n");
|
|
693
|
+
in_media_block = 1;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
646
697
|
// Check if this is an AtRule
|
|
647
698
|
if (rb_obj_is_kind_of(rule, cAtRule)) {
|
|
648
699
|
serialize_at_rule(result, rule);
|
|
@@ -657,6 +708,11 @@ static VALUE stylesheet_to_s_new(VALUE self, VALUE rules_array, VALUE media_inde
|
|
|
657
708
|
);
|
|
658
709
|
}
|
|
659
710
|
|
|
711
|
+
// Close final media block if still open
|
|
712
|
+
if (in_media_block) {
|
|
713
|
+
rb_str_cat2(result, "}\n");
|
|
714
|
+
}
|
|
715
|
+
|
|
660
716
|
return result;
|
|
661
717
|
}
|
|
662
718
|
|
|
@@ -779,6 +835,10 @@ static VALUE stylesheet_to_formatted_s_new(VALUE self, VALUE rules_array, VALUE
|
|
|
779
835
|
}
|
|
780
836
|
}
|
|
781
837
|
|
|
838
|
+
// Track media block state for proper opening/closing
|
|
839
|
+
VALUE current_media = Qnil;
|
|
840
|
+
int in_media_block = 0;
|
|
841
|
+
|
|
782
842
|
// Serialize only top-level rules (parent_rule_id == nil)
|
|
783
843
|
for (long i = 0; i < total_rules; i++) {
|
|
784
844
|
VALUE rule = rb_ary_entry(rules_array, i);
|
|
@@ -789,20 +849,66 @@ static VALUE stylesheet_to_formatted_s_new(VALUE self, VALUE rules_array, VALUE
|
|
|
789
849
|
continue;
|
|
790
850
|
}
|
|
791
851
|
|
|
852
|
+
// Get media for this rule
|
|
853
|
+
VALUE rule_id = rb_struct_aref(rule, INT2FIX(RULE_ID));
|
|
854
|
+
VALUE rule_media = rb_hash_aref(rule_to_media, rule_id);
|
|
855
|
+
|
|
856
|
+
// Handle media block transitions
|
|
857
|
+
if (NIL_P(rule_media)) {
|
|
858
|
+
// Not in media - close any open media block
|
|
859
|
+
if (in_media_block) {
|
|
860
|
+
rb_str_cat2(result, "}\n");
|
|
861
|
+
in_media_block = 0;
|
|
862
|
+
current_media = Qnil;
|
|
863
|
+
|
|
864
|
+
// Add blank line after closing media block
|
|
865
|
+
rb_str_cat2(result, "\n");
|
|
866
|
+
}
|
|
867
|
+
} else {
|
|
868
|
+
// In media - check if we need to open/change block
|
|
869
|
+
if (NIL_P(current_media) || !rb_equal(current_media, rule_media)) {
|
|
870
|
+
// Close previous media block if open
|
|
871
|
+
if (in_media_block) {
|
|
872
|
+
rb_str_cat2(result, "}\n");
|
|
873
|
+
} else if (RSTRING_LEN(result) > 0) {
|
|
874
|
+
// Add blank line before new media block (except at start)
|
|
875
|
+
rb_str_cat2(result, "\n");
|
|
876
|
+
}
|
|
877
|
+
// Open new media block
|
|
878
|
+
current_media = rule_media;
|
|
879
|
+
rb_str_cat2(result, "@media ");
|
|
880
|
+
rb_str_append(result, rb_sym2str(rule_media));
|
|
881
|
+
rb_str_cat2(result, " {\n");
|
|
882
|
+
in_media_block = 1;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
792
886
|
// Check if this is an AtRule
|
|
793
887
|
if (rb_obj_is_kind_of(rule, cAtRule)) {
|
|
794
888
|
serialize_at_rule(result, rule);
|
|
795
889
|
continue;
|
|
796
890
|
}
|
|
797
891
|
|
|
892
|
+
// Add indent if inside media block
|
|
893
|
+
if (in_media_block) {
|
|
894
|
+
DEBUG_PRINTF("[FORMATTED] Adding base indent for media block\n");
|
|
895
|
+
rb_str_cat2(result, " ");
|
|
896
|
+
}
|
|
897
|
+
|
|
798
898
|
// Serialize rule with nested children
|
|
899
|
+
DEBUG_PRINTF("[FORMATTED] Calling serialize_rule_with_children, in_media_block=%d\n", in_media_block);
|
|
799
900
|
serialize_rule_with_children(
|
|
800
901
|
result, rules_array, i, rule_to_media, parent_to_children,
|
|
801
902
|
1, // formatted (with indentation)
|
|
802
|
-
0 // indent_level (
|
|
903
|
+
in_media_block ? 1 : 0 // indent_level (1 if inside media block, 0 otherwise)
|
|
803
904
|
);
|
|
804
905
|
}
|
|
805
906
|
|
|
907
|
+
// Close final media block if still open
|
|
908
|
+
if (in_media_block) {
|
|
909
|
+
rb_str_cat2(result, "}\n");
|
|
910
|
+
}
|
|
911
|
+
|
|
806
912
|
return result;
|
|
807
913
|
}
|
|
808
914
|
|
data/ext/cataract/cataract.h
CHANGED
|
@@ -120,6 +120,10 @@ static inline VALUE strip_string(const char *str, long len) {
|
|
|
120
120
|
#define MAX_PARSE_DEPTH 10 // Max recursion depth for nested @media/@supports blocks and CSS nesting
|
|
121
121
|
#endif
|
|
122
122
|
|
|
123
|
+
// Max buffer size for indent strings in serialization
|
|
124
|
+
// (MAX_PARSE_DEPTH + 1) * 2 spaces + null terminator, rounded up for safety
|
|
125
|
+
#define MAX_INDENT_BUFFER ((MAX_PARSE_DEPTH + 2) * 2 + 1)
|
|
126
|
+
|
|
123
127
|
#ifndef MAX_PROPERTY_NAME_LENGTH
|
|
124
128
|
#define MAX_PROPERTY_NAME_LENGTH 256 // Max length of CSS property name
|
|
125
129
|
#endif
|
|
@@ -355,6 +355,9 @@ module Cataract
|
|
|
355
355
|
current_media = nil
|
|
356
356
|
end
|
|
357
357
|
|
|
358
|
+
# Add blank line before base rule if we just closed a media block (ends with "}\n")
|
|
359
|
+
result << "\n" if result.length > 1 && result.getbyte(-1) == BYTE_NEWLINE && result.getbyte(-2) == BYTE_RBRACE
|
|
360
|
+
|
|
358
361
|
serialize_rule_with_nesting_formatted(result, rule, rule_children, rule_to_media, '')
|
|
359
362
|
else
|
|
360
363
|
if current_media.nil? || current_media != rule_media
|
data/lib/cataract/version.rb
CHANGED