hokusai-zero 0.1.3 → 0.1.5

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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -1
  3. data/Gemfile.lock +4 -0
  4. data/README.md +33 -83
  5. data/ast/src/core/hml.c +9 -9
  6. data/ast/src/core/text.c +21 -3
  7. data/ast/test/text.c +3 -3
  8. data/docs.sh +29 -0
  9. data/ext/extconf.rb +69 -14
  10. data/grammar/corpus/1_document.txt +24 -0
  11. data/grammar/corpus/6_styles.txt +23 -0
  12. data/grammar/grammar.js +4 -4
  13. data/grammar/src/grammar.json +19 -19
  14. data/grammar/src/parser.c +1904 -1956
  15. data/grammar/test.nml +10 -8
  16. data/hokusai.gemspec +3 -1
  17. data/ui/examples/assets/Delius-Regular.ttf +0 -0
  18. data/ui/examples/assets/DoHyeon.ttf +0 -0
  19. data/ui/examples/assets/Inter-Regular.ttf +0 -0
  20. data/ui/examples/assets/ernest.gif +0 -0
  21. data/ui/examples/assets/icons/audio-x-generic.png +0 -0
  22. data/ui/examples/assets/icons/image-x-generic.png +0 -0
  23. data/ui/examples/assets/icons/media-playback-pause.png +0 -0
  24. data/ui/examples/assets/icons/media-playback-start.png +0 -0
  25. data/ui/examples/assets/icons/media-playback-stop.png +0 -0
  26. data/ui/examples/assets/icons/package-x-generic.png +0 -0
  27. data/ui/examples/assets/icons/text-x-generic.png +0 -0
  28. data/ui/examples/assets/icons/video-x-generic.png +0 -0
  29. data/ui/examples/buddy.rb +16 -14
  30. data/ui/examples/clock.rb +38 -36
  31. data/ui/examples/counter.rb +100 -98
  32. data/ui/examples/dynamic.rb +115 -113
  33. data/ui/examples/foobar.rb +189 -187
  34. data/ui/examples/forum/file.rb +54 -0
  35. data/ui/examples/forum/music.rb +76 -0
  36. data/ui/examples/forum/post.rb +146 -0
  37. data/ui/examples/forum.rb +198 -0
  38. data/ui/examples/spreadsheet/csv.rb +261 -0
  39. data/ui/examples/spreadsheet.rb +138 -0
  40. data/ui/examples/stock.rb +86 -92
  41. data/ui/examples/stock_decider/option.rb +1 -1
  42. data/ui/examples/tic_tac_toe.rb +193 -191
  43. data/ui/lib/lib_hokusai.rb +2 -1
  44. data/ui/src/hokusai/assets/arrow-drop-down-line.png +0 -0
  45. data/ui/src/hokusai/assets/chevron-down.svg +1 -0
  46. data/ui/src/hokusai/assets/close-large-line.png +0 -0
  47. data/ui/src/hokusai/ast.rb +42 -43
  48. data/ui/src/hokusai/backends/raylib/font.rb +1 -2
  49. data/ui/src/hokusai/backends/raylib.rb +29 -17
  50. data/ui/src/hokusai/backends/sdl2/font.rb +13 -9
  51. data/ui/src/hokusai/backends/sdl2.rb +32 -5
  52. data/ui/src/hokusai/block.rb +14 -7
  53. data/ui/src/hokusai/blocks/dropdown.rb +205 -0
  54. data/ui/src/hokusai/blocks/hblock.rb +2 -2
  55. data/ui/src/hokusai/blocks/image.rb +6 -1
  56. data/ui/src/hokusai/blocks/input.rb +17 -0
  57. data/ui/src/hokusai/blocks/label.rb +5 -2
  58. data/ui/src/hokusai/blocks/modal.rb +62 -0
  59. data/ui/src/hokusai/blocks/panel.rb +2 -2
  60. data/ui/src/hokusai/blocks/scrollbar.rb +0 -2
  61. data/ui/src/hokusai/blocks/text.rb +12 -6
  62. data/ui/src/hokusai/blocks/titlebar/osx.rb +4 -4
  63. data/ui/src/hokusai/blocks/variable.rb +33 -0
  64. data/ui/src/hokusai/blocks/vblock.rb +1 -1
  65. data/ui/src/hokusai/commands/rect.rb +4 -4
  66. data/ui/src/hokusai/commands.rb +46 -29
  67. data/ui/src/hokusai/diff.rb +11 -0
  68. data/ui/src/hokusai/event.rb +19 -5
  69. data/ui/src/hokusai/events/mouse.rb +9 -1
  70. data/ui/src/hokusai/font.rb +60 -0
  71. data/ui/src/hokusai/meta.rb +11 -24
  72. data/ui/src/hokusai/node.rb +1 -1
  73. data/ui/src/hokusai/painter.rb +66 -8
  74. data/ui/src/hokusai/util/clamping_iterator.rb +5 -6
  75. data/ui/src/hokusai.rb +53 -4
  76. metadata +56 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f47573fc0ce1a9441f6f245e01d1fbabadb0304200bad43ad9335df021c2b192
4
- data.tar.gz: 6d7ea6070947c4858d4c39f061394556cfd981f5c30bc59d0c84c632f9f30ada
3
+ metadata.gz: 85dc0be97bf2f9c770f53b45a7790bd5b1dbfda261fb0f0da4f71c6c2c9c67eb
4
+ data.tar.gz: eb62a84b75ba128fbcd6b052e97a95853a0379572be85ea5584c98117af84b61
5
5
  SHA512:
6
- metadata.gz: e3c6601b81deae18295b0a942e1cecbf46e6cdf7c0a70b4ac86cbf5b362757e270188e7ac8090d0e4cc49391fe41701cb5bbfd93f83f4e0ff22cde94b6365236
7
- data.tar.gz: 94d7ce2d8d856c7ad2f1f6e2ce8727cb0e5152655f6df1d5d4645f338f497af702a501c874fd21530d5fc9d0660e7643166712c48d1e8b7c1a3d7b9af51c46c4
6
+ metadata.gz: 1ac8520911b6ba9b3112c68d1f1f653b179b43678c320489a732c97462ba930b637545f018aadc190418be97a6b9fac725eae62dc133ec576e253e87ac518cc6
7
+ data.tar.gz: fad9fccafdca8cca5ad855dd69b6e7741bd251c39152fb04bdcf1a9027dc47acb59661b247eeb2dbbc32dae09c7c8c7b1273eb1c55afd35db62301477da4e7c5
data/Gemfile CHANGED
@@ -5,11 +5,13 @@ gem "ffi", github: "ffi/ffi", submodules: true
5
5
  group :development, :test do
6
6
  gem "colorize"
7
7
  gem "concurrent-ruby", require: "concurrent"
8
- gem "memory_profiler"
8
+ gem "memory_profiler", require: false
9
+ gem "mini_portile2", "~> 2.0.0"
9
10
  gem "raylib-bindings"
10
11
  gem "rerun"
11
12
  gem "rest-client"
12
13
  gem "rspec"
13
14
  gem "sdl2-bindings"
14
15
  gem "thin", "1.8.0"
16
+ gem "yard", require: false
15
17
  end
data/Gemfile.lock CHANGED
@@ -26,6 +26,7 @@ GEM
26
26
  logger
27
27
  mime-types-data (~> 3.2015)
28
28
  mime-types-data (3.2024.1203)
29
+ mini_portile2 (2.0.0)
29
30
  netrc (0.11.0)
30
31
  rack (2.2.10)
31
32
  raylib-bindings (0.7.9)
@@ -67,6 +68,7 @@ GEM
67
68
  daemons (~> 1.0, >= 1.0.9)
68
69
  eventmachine (~> 1.0, >= 1.0.4)
69
70
  rack (>= 1, < 3)
71
+ yard (0.9.37)
70
72
 
71
73
  PLATFORMS
72
74
  aarch64-linux
@@ -80,12 +82,14 @@ DEPENDENCIES
80
82
  concurrent-ruby
81
83
  ffi!
82
84
  memory_profiler
85
+ mini_portile2 (~> 2.0.0)
83
86
  raylib-bindings
84
87
  rerun
85
88
  rest-client
86
89
  rspec
87
90
  sdl2-bindings
88
91
  thin (= 1.8.0)
92
+ yard
89
93
 
90
94
  BUNDLED WITH
91
95
  2.5.22
data/README.md CHANGED
@@ -3,17 +3,19 @@
3
3
  A Ruby library for authoring GUI applications
4
4
 
5
5
  [![status-badge](https://ci.skinnyjames.net/api/badges/skinnyjames/hokusai/status.svg)](https://ci.skinnyjames.net/skinnyjames/hokusai)
6
+ [![guides](https://img.shields.io/badge/guide-skinnyjames.net-black.svg)](https://hokusai.skinnyjames.net)
7
+ [![docs](https://img.shields.io/badge/documentation-codeberg_pages-blue.svg)](https://skinnyjames.codeberg.page/hokusai/)
6
8
  [![license](https://img.shields.io/badge/license-peer_production-teal.svg)](https://wiki.p2pfoundation.net/Peer_Production_License)
7
9
 
8
10
  ## Getting started
9
11
 
10
- The build tooling of this project is [xmake](https://xmake.io/#/). You will need it to compile dependencies and run demos.
11
-
12
- Hokusai contains a tree-sitter grammar to parse templates, and uses `md4c` to parse markdown.
12
+ In your Gemfile
13
13
 
14
- When compiling the C portion of hokusai, tree-sitter will be statically linked.
14
+ ```ruby
15
+ gem "hokusai-zero", "0.1.4"
16
+ ```
15
17
 
16
- ## In order to run an application, you will also need to install a backend
18
+ ## In order to run an application, you will need to install a backend
17
19
 
18
20
  ### Raylib
19
21
 
@@ -21,7 +23,7 @@ When compiling the C portion of hokusai, tree-sitter will be statically linked.
21
23
  * Write your app
22
24
  * Run app with `RAYLIB_PATH=/libpath/for/libraylib.(so|dylib) ruby <your app>.rb`
23
25
 
24
- ### SDL
26
+ ### SDL2
25
27
 
26
28
  * Install the following deps
27
29
 
@@ -33,13 +35,6 @@ When compiling the C portion of hokusai, tree-sitter will be statically linked.
33
35
  * Write your app
34
36
  * Run app with `SDL_PATH=/libpath/for/libsdl.(so|dylib) ruby <your app>.rb`
35
37
 
36
-
37
- ## Gemfile
38
-
39
- ```ruby
40
- gem "hokusai-zero"
41
- ```
42
-
43
38
  ## Example counter application
44
39
 
45
40
  ```ruby
@@ -47,86 +42,35 @@ require "hokusai"
47
42
  require "hokusai/backends/raylib"
48
43
 
49
44
  class Counter < Hokusai::Block
50
- style <<~EOF
51
- [style]
52
- additionStyles {
53
- background: rgb(214, 49, 24);
54
- rounding: 0.0;
55
- outline: outline(1,4,4,1);
56
- outline_color: rgb(216, 26, 137);
57
- }
58
-
59
- additionLabel {
60
- size: 40;
61
- color: rgb(255,255,255);
62
- }
63
-
64
- subtractStyles {
65
- background: rgb(0, 85, 170);
66
- rounding: 0.0;
67
- }
68
-
69
- subtractLabel {
70
- size: 50;
71
- color: rgb(255,255,255);
72
- }
73
-
74
- scrollbar {
75
- width: 25;
76
- control_height: 100;
77
- control_padding: 5;
78
- control_rounding: 5;
79
- }
80
- EOF
81
-
82
45
  template <<-EOF
83
46
  [template]
84
- hblock { @keypress="update_keys"}
85
- vblock
86
- hblock
87
- label#count {
88
- :content="count"
89
- size="130"
90
- :color="count_color"
47
+ vblock
48
+ hblock
49
+ label {
50
+ :content="count"
51
+ size="130"
52
+ :color="count_color"
53
+ }
54
+ hblock
55
+ vblock
56
+ label {
57
+ content="Add"
58
+ @click="increment"
59
+ }
60
+ vblock
61
+ label {
62
+ content="Subtract"
63
+ @click="decrement"
91
64
  }
92
- hblock
93
- vblock#add { ...additionStyles }
94
- label {
95
- content="Add"
96
- @click="increment"
97
- ...additionLabel
98
- }
99
- vblock#subtract { ...subtractStyles }
100
- label {
101
- content="Subtract"
102
- @click="decrement"
103
- ...subtractLabel
104
- }
105
- [if="count_positive"]
106
- scrollbar { ...scrollbar }
107
65
  EOF
108
66
 
109
67
  uses(
110
68
  vblock: Hokusai::Blocks::Vblock,
111
69
  hblock: Hokusai::Blocks::Hblock,
112
70
  label: Hokusai::Blocks::Label,
113
- scrollbar: Hokusai::Blocks::Scrollbar,
114
- image: Hokusai::Blocks::Image
115
71
  )
116
72
 
117
- attr_accessor :count, :keys
118
-
119
- def count_positive
120
- count > 0
121
- end
122
-
123
- def modal
124
- !keys.empty?
125
- end
126
-
127
- def update_keys(event)
128
- @keys << event.char
129
- end
73
+ attr_accessor :count
130
74
 
131
75
  def increment(event)
132
76
  self.count += 1
@@ -142,7 +86,7 @@ class Counter < Hokusai::Block
142
86
 
143
87
  def initialize(**args)
144
88
  @count = 0
145
- @keys = ""
89
+
146
90
  super(**args)
147
91
  end
148
92
  end
@@ -156,6 +100,12 @@ end
156
100
 
157
101
  ## Development
158
102
 
103
+ The build tooling of this project is [xmake](https://xmake.io/#/). You will need it to compile dependencies and run demos.
104
+
105
+ Hokusai contains a tree-sitter grammar to parse templates, and uses `md4c` to parse markdown.
106
+
107
+ When compiling the C portion of hokusai, tree-sitter will be statically linked.
108
+
159
109
  Requirements:
160
110
  * [xmake](https://xmake.io/#/) to build dependencies
161
111
  * Ruby to run applications
data/ast/src/core/hml.c CHANGED
@@ -109,7 +109,7 @@ hoku_ast_func_call* hoku_ast_walk_func(TSNode node, char* template, int level)
109
109
  {
110
110
  if (init->args_len >= 9)
111
111
  {
112
- printf("maxed args!\n");
112
+ // printf("maxed args!\n");
113
113
  break;
114
114
  }
115
115
  char* str = hoku_get_tag(arg, template);
@@ -456,17 +456,17 @@ hoku_style_attribute* hoku_walk_style_attributes(TSNode node, char* template)
456
456
 
457
457
  if (function_name)
458
458
  {
459
- printf("setting func name!\n");
459
+ // printf("setting func name!\n");
460
460
  attribute->function_name = strdup(function_name);
461
461
  if (attribute->function_name == NULL) return NULL;
462
462
  free(function_name);
463
- printf("fter set func name\n");
463
+ // printf("fter set func name\n");
464
464
  }
465
465
 
466
466
  free(attribute_name);
467
467
  free(value);
468
468
 
469
- printf("after free!\n");
469
+ // printf("after free!\n");
470
470
 
471
471
  if (top == NULL)
472
472
  {
@@ -474,9 +474,9 @@ hoku_style_attribute* hoku_walk_style_attributes(TSNode node, char* template)
474
474
  }
475
475
  else
476
476
  {
477
- printf("append!\n %p, %p\n", top, attribute);
477
+ // printf("append!\n %p, %p\n", top, attribute);
478
478
  hoku_style_attribute_append(top, attribute);
479
- printf("after append\n");
479
+ // printf("after append\n");
480
480
  }
481
481
 
482
482
  attribute_node = ts_node_next_named_sibling(attribute_node);
@@ -501,9 +501,9 @@ hoku_style* hoku_walk_style_template(TSNode node, char* template)
501
501
 
502
502
  TSNode style_children_node = ts_node_next_named_sibling(style_name_node);
503
503
 
504
- printf("walking attributes!\n");
504
+ // printf("walking attributes!\n");
505
505
  hoku_style_attribute* attributes = hoku_walk_style_attributes(style_children_node, template);
506
- printf("after walk attributes!\n");
506
+ // printf("after walk attributes!\n");
507
507
  if (attributes == NULL) return NULL;
508
508
  style->attributes = attributes;
509
509
 
@@ -555,7 +555,7 @@ int hoku_style_from_template(hoku_style** out, char* template)
555
555
 
556
556
  hoku_style* style = hoku_walk_style_template(templ, template);
557
557
 
558
- printf("after walk style!\n");
558
+ // printf("after walk style!\n");
559
559
  if (style == NULL)
560
560
  {
561
561
  ts_tree_delete(tree);
data/ast/src/core/text.c CHANGED
@@ -3,6 +3,26 @@
3
3
 
4
4
  #include "text.h"
5
5
 
6
+ #ifdef _WIN32
7
+ size_t my_strnlen(const char* src, size_t n) {
8
+ size_t len = 0;
9
+ while (len < n && src[len]) len++;
10
+ return len;
11
+ }
12
+
13
+ char* strndup(const char* s, size_t n) {
14
+ size_t len = my_strnlen(s, n);
15
+ char* p = malloc(len + 1);
16
+ if (p)
17
+ {
18
+ memcpy(p, s, len);
19
+ p[len] = '\0';
20
+ }
21
+
22
+ return p;
23
+ }
24
+ #endif
25
+
6
26
  int hoku_text_char_init(hoku_char** character, int offset, int width)
7
27
  {
8
28
  hoku_char* init = malloc(sizeof(hoku_char));
@@ -55,7 +75,7 @@ hoku_char* hoku_text_segment_split(hoku_segment* segment, int at)
55
75
  hoku_char* current_char = head->chars;
56
76
  if (at > head->size) return NULL;
57
77
 
58
- printf("at: %d\n", at);
78
+ // printf("at: %d\n", at);
59
79
  int i = 0;
60
80
  for (i = 1; i < at; i++)
61
81
  {
@@ -692,8 +712,6 @@ int hoku_text_clamp(hoku_clamping** out, char* text, float width, float initial,
692
712
  // hard break on line
693
713
  else
694
714
  {
695
- printf("easy branch %d\n", total_offset);
696
-
697
715
  // make a new segment
698
716
  hoku_segment* segment;
699
717
  if (hoku_text_segment_init(&segment, total_offset) != 0) return -1;
data/ast/test/text.c CHANGED
@@ -30,7 +30,7 @@ TEST test_hoku_clamp_basic()
30
30
  for (d = 0; d < 2; d++)
31
31
  {
32
32
 
33
- printf("[seg: %d] %d\n", i, d);
33
+ // printf("[seg: %d] %d\n", i, d);
34
34
  ASSERT_NEQ(NULL, chr);
35
35
  ASSERT_EQ_FMT(i * 2 + d, chr->offset, "%d");
36
36
  ASSERT_EQ_FMT(2, seg->size, "%d");
@@ -80,7 +80,7 @@ TEST test_hoku_clamp_file()
80
80
  // we can now close the file
81
81
  fclose(fh); fh = NULL;
82
82
 
83
- printf("%s\n", buffer);
83
+ // printf("%s\n", buffer);
84
84
 
85
85
  hoku_clamping* clamp;
86
86
  int ret = hoku_text_clamp(&clamp, buffer, 400, 0.0, NULL, test_char_width_cb);
@@ -102,7 +102,7 @@ TEST test_hoku_clamp_markdown()
102
102
  hoku_clamping* clamp;
103
103
  int ret = hoku_text_md_clamp(&clamp, "hello _world_\nMy my **my**", 20, 0.0, NULL, test_char_width_cb);
104
104
  ASSERT_EQ_FMT(0, ret, "%d");
105
- printf("clamp text: %s\n", clamp->text);
105
+ // printf("clamp text: %s\n", clamp->text);
106
106
  PASS();
107
107
 
108
108
  }
data/docs.sh ADDED
@@ -0,0 +1,29 @@
1
+ #! /bin/bash
2
+
3
+ build_directory="doc"
4
+ build_branch="pages"
5
+
6
+ # delete previous site built, if it exists
7
+ if [ -d "$build_directory" ]; then
8
+ echo "Found previous site build, deleting it"
9
+ rm -rf $build_directory
10
+ fi
11
+
12
+ # get remote origin url, e.g. https://codeberg.org/user/repo.git
13
+ remote_origin_url=$(git config --get remote.origin.url)
14
+
15
+ # generate hugo static site to `build` directory
16
+ bundle exec yardoc
17
+
18
+ # initialize a git repo in build_directory and checkout to build_branch
19
+ cd $build_directory
20
+ git init
21
+ git checkout -b $build_branch
22
+
23
+ # stage all files except .gitignore (don't want it in the static site)
24
+ git add -- . ':!.gitignore'
25
+
26
+ # commit static site files and force push to build_branch of the origin
27
+ git commit -m "build: update static site"
28
+ git remote add origin $remote_origin_url
29
+ git push --force origin $build_branch
data/ext/extconf.rb CHANGED
@@ -1,29 +1,84 @@
1
1
  require "mkmf"
2
+ require "mini_portile2"
3
+
4
+ if MiniPortile.darwin?
5
+ suffix = "dylib"
6
+ elsif MiniPortile.linux?
7
+ suffix = "so"
8
+ elsif MiniPortile.windows?
9
+ suffix = "dll"
10
+ else
11
+ raise "Currently only supporting darwin and linux"
12
+ end
13
+
14
+ tree_sitter = MiniPortile.new("libtree-sitter", "master", make_command: "make")
15
+ tree_sitter.files = ["https://github.com/tree-sitter/tree-sitter/archive/refs/heads/master.zip"]
16
+ tree_sitter.tap do |t|
17
+ if t.source_directory
18
+ t.prepare_build_directory
19
+ else
20
+ t.download unless t.downloaded?
21
+ t.extract
22
+ t.patch
23
+ end
24
+
25
+ def t.install
26
+ return if installed?
27
+
28
+ execute('install', %Q(#{make_cmd} all install CC=gcc AR=ar), { env: { "PREFIX" => File.expand_path(port_path) }})
29
+ end
30
+
31
+ t.install
32
+ end
33
+
34
+ tree_sitter.activate
35
+
36
+ md4c = MiniPortileCMake.new("md4c", "0.5.2")
37
+ md4c.files = ["https://github.com/mity/md4c/archive/refs/tags/release-0.5.2.zip"]
38
+
39
+ def md4c.cmake_compile_flags
40
+ [*super, "-DBUILD_SHARED_LIBS=OFF"]
41
+ end
42
+
43
+ md4c.cook
44
+ md4c.activate
45
+
46
+ pre = "#{__dir__}/.."
47
+ cwd = "#{__dir__}"
48
+
49
+ files = %w[ast/src/core/hml.c ast/src/core/ast.c ast/rc/core/style.c ast/src/core/input.c ast/src/core/component.c ast/src/core/util.c ast/src/core/text.c grammar/src/parser.c grammar/src/scanner.c ast/include/hashmap.c]
50
+ objects = %w[hml.o ast.o style.o input.o component.o util.o text.o parser.o scanner.o hashmap.o]
51
+ libraries = ["#{tree_sitter.path}/lib/libtree-sitter.a", "#{md4c.path}/lib/libmd4c.a"]
52
+
53
+ if MiniPortile.windows?
54
+ cflags = "-shared -Wall -Wl,--export-all-symbols -Wl,--enable-auto-import"
55
+ mkdir = "mkdir #{pre}\\vendor\\lib"
56
+ else
57
+ cflags = "-shared -Wall"
58
+ mkdir = "mkdir -p #{pre}/vendor/lib"
59
+ end
2
60
 
3
61
  File.open("Makefile", "w") do |io|
4
62
  io << <<~EOF
63
+ src_files = #{files.map {|file| "#{pre}/#{file}"}.join(" ")}
64
+ object_files = #{objects.map {|file| "#{cwd}/#{file}"}.join(" ")}
65
+ libraries = #{libraries.join(" ")}
66
+ src_files = #{tree_sitter.path}/lib/libtree-sitter.a #{md4c.path}/lib/libmd4c.a #{pre}/ast/src/core/hml.c #{pre}/ast/src/core/ast.c #{pre}/ast/src/core/style.c #{pre}/ast/src/core/input.c #{pre}/ast/src/core/component.c #{pre}/ast/src/core/util.c #{pre}/ast/src/core/text.c #{pre}/grammar/src/parser.c #{pre}/grammar/src/scanner.c #{pre}/ast/include/hashmap.c
67
+ includes = -I#{pre}/ast/include -I#{pre}/ast/src -I#{pre}/grammar/src -I#{tree_sitter.path}/include -I#{md4c.path}/include
5
68
  all: clean hokusai
69
+
70
+ .PHONY: hokuasi
6
71
 
7
72
  install:
8
73
  #{"\t"}echo "done"
9
74
 
10
- vendor/lib/libtree-sitter.a:
11
- #{"\t"}xmake q -y hoku-tree-sitter
12
-
13
- vendor/lib/libmd4c.a:
14
- #{"\t"}xmake q -y hoku-md4c
15
-
16
- hokusai: vendor/lib/libmd4c.a vendor/lib/libtree-sitter.a
17
- #{"\t"}xmake b -y hokusai
75
+ hokusai:
76
+ #{"\t"}#{mkdir}
77
+ #{"\t"}gcc -c $(includes) $(src_files) $(libraries)
78
+ #{"\t"}gcc #{cflags} $(includes) -o #{pre}/vendor/lib/libhokusai.#{suffix} $(object_files) $(libraries)
18
79
 
19
80
  clean:
20
- #{"\t"}xmake clean
21
- #{"\t"}xmake q -y --uninstall hoku-tree-sitter
22
- #{"\t"}xmake q -y --uninstall hoku-md4c
23
- #{"\t"}xrepo clean -y hoku-tree-sitter
24
- #{"\t"}xrepo clean -y hoku-md4c
25
81
  #{"\t"}rm -f vendor/lib/libhokusai.*
26
82
  #{"\t"}rm -f vendor/lib/libmd4c.*
27
- #{"\t"}rm -f vendor/lib/libtree-sitter.*
28
83
  EOF
29
84
  end
@@ -129,3 +129,27 @@ Attributes (Multiline)
129
129
  (name)
130
130
  (function
131
131
  (name)))))))))
132
+
133
+ ==========
134
+ Attributes (expressions)
135
+ ==========
136
+ [template]
137
+ top
138
+ image {
139
+ :source="post.title"
140
+ }
141
+ -----
142
+
143
+ (document
144
+ (template
145
+ (element
146
+ (name)
147
+ (children
148
+ (element
149
+ (name)
150
+ (attributes
151
+ (prop
152
+ (computed)
153
+ (name)
154
+ (function
155
+ (name)))))))))
@@ -79,3 +79,26 @@ styleSpread {
79
79
  (style_func
80
80
  (function)
81
81
  (value)))))))
82
+
83
+ ========
84
+ pathname
85
+ ========
86
+
87
+ [style]
88
+ ernestImage {
89
+ height: 80;
90
+ source: "assets/ernest.gif";
91
+ }
92
+ ---------
93
+
94
+ (document
95
+ (style_template
96
+ (style
97
+ (name)
98
+ (children
99
+ (element
100
+ (name)
101
+ (style_int))
102
+ (element
103
+ (name)
104
+ (style_string))))))
data/grammar/grammar.js CHANGED
@@ -171,11 +171,11 @@ module.exports = grammar({
171
171
  $._colon,
172
172
  optional(/\s+/),
173
173
  choice(
174
- seq($._quote, alias($._method, $.style_string), $._quote),
175
174
  $.style_float,
176
175
  $.style_int,
177
176
  $.style_bool,
178
- $.style_func
177
+ $.style_func,
178
+ seq($._quote, alias($._any, $.style_string), $._quote),
179
179
  ),
180
180
  $._semi,
181
181
  optional(/\s*/)
@@ -250,11 +250,11 @@ module.exports = grammar({
250
250
  _else_key: $ => "else",
251
251
  _template_key: $ => "template",
252
252
  _style_key: $ => "style",
253
- _any: $ => /[A-Za-z0-9\,\_\-\=\*\&\^\%\.\$\#\s]*/,
253
+ _any: $ => /[^\"\n\;\(\)]+/,
254
254
  _method: $ => /[A-Za-z][A-Za-z0-9\_]*/,
255
255
  _word: $ => /[A-Za-z][A-Za-z0-9_-]*/,
256
256
  _float: $ => /\d+\.\d+/,
257
- _static_string: $ => /[A-Za-z0-9_\-,]*/,
257
+ _static_string: $ => /[A-Za-z0-9_\-,\.]*/,
258
258
  _attributes_start: $ => / *\{/,
259
259
  _attributes_end: $ => /\} */,
260
260
  _macro_start: $ => "[",
@@ -799,6 +799,22 @@
799
799
  {
800
800
  "type": "CHOICE",
801
801
  "members": [
802
+ {
803
+ "type": "SYMBOL",
804
+ "name": "style_float"
805
+ },
806
+ {
807
+ "type": "SYMBOL",
808
+ "name": "style_int"
809
+ },
810
+ {
811
+ "type": "SYMBOL",
812
+ "name": "style_bool"
813
+ },
814
+ {
815
+ "type": "SYMBOL",
816
+ "name": "style_func"
817
+ },
802
818
  {
803
819
  "type": "SEQ",
804
820
  "members": [
@@ -810,7 +826,7 @@
810
826
  "type": "ALIAS",
811
827
  "content": {
812
828
  "type": "SYMBOL",
813
- "name": "_method"
829
+ "name": "_any"
814
830
  },
815
831
  "named": true,
816
832
  "value": "style_string"
@@ -820,22 +836,6 @@
820
836
  "name": "_quote"
821
837
  }
822
838
  ]
823
- },
824
- {
825
- "type": "SYMBOL",
826
- "name": "style_float"
827
- },
828
- {
829
- "type": "SYMBOL",
830
- "name": "style_int"
831
- },
832
- {
833
- "type": "SYMBOL",
834
- "name": "style_bool"
835
- },
836
- {
837
- "type": "SYMBOL",
838
- "name": "style_func"
839
839
  }
840
840
  ]
841
841
  },
@@ -1151,7 +1151,7 @@
1151
1151
  },
1152
1152
  "_any": {
1153
1153
  "type": "PATTERN",
1154
- "value": "[A-Za-z0-9\\,\\_\\-\\=\\*\\&\\^\\%\\.\\$\\#\\s]*"
1154
+ "value": "[^\\\"\\n\\;\\(\\)]+"
1155
1155
  },
1156
1156
  "_method": {
1157
1157
  "type": "PATTERN",
@@ -1167,7 +1167,7 @@
1167
1167
  },
1168
1168
  "_static_string": {
1169
1169
  "type": "PATTERN",
1170
- "value": "[A-Za-z0-9_\\-,]*"
1170
+ "value": "[A-Za-z0-9_\\-,\\.]*"
1171
1171
  },
1172
1172
  "_attributes_start": {
1173
1173
  "type": "PATTERN",