Skip to content

Commit 12456c5

Browse files
committed
add lua lang
1 parent a46a170 commit 12456c5

9 files changed

Lines changed: 1155 additions & 11 deletions

File tree

app/src/main/java/ir/ninjacoder/code/MainActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ protected void onCreate(Bundle savedInstanceState) {
5050

5151
binding.btn.setOnClickListener(
5252
v -> {
53-
binding.et.takeScreenshot(FormatImage.VECTORDRAWABLE);
53+
binding.et.takeScreenshot();
5454
});
5555

5656
ad.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#AndroidIDE: enforce UTF-8 & locale for Gradle daemon
2-
#Fri Oct 31 12:31:56 GMT 2025
2+
#Fri Oct 31 15:47:16 GMT 2025
33
android.suppressUnsupportedCompileSdk=35
44
android.nonTransitiveRClass=false
55
-Dfile.encoding=UTF-8

snapcode/src/main/java/ir/ninjacoder/codesnap/LangType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public enum LangType {
2424
RUBY(".rb"),
2525
MARKDOWN(".md"),
2626
ZIG(".zig"),
27+
LUA(".lua"),
2728
NONE("");
2829

2930
private final String langname;
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
package ir.ninjacoder.codesnap.Utils;
2+
3+
import ir.ninjacoder.codesnap.LangType;
4+
import ir.ninjacoder.codesnap.antlr4.lua.LuaLexer;
5+
import ir.ninjacoder.codesnap.colorhelper.ColorHelper;
6+
import android.text.SpannableStringBuilder;
7+
import ir.ninjacoder.codesnap.Utils.Highlighter;
8+
import ir.ninjacoder.codesnap.widget.data.SpanStyler;
9+
import java.io.StringReader;
10+
import java.util.regex.Pattern;
11+
import org.antlr.v4.runtime.CharStreams;
12+
import org.antlr.v4.runtime.Token;
13+
14+
public class CodeHighlighterLua implements Highlighter {
15+
16+
@Override
17+
public SpannableStringBuilder highlight(LangType types, String code, ColorHelper color)
18+
throws Exception {
19+
SpanStyler span = SpanStyler.create();
20+
Token token;
21+
int type;
22+
int pretoken = -1;
23+
var lexer = new LuaLexer(CharStreams.fromReader(new StringReader(code)));
24+
25+
while ((token = lexer.nextToken()) != null) {
26+
type = token.getType();
27+
if (type == LuaLexer.EOF) {
28+
break;
29+
}
30+
31+
String tokenText = token.getText();
32+
33+
switch (type) {
34+
// Whitespace and newlines
35+
case LuaLexer.WS:
36+
case LuaLexer.NL:
37+
span.addNullText(tokenText);
38+
break;
39+
40+
// Keywords
41+
case LuaLexer.BREAK:
42+
case LuaLexer.GOTO:
43+
case LuaLexer.DO:
44+
case LuaLexer.END:
45+
case LuaLexer.WHILE:
46+
case LuaLexer.REPEAT:
47+
case LuaLexer.UNTIL:
48+
case LuaLexer.IF:
49+
case LuaLexer.THEN:
50+
case LuaLexer.ELSEIF:
51+
case LuaLexer.ELSE:
52+
case LuaLexer.FOR:
53+
case LuaLexer.IN:
54+
case LuaLexer.FUNCTION:
55+
case LuaLexer.LOCAL:
56+
case LuaLexer.RETURN:
57+
case LuaLexer.CONTINUE:
58+
case LuaLexer.NIL:
59+
case LuaLexer.FALSE:
60+
case LuaLexer.TRUE:
61+
case LuaLexer.NOT:
62+
case LuaLexer.AND:
63+
case LuaLexer.OR:
64+
span.text(tokenText, color.getKeyword(),true,false);
65+
break;
66+
67+
// Operators
68+
case LuaLexer.LT:
69+
case LuaLexer.GT:
70+
case LuaLexer.LE:
71+
case LuaLexer.GE:
72+
case LuaLexer.EE:
73+
case LuaLexer.SQEQ:
74+
case LuaLexer.PLUS:
75+
case LuaLexer.MINUS:
76+
case LuaLexer.STAR:
77+
case LuaLexer.SLASH:
78+
case LuaLexer.SS:
79+
case LuaLexer.PER:
80+
case LuaLexer.AMP:
81+
case LuaLexer.PIPE:
82+
case LuaLexer.CARET:
83+
case LuaLexer.SQUIG:
84+
case LuaLexer.LL:
85+
case LuaLexer.GG:
86+
case LuaLexer.DD:
87+
case LuaLexer.DDD:
88+
case LuaLexer.POUND:
89+
span.text(tokenText, color.getCssoprator());
90+
break;
91+
92+
// Punctuation and delimiters
93+
case LuaLexer.SEMI:
94+
case LuaLexer.COMMA:
95+
case LuaLexer.DOT:
96+
case LuaLexer.COL:
97+
case LuaLexer.CC:
98+
case LuaLexer.OP:
99+
case LuaLexer.CP:
100+
case LuaLexer.OCU:
101+
case LuaLexer.CCU:
102+
case LuaLexer.OB:
103+
case LuaLexer.CB:
104+
case LuaLexer.EQ:
105+
span.text(tokenText, color.getSymbol());
106+
break;
107+
108+
// Strings
109+
case LuaLexer.NORMALSTRING:
110+
case LuaLexer.CHARSTRING:
111+
case LuaLexer.LONGSTRING:
112+
span.text(tokenText, color.getStrings());
113+
break;
114+
115+
// Numbers
116+
case LuaLexer.INT:
117+
case LuaLexer.HEX:
118+
case LuaLexer.FLOAT:
119+
case LuaLexer.HEX_FLOAT:
120+
span.text(tokenText, color.getOperator());
121+
break;
122+
123+
case LuaLexer.NAME:
124+
{
125+
int colorNormal = color.getTextnormal();
126+
boolean isClassName = false, isbold = false, isShadow = false;
127+
128+
// تشخیص نام کلاس‌ها و تایپ‌ها
129+
if (pretoken == LuaLexer.FUNCTION
130+
|| pretoken == LuaLexer.LOCAL
131+
|| pretoken == LuaLexer.END) {
132+
colorNormal = color.getMethod();
133+
isShadow = true;
134+
isbold = true;
135+
isClassName = true;
136+
}
137+
// تشخیص توابع و متدها
138+
else if (pretoken == LuaLexer.COMMA
139+
|| pretoken == LuaLexer.OP
140+
|| pretoken == LuaLexer.EQ) {
141+
colorNormal = color.getVariable();
142+
isbold = true;
143+
// اگر بعد از شناسه پرانتز باز باشد، احتمالاً تابع است
144+
if (lexer._input.LA(1) == '(') {
145+
colorNormal = color.getPrebrak();
146+
}
147+
}
148+
// تشخیص پس از dot (متدها یا فیلدها)
149+
else if (lexer._input.LA(1) == '.') {
150+
colorNormal = color.getPredot();
151+
}
152+
// تشخیص پس از براکت
153+
else if (lexer._input.LA(1) == '[' || lexer._input.LA(1) == ']') {
154+
colorNormal = color.getBracketlevel1();
155+
}
156+
// تشخیص پس از dot
157+
else if (pretoken == LuaLexer.DOT) {
158+
colorNormal = color.getLastdot();
159+
}
160+
// تشخیص شناسه‌هایی که با حرف بزرگ شروع می‌شوند (معمولاً کلاس یا ثابت)
161+
else if (!isClassName && Character.isUpperCase(token.getText().charAt(0))) {
162+
Pattern pattern = Pattern.compile("^[A-Z][A-Z0-9_]*$");
163+
var matcher = pattern.matcher(token.getText());
164+
if (matcher.matches()) {
165+
// اگر تمام حروف بزرگ باشد (ثابت)
166+
colorNormal = color.getUppercase();
167+
}
168+
}
169+
170+
// بررسی توابع built-in
171+
if (isBuiltInFunction(token.getText())) {
172+
colorNormal = color.getBracketlevel3();
173+
isbold = true;
174+
} else if (isBuiltInLibrary(token.getText())) {
175+
colorNormal = color.getBracketlevel4();
176+
isbold = true;
177+
}
178+
span.text(token.getText(), colorNormal, isbold, isShadow);
179+
break;
180+
}
181+
// Comments (hidden channel but we can still style them if needed)
182+
case LuaLexer.COMMENT:
183+
span.text(tokenText, color.getComment());
184+
break;
185+
186+
// Shebang (hidden channel)
187+
case LuaLexer.SHEBANG:
188+
span.text(tokenText, color.getComment());
189+
break;
190+
191+
default:
192+
span.text(tokenText, color.getTextnormal());
193+
break;
194+
}
195+
if (type != LuaLexer.WS && type != LuaLexer.NL) {
196+
pretoken = type;
197+
}
198+
}
199+
return span;
200+
}
201+
202+
private boolean isBuiltInFunction(String name) {
203+
String[] builtInFunctions = {
204+
"print",
205+
"type",
206+
"tostring",
207+
"tonumber",
208+
"getmetatable",
209+
"setmetatable",
210+
"rawget",
211+
"rawset",
212+
"rawequal",
213+
"pairs",
214+
"ipairs",
215+
"next",
216+
"assert",
217+
"error",
218+
"pcall",
219+
"xpcall",
220+
"select",
221+
"load",
222+
"loadstring",
223+
"loadfile",
224+
"dofile",
225+
"require",
226+
"module",
227+
"collectgarbage",
228+
"getfenv",
229+
"setfenv"
230+
};
231+
232+
for (String func : builtInFunctions) {
233+
if (func.equals(name)) {
234+
return true;
235+
}
236+
}
237+
return false;
238+
}
239+
240+
private boolean isBuiltInLibrary(String name) {
241+
String[] builtInLibraries = {
242+
"string", "table", "math", "io", "os", "debug", "coroutine", "package"
243+
};
244+
245+
for (String lib : builtInLibraries) {
246+
if (lib.equals(name)) {
247+
return true;
248+
}
249+
}
250+
return false;
251+
}
252+
}

snapcode/src/main/java/ir/ninjacoder/codesnap/Utils/CodeHighlighterTs.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ public SpannableStringBuilder highlight(LangType typ, String code, ColorHelper c
191191
|| pretoken == TypeScriptLexer.Instanceof
192192
|| pretoken == TypeScriptLexer.Let
193193
|| pretoken == TypeScriptLexer.Not
194+
|| pretoken == TypeScriptLexer.Const
194195
|| pretoken == TypeScriptLexer.Var
195196
|| pretoken == TypeScriptLexer.Abstract
196197
|| pretoken == TypeScriptLexer.Identifier) {
@@ -201,10 +202,18 @@ public SpannableStringBuilder highlight(LangType typ, String code, ColorHelper c
201202
if (lexer._input.LA(1) == '(') {
202203
colorNormal = color.getLastsymi();
203204
}
205+
} else if (pretoken == TypeScriptLexer.Import) {
206+
colorNormal = color.getUppercase();
207+
} else if (pretoken == TypeScriptLexer.OpenParen) {
208+
colorNormal = color.getMethod();
209+
} else if (pretoken == TypeScriptLexer.LessThan) {
210+
colorNormal = color.getHtmlkeyword();
204211
} else if (lexer._input.LA(1) == '.') {
205212
colorNormal = color.getLastdot();
206213
} else if (lexer._input.LA(1) == '[' || lexer._input.LA(1) == ']') {
207214
colorNormal = color.getPrebrak();
215+
} else if (pretoken == TypeScriptLexer.Divide) {
216+
colorNormal = color.getHtmlkeyword();
208217
} else if (pretoken == TypeScriptLexer.Dot) {
209218
colorNormal = color.getPredot();
210219
} else if (!isClassName && Character.isUpperCase(token.getText().charAt(0))) {

snapcode/src/main/java/ir/ninjacoder/codesnap/Utils/CodeImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public SpannableStringBuilder highlight(LangType type, String code, ColorHelper
4949
return new CodeHighlighterMarkdown().highlight(type, code, color);
5050
} else if (type == LangType.ZIG) {
5151
return new CodeHighlighterZig().highlight(type, code, color);
52+
} else if (type == LangType.LUA) {
53+
return new CodeHighlighterLua().highlight(type, code, color);
5254
} else if (type == LangType.NONE) {
5355
return new EmptyLang().highlight(type, code, color);
5456
}

0 commit comments

Comments
 (0)