rouge-picat 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4bf3b0a384725113f58d6e2f389414168405f241261964102744e41758a71942
4
+ data.tar.gz: 39e997b9b5d4d16a29f063f659830c438c489a0b01e8242f0ae574a15d1fc374
5
+ SHA512:
6
+ metadata.gz: a63a045b27fbe55b9c8d5323f08bd8c41e9a3ae60d3b38973b1284af2168d43d5c4c671b7fd0dae2878c880603e54ba7166c52985655f98d0f158bdb1b118907
7
+ data.tar.gz: 794ef72e1d23cc3b6ce7318569e7044cb315ab950e1a4d8a007399da919d9ca73dd36469911cc69306956806c0cd9cc197e3f29182ccf6ee57bea0a50bd4f532
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'minitest'
6
+ gem 'rake'
7
+ gem 'webrick'
8
+ gem 'rackup'
data/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Arclight Automata
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # rouge-picat
2
+
3
+ A [Rouge](https://github.com/rouge-ruby/rouge) plugin that adds syntax
4
+ highlighting support for the [Picat](http://picat-lang.org/) programming
5
+ language.
6
+
7
+ Picat is a logic-based multi-paradigm programming language aimed at
8
+ general-purpose applications, combining features from logic programming,
9
+ functional programming, and scripting languages.
10
+
11
+ ## Background
12
+
13
+ This lexer was originally submitted to Rouge core as
14
+ [rouge-ruby/rouge#2110](https://github.com/rouge-ruby/rouge/pull/2110).
15
+ The Rouge maintainers declined the PR and asked that new languages be
16
+ distributed as plugin gems instead — this repository is that plugin.
17
+
18
+ ## Installation
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ ```ruby
23
+ gem 'rouge-picat'
24
+ ```
25
+
26
+ Or install it directly:
27
+
28
+ ```console
29
+ $ gem install rouge-picat
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ Require the gem after Rouge and the lexer registers itself under the
35
+ `picat` tag:
36
+
37
+ ```ruby
38
+ require 'rouge'
39
+ require 'rouge-picat'
40
+
41
+ source = File.read('queens.pi')
42
+ formatter = Rouge::Formatters::HTML.new
43
+ lexer = Rouge::Lexer.find('picat')
44
+
45
+ formatter.format(lexer.lex(source))
46
+ ```
47
+
48
+ The lexer is also picked up automatically when guessing by filename
49
+ (`*.pi`) or mimetype (`text/x-picat`).
50
+
51
+ ## Development
52
+
53
+ * `spec/sample.pi` holds the visual spec - this is text intended to
54
+ stress-test the lexer and catch any weirdnesses or errors.
55
+ * `ruby preview.rb` will output the highlighted sample to the terminal.
56
+ Set the environment variable `DEBUG=1` to instead output detailed debugging
57
+ information.
58
+ * `rake` or `rake spec` runs the tests.
59
+ * `rake server` runs a preview server on port 9292, which hot-reloads the lexer.
60
+
61
+ This plugin follows the structure of the
62
+ [rouge-plugin-example](https://github.com/rouge-ruby/rouge-plugin-example)
63
+ repository. See also Rouge's [Lexer Development Guide][lexer-dev-doc].
64
+
65
+ [lexer-dev-doc]: https://rouge-ruby.github.io/docs/file.LexerDevelopment.html "Rouge's lexer development guide"
66
+
67
+ ## License
68
+
69
+ MIT - see [LICENSE](LICENSE).
@@ -0,0 +1,154 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
4
+ require 'rouge' unless defined?(Rouge)
5
+
6
+ module RougePicat
7
+ class Picat < Rouge::RegexLexer
8
+ title "Picat"
9
+ desc "The Picat programming language (picat-lang.org)"
10
+
11
+ tag 'picat'
12
+ filenames '*.pi'
13
+ mimetypes 'text/x-picat'
14
+
15
+ demo <<~'DEMO'
16
+ module main.
17
+
18
+ import util.
19
+
20
+ % Calculate factorial using recursion
21
+ fact(0) = 1.
22
+ fact(N) = N * fact(N-1) => N > 0.
23
+
24
+ main =>
25
+ X = 5,
26
+ writef("Factorial of %d is %d\n", X, fact(X)),
27
+ Sum = sum([1,2,3]),
28
+ writef("Sum = %d\n", Sum).
29
+ DEMO
30
+
31
+ def self.keywords
32
+ @keywords ||= Set.new %w(
33
+ module import private table index
34
+ if else elseif end foreach while do
35
+ not fail true false
36
+ catch try in
37
+ repeat once var throw
38
+ )
39
+ end
40
+
41
+ def self.builtins
42
+ @builtins ||= Set.new %w(
43
+ append write writeln print println member length
44
+ solve solve_all new_array new_map new_set
45
+ min max sum prod floor ceiling round
46
+ abs sqrt sin cos tan log exp
47
+ open close printf get_heap_map get_global_map
48
+ get_table_map instance final action solve
49
+ )
50
+ end
51
+
52
+ state :root do
53
+ rule %r/\s+/m, Text
54
+ rule %r/%.*$/, Comment::Single
55
+ rule %r/\/\*/, Comment::Multiline, :multiline_comment
56
+
57
+ # Module declaration
58
+ rule %r/(module)(\s+)([a-z][a-zA-Z0-9_]*)/m do
59
+ groups Keyword::Namespace, Text::Whitespace, Name::Namespace
60
+ end
61
+
62
+ # Import declaration
63
+ rule %r/(import)(\s+)([a-z][a-zA-Z0-9_]*)/m do
64
+ groups Keyword::Namespace, Text::Whitespace, Name::Namespace
65
+ push :import_list
66
+ end
67
+
68
+ # Handle bare 'import' without immediate module name
69
+ rule %r/(import)(\s*$)/ do
70
+ groups Keyword::Namespace, Text::Whitespace
71
+ push :import_list
72
+ end
73
+
74
+ # Numbers with underscore separators (must come before regular integers)
75
+ rule %r/\d+(_\d+)+/, Num::Integer
76
+
77
+ # Other numbers
78
+ rule %r/0[xX][0-9a-fA-F]+/, Num::Hex
79
+ rule %r/0[oO][0-7]+/, Num::Oct
80
+ rule %r/0[bB][01]+/, Num::Bin
81
+ rule %r/[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?/, Num::Float
82
+ rule %r/[0-9]+/, Num::Integer
83
+
84
+ # Strings and Atoms
85
+ rule %r/"(\\.|[^"])*"/, Str::Double
86
+ rule %r/'(\\.|[^'])*'/, Str::Symbol # Quoted atoms
87
+
88
+ # Variables
89
+ rule %r/[A-Z_][A-Za-z0-9_]*/, Name::Variable
90
+
91
+ # Keywords and builtins (moved before other identifier patterns)
92
+ rule %r/[a-z][a-zA-Z0-9_]*(?=[^a-zA-Z0-9_])/ do |m|
93
+ if self.class.keywords.include? m[0]
94
+ token Keyword
95
+ elsif self.class.builtins.include? m[0]
96
+ token Name::Builtin
97
+ else
98
+ token Name
99
+ end
100
+ end
101
+
102
+ # Module-qualified names
103
+ rule %r/([a-z][a-zA-Z0-9_]*)(\.)([a-z][a-zA-Z0-9_]*)/ do
104
+ groups Name::Namespace, Punctuation, Name::Function
105
+ end
106
+
107
+ # Structure notation
108
+ rule %r/\$[a-z][a-zA-Z0-9_]*/, Name::Class
109
+
110
+ # Other identifiers
111
+ rule %r/[a-z][a-zA-Z0-9_]*/, Name
112
+
113
+ # Import items (commas and periods)
114
+ rule %r/,|\./, Punctuation
115
+
116
+ # Constraint operators
117
+ rule %r/#=>|#<=>|#\/\\|#\\\/|#\^|#~|#=|#!=|#<|#=<|#<=|#>|#>=/, Operator
118
+
119
+ # Term comparison operators
120
+ rule %r/@<|@=<|@<=|@>|@>=/, Operator
121
+
122
+ # DCG notation
123
+ rule %r/-->/, Operator
124
+
125
+ # List comprehension separator
126
+ rule %r/\s+:\s+/, Punctuation
127
+
128
+ # Range notation
129
+ rule %r/\.\./, Operator
130
+
131
+ # List cons operator (|)
132
+ rule %r/\|/, Punctuation
133
+
134
+ # Other operators and punctuation
135
+ rule %r/=>|:=|\?=>|==|!=|=<|>=|::|\+\+|--|!|;|:|\.|=|<|>|\+|-|\*|\/|\[|\]|\{|\}|\(|\)|\$|@/, Operator
136
+
137
+ # Table/index declarations
138
+ rule %r/(\+|-)(?=[\s,\)])/, Operator
139
+ end
140
+
141
+ state :multiline_comment do
142
+ rule %r/[^*\/]+/m, Comment::Multiline
143
+ rule %r/\*\//, Comment::Multiline, :pop!
144
+ rule %r/[\*\/]/, Comment::Multiline
145
+ end
146
+
147
+ state :import_list do
148
+ rule %r/\s+/m, Text::Whitespace
149
+ rule %r/[a-z][a-zA-Z0-9_]*/, Name::Namespace
150
+ rule %r/,/, Punctuation
151
+ rule %r/\./, Punctuation, :pop!
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "rouge-picat"
5
+ s.version = "0.1.0"
6
+ s.authors = ["Arclight Automata"]
7
+ s.email = ["root@arclight.run"]
8
+ s.summary = "A Picat language plugin for Rouge"
9
+ s.description = <<-desc.strip.gsub(/\s+/, ' ')
10
+ Support for the Picat programming language (picat-lang.org) for Rouge
11
+ desc
12
+
13
+ s.homepage = "https://github.com/arclight-automata/rouge-picat"
14
+ s.files = Dir['Gemfile', 'LICENSE', 'README.md', 'rouge-picat.gemspec', 'lib/**/*.rb']
15
+ s.licenses = ['MIT']
16
+ s.required_ruby_version = '>= 3.0'
17
+
18
+ s.add_dependency 'rouge', '>= 4.0', '< 6'
19
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rouge-picat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Arclight Automata
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2026-08-05 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rouge
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '4.0'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '6'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '4.0'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '6'
32
+ description: Support for the Picat programming language (picat-lang.org) for Rouge
33
+ email:
34
+ - root@arclight.run
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - Gemfile
40
+ - LICENSE
41
+ - README.md
42
+ - lib/rouge-picat.rb
43
+ - rouge-picat.gemspec
44
+ homepage: https://github.com/arclight-automata/rouge-picat
45
+ licenses:
46
+ - MIT
47
+ metadata: {}
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '3.0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubygems_version: 3.6.2
63
+ specification_version: 4
64
+ summary: A Picat language plugin for Rouge
65
+ test_files: []