├── .gitignore
├── nbproject
├── .DS_Store
├── project.properties
├── genfiles.properties
├── platform.properties
├── build-impl.xml
└── project.xml
├── release
└── modules
│ └── ext
│ └── gson-2.2.2.jar
├── src
└── net
│ └── dfranek
│ └── typoscript
│ ├── resources
│ ├── ts.png
│ ├── type.png
│ ├── logic.png
│ ├── menus.png
│ ├── value.png
│ ├── wraps.png
│ ├── constants.png
│ ├── content.png
│ ├── effects.png
│ ├── parsing.png
│ ├── ts_file_16.png
│ ├── templates
│ │ ├── TSTemplate.ts
│ │ ├── TSTemplateComments.ts
│ │ ├── TSTemplate.html
│ │ ├── TSTemplateHTML5Advanced.html
│ │ ├── TSTemplateRTE.html
│ │ ├── TSTemplateComments.html
│ │ ├── TSTemplateHTML5Multilingual.html
│ │ ├── TSTemplateHTML5Advanced.ts
│ │ ├── TSTemplateHTML5Multilingual.ts
│ │ └── TSTemplateRTE.ts
│ ├── TSExample.ts
│ ├── Bundle.properties
│ ├── FontAndColors.xml
│ ├── layer.xml
│ └── TSResolver.xml
│ ├── Bundle.properties
│ ├── parser
│ ├── TSParserResult.java
│ ├── TSBracketNode.java
│ ├── TSError.java
│ ├── TSParser.java
│ ├── ast
│ │ ├── TSASTNode.java
│ │ └── TSASTNodeType.java
│ ├── TSParserUtils.java
│ └── TSTokenParser.java
│ ├── lexer
│ ├── TSLexerState.java
│ ├── TSLanguageHierarchy.java
│ ├── TSLexer.java
│ ├── TSTokenId.java
│ └── TSLexerUtils.java
│ ├── indent
│ ├── TSBracesMatcherFactory.java
│ └── TSBracesMatcher.java
│ ├── completion
│ ├── tsref
│ │ ├── TSRefProperty.java
│ │ ├── TSRefType.java
│ │ └── TSRef.java
│ ├── TSCompletionResult.java
│ ├── TSElement.java
│ └── TSCompletionItem.java
│ ├── embedding
│ └── HtmlEmbeddingProvider.java
│ ├── nav
│ └── TSDeclarationFinder.java
│ ├── typinghooks
│ ├── TSTypedTextInterceptor.java
│ └── TSTypedBreakInterceptor.java
│ └── TSLanguage.java
├── test
└── unit
│ └── src
│ └── net
│ └── dfranek
│ └── typoscript
│ ├── lexer
│ ├── Test.ts
│ ├── TSExample
│ ├── TSLexerTestUtils.java
│ └── TSScannerTest.java
│ └── parser
│ ├── test.ts
│ ├── TSParserTestUtils.java
│ └── TSTokenParserTest.java
├── manifest.mf
├── README
├── helper
└── json.php
└── CHANGELOG
/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /nbproject/private/
3 | .DS_Store
4 | /local/
--------------------------------------------------------------------------------
/nbproject/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/nbproject/.DS_Store
--------------------------------------------------------------------------------
/release/modules/ext/gson-2.2.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/release/modules/ext/gson-2.2.2.jar
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/ts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/src/net/dfranek/typoscript/resources/ts.png
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/type.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/src/net/dfranek/typoscript/resources/type.png
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/logic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/src/net/dfranek/typoscript/resources/logic.png
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/menus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/src/net/dfranek/typoscript/resources/menus.png
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/value.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/src/net/dfranek/typoscript/resources/value.png
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/wraps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/src/net/dfranek/typoscript/resources/wraps.png
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/constants.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/src/net/dfranek/typoscript/resources/constants.png
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/content.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/src/net/dfranek/typoscript/resources/content.png
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/effects.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/src/net/dfranek/typoscript/resources/effects.png
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/parsing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/src/net/dfranek/typoscript/resources/parsing.png
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/ts_file_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dfranek/NetBeans-TypoScript/HEAD/src/net/dfranek/typoscript/resources/ts_file_16.png
--------------------------------------------------------------------------------
/test/unit/src/net/dfranek/typoscript/lexer/Test.ts:
--------------------------------------------------------------------------------
1 | {}
2 | (
3 |
4 |
5 | )
6 | []
7 | [browser = msie] { AND } [ version > 5]
8 | {
9 | (
10 | )
11 | }
12 | (
13 | )
14 | {}
15 | {}
16 | ]
--------------------------------------------------------------------------------
/test/unit/src/net/dfranek/typoscript/lexer/TSExample:
--------------------------------------------------------------------------------
1 | headerimg.file {
2 | XY = [10.w]+2,20
3 | }
4 |
5 | [globalVar=TSFE:type = 0]
6 | page.typeNum = 0
7 | [global]
8 |
9 | page.10.value (
10 | Multi
11 | Line
12 | Value
13 | )
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/templates/TSTemplate.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Project: ${project.displayName} - ${project.name}
3 | * Version: 1.0.0
4 | * Date: ${date} ${time}
5 | * Author: ${user}
6 | *
7 | * Coded with Netbeans!
8 | */
9 |
--------------------------------------------------------------------------------
/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | OpenIDE-Module: net.dfranek.typoscript/1
3 | OpenIDE-Module-Implementation-Version: 0
4 | OpenIDE-Module-Layer: net/dfranek/typoscript/resources/layer.xml
5 | OpenIDE-Module-Localizing-Bundle: net/dfranek/typoscript/resources/Bundle.properties
6 |
--------------------------------------------------------------------------------
/test/unit/src/net/dfranek/typoscript/parser/test.ts:
--------------------------------------------------------------------------------
1 | seite = PAGE
2 | seite.headerData.10.value = test
3 | seite {
4 | config.test = 129
5 | test2 = [10.w] + 16,19
6 | test3 {
7 | test = 4
8 | }
9 | test4 = 3
10 | test8 < seite.config.test
11 | test5 (
12 | asdasdasdasdasdsa
13 | )
14 | }
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/TSExample.ts:
--------------------------------------------------------------------------------
1 | # Comment
2 |
3 | /*
4 | * Line Comment
5 | */
6 | page = PAGE
7 | page.config.SUBTEMPLATE = {$SUBTEMPLATE}
8 |
9 | headerimg.file {
10 | XY = [10.w]+2,20
11 | }
12 |
13 | [globalVar=TSFE:type = 0]
14 | page.typeNum = 0
15 | [global]
16 |
17 | page.10.value (
18 | Multi
19 | Line
20 | Value
21 | )
22 |
23 | plugin.tx_something_pi1.10 >
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/Bundle.properties:
--------------------------------------------------------------------------------
1 | LBL_TSEditorTab=&Source
2 | Templates/TypoScript/TSTemplate.ts=Empty TS file
3 | Templates/TypoScript/TSTemplateComments.ts=Empty TS file with coding sections
4 | Templates/TypoScript/TSTemplateHTML5Advanced.ts=Advanced HTML5 TS file
5 | Templates/TypoScript/TSTemplateHTML5Multilingual.ts=Advanced HTML5 TS
6 | Templates/TypoScript/TSTemplateRTE.ts=TS file for RTE configuration
7 |
8 | text/x-typoscript=TypoScript
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | This Project aims to provide support for the TypoScript Language used by TYPO3.
2 |
3 | The currently implemented features are:
4 | - Syntax highlighting (based on the file tokenizetyposcript.js from the TYPO3 extension t3editor).
5 | - a navigator for all properties declared in a file
6 | - a check for syntax errors (thanks to familie-redlich)
7 | - Code folding
8 | - a parser, responsible for syntax errors, navigator and other things
9 | - Code completion
10 |
--------------------------------------------------------------------------------
/nbproject/project.properties:
--------------------------------------------------------------------------------
1 | auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml
2 | javac.source=1.7
3 | javac.compilerargs=-Xlint -Xlint:-serial
4 | javadoc.arch=${basedir}/arch.xml
5 | license.file=gpl.txt
6 | nbm.homepage=https://github.com/dfranek/Netbeans-TypoScript
7 | nbm.module.author=Daniel Franek
8 |
9 | nbm.needs.restart=true
10 | spec.version.base=1.9
11 |
12 | keystore=nbproject/private/keystore
13 | nbm_alias=dfranek
14 |
--------------------------------------------------------------------------------
/nbproject/genfiles.properties:
--------------------------------------------------------------------------------
1 | build.xml.data.CRC32=07aabe4a
2 | build.xml.script.CRC32=4a07b388
3 | build.xml.stylesheet.CRC32=a56c6a5b@2.70.1
4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
6 | nbproject/build-impl.xml.data.CRC32=07aabe4a
7 | nbproject/build-impl.xml.script.CRC32=a99342a4
8 | nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.70.1
9 |
--------------------------------------------------------------------------------
/nbproject/platform.properties:
--------------------------------------------------------------------------------
1 | cluster.path=\
2 | ${nbplatform.active.dir}/apisupport:\
3 | ${nbplatform.active.dir}/cnd:\
4 | ${nbplatform.active.dir}/dlight:\
5 | ${nbplatform.active.dir}/enterprise:\
6 | ${nbplatform.active.dir}/ergonomics:\
7 | ${nbplatform.active.dir}/groovy:\
8 | ${nbplatform.active.dir}/harness:\
9 | ${nbplatform.active.dir}/ide:\
10 | ${nbplatform.active.dir}/java:\
11 | ${nbplatform.active.dir}/javacard:\
12 | ${nbplatform.active.dir}/mobility:\
13 | ${nbplatform.active.dir}/nb:\
14 | ${nbplatform.active.dir}/php:\
15 | ${nbplatform.active.dir}/platform:\
16 | ${nbplatform.active.dir}/profiler:\
17 | ${nbplatform.active.dir}/websvccommon
18 | nbjdk.active=default
19 | nbplatform.active=default
20 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/Bundle.properties:
--------------------------------------------------------------------------------
1 | OpenIDE-Module-Name=TypoScript
2 | OpenIDE-Module-Display-Category=Web
3 | OpenIDE-Module-Long-Description=\
4 | TypoScript Support for NetBeans IDE
5 | OpenIDE-Module-Short-Description=TypoScript Support for NetBeans IDE
6 |
7 | Services/MIMEResolver/TSResolver.xml=TS Files
8 |
9 |
10 | text/x-typoscript=TypoScript
11 |
12 | operator=Operator
13 | brace=Braces
14 | comment=Comments
15 | value=Values
16 | condition=Conditions
17 | ts=TypoScript
18 | keyword=Keywords
19 | reserved=Reserved Words
20 | whitespace=Whitespace
21 | error=Errors
22 | constant=Constants
23 | extension=Extensions
24 |
25 | net_dfranek_typoscript_update_center=http://netbeans.dfranek.net/updates.xml.php
26 | Services/AutoupdateType/net_dfranek_typoscript_update_center.instance=TypoScript Update Center
27 |
28 | LBL_TS_loader_name=TS Files
29 | LBL_TSEditorTab=&Source
--------------------------------------------------------------------------------
/helper/json.php:
--------------------------------------------------------------------------------
1 | type as $type) {
8 | $typeId = (string)$type['id'];
9 | if($typeId == 'GB_TEXT') {
10 | $typeId = 'GIFBUILDER_TEXT';
11 | }
12 | if($typeId == 'GB_IMAGE') {
13 | $typeId = 'GIFBUILDER_IMAGE';
14 | }
15 |
16 | $types[$typeId]['extendsType'] = (string)$type['extends'];
17 | foreach ($type->property as $property) {
18 | $types[$typeId]['properties'][(string)$property['name']] = array(
19 | 'type' => (string)$property['type'],
20 | 'defaultValue' => (string)$property->default,
21 | 'description' => nl2br((string)$property->description),
22 | );
23 | }
24 | }
25 | echo "
";
26 | print_r($types);
27 | echo "
";
28 | file_put_contents('tsref.json', json_encode($types));
29 |
30 | ?>
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/FontAndColors.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/templates/TSTemplateComments.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Project: ${project.displayName} - ${project.name}
3 | * Version: 1.0.0
4 | * Date: ${date} ${time}
5 | * Author: ${user}
6 | *
7 | * Coded with Netbeans!
8 | */
9 |
10 | #| --- Plugin ----------------------------------------------------------------------------------------- |#
11 |
12 |
13 | #| --- Libs ------------------------------------------------------------------------------------------- |#
14 |
15 |
16 | #| --- tt_content ------------------------------------------------------------------------------------- |#
17 |
18 |
19 | #| --- Code Cleanup ----------------------------------------------------------------------------------- |#
20 | lib.parseFunc_RTE.nonTypoTagStdWrap.encapsLines.addAttributes.P.class =
21 |
22 |
23 | #| --- Page Config ------------------------------------------------------------------------------------ |#
24 |
25 |
26 | #| --- Header & Body ---------------------------------------------------------------------------------- |#
27 |
28 |
29 | #| --- Template --------------------------------------------------------------------------------------- |#
30 |
31 |
32 | #| --- Markers & Subparts ----------------------------------------------------------------------------- |#
33 |
34 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/parser/TSParserResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 | package net.dfranek.typoscript.parser;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import net.dfranek.typoscript.lexer.TSTokenId;
10 | import net.dfranek.typoscript.parser.ast.TSASTNode;
11 | import org.netbeans.api.lexer.TokenSequence;
12 | import org.netbeans.modules.csl.api.Error;
13 | import org.netbeans.modules.csl.api.OffsetRange;
14 | import org.netbeans.modules.csl.spi.ParserResult;
15 | import org.netbeans.modules.parsing.api.Snapshot;
16 |
17 | /**
18 | *
19 | * @author Eric Waldburger
20 | */
21 | public class TSParserResult extends ParserResult {
22 |
23 | private final List errors;
24 | private boolean valid = true;
25 | private TSASTNode tree;
26 | private TokenSequence sequence;
27 | private List codeblocks;
28 |
29 | public TSParserResult(Snapshot snapshot) {
30 | super(snapshot);
31 | this.errors = new ArrayList<>();
32 | this.codeblocks = new ArrayList<>();
33 | }
34 |
35 | private TSParserResult(Snapshot snapshot, TokenSequence source) {
36 | super(snapshot);
37 | this.errors = new ArrayList<>();
38 | }
39 |
40 | @Override
41 | public List extends Error> getDiagnostics() {
42 | return errors;
43 | }
44 |
45 | public void addError(Error e) {
46 | errors.add(e);
47 | }
48 |
49 | public void addCodeBlock(OffsetRange r) {
50 | codeblocks.add(r);
51 | }
52 |
53 | @Override
54 | protected void invalidate() {
55 | valid = false;
56 | }
57 |
58 | public TSASTNode getTree() {
59 | return tree;
60 | }
61 |
62 | public void setTree(TSASTNode tree) {
63 | this.tree = tree;
64 | }
65 |
66 | public void setSequence(TokenSequence sequence) {
67 | this.sequence = sequence;
68 | }
69 |
70 | public TokenSequence getSequence() {
71 | return this.sequence;
72 | }
73 |
74 | public List getCodeBlocks() {
75 | return codeblocks;
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/layer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/nbproject/build-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | 1.2.9:
2 | - added highlighting for constants
3 | - added highlighting for extensions
4 | - changed highlighting for copied values, e.g. plugin.schluessel.config.value < tmp.schluessel.config.default
5 | - changed default style for conditions
6 | - fixed bug with code completion
7 | 1.2.10
8 | - fixed a severe bug in the lexer
9 | 1.3.0
10 | - Source/History now works
11 | - errors for non closed bracket are now added in the parser
12 | - fixed bug with code completion
13 | 1.3.1
14 | - fixed bug in lexer with opening curly brace
15 | 1.3.2
16 | - fixed Issue 12 (Matching constants fails when they contain a dot )
17 | - more keywords were added to xml
18 | 1.3.3
19 | - fixed bug with constants and xml
20 | 1.3.8
21 | - added more filetypes to resolver:
22 | setup.txt
23 | constants.txt
24 | ext_conf_template.txt
25 | ext_typoscript_setup.txt
26 | ext_typoscript_constants.txt
27 | 1.4.0
28 | - removed the internal class for keywords, moved all keywords to external xml file
29 | - parser now builds a tree
30 | - the navigator now shows a tree with all the properties
31 | 1.4.1
32 | - a bug in the lexer was fixed (issue #16)
33 | 1.4.2
34 | - fixed an error in the lexer (issue #17)
35 | - fixed an error in the parser
36 | 1.4.3
37 | - fixed slow loading of editor (issue #18)
38 | 1.5.0
39 | - improved code completion with parse result
40 | - parsing now sets correct types for stdWrap and config
41 | - help is now shown for some types in code completion
42 | 1.5.1
43 | - fixed bug with documentation
44 | - further improved documentation, inherited properties are now shown
45 | - improved parsing, now sets correct type for IMAGE and TEXT inside GIFBUILDER, as well as for NO, RO etc.
46 | 1.5.2
47 | - added more and better icons (thanks to familie redlich)
48 | 1.5.3
49 | - added more icons
50 | - conditions are now an own tree in the parser
51 | 1.5.4
52 | - fixed small bugs in code completion
53 | 1.6.0.
54 | - added "Go to Declaration" for copied properties
55 | 1.7.0
56 | - added auto complete for square brackets and curly braces
57 | 1.7.1
58 | - fixed bug with inserting of end parantheses in multiline values
59 | 1.7.2
60 | - some cleanup, reduced layer.xml, more annotations
61 | 1.8.0
62 | - Release for NetBeans 8.1
63 | - HTML/CSS Embedded Markup
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/templates/TSTemplate.html:
--------------------------------------------------------------------------------
1 |
36 |
37 |
38 |
39 |
40 |
41 | Creates empty TypoScript file. You can edit the file in the IDE's Source Editor.
42 | To change this template, choose Tools | Template Manager
43 | and open the template in the editor.
44 |
45 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/templates/TSTemplateHTML5Advanced.html:
--------------------------------------------------------------------------------
1 |
36 |
37 |
38 |
39 |
40 |
41 | Creates empty TypoScript file for HTML5. You can edit the file in the IDE's Source Editor.
42 | To change this template, choose Tools | Template Manager
43 | and open the template in the editor.
44 |
45 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/templates/TSTemplateRTE.html:
--------------------------------------------------------------------------------
1 |
36 |
37 |
38 |
39 |
40 |
41 | Creates empty TSConfig file for a RTE Configuaration. You can edit the file in the IDE's Source Editor.
42 | To change this template, choose Tools | Template Manager
43 | and open the template in the editor.
44 |
45 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/templates/TSTemplateComments.html:
--------------------------------------------------------------------------------
1 |
36 |
37 |
38 |
39 |
40 |
41 | Creates empty TypoScript file divided into Sections. You can edit the file in the IDE's Source Editor.
42 | To change this template, choose Tools | Template Manager
43 | and open the template in the editor.
44 |
45 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/templates/TSTemplateHTML5Multilingual.html:
--------------------------------------------------------------------------------
1 |
36 |
37 |
38 |
39 |
40 |
41 | Creates empty TypoScript file with multi language support. You can edit the file in the IDE's Source Editor.
42 | To change this template, choose Tools | Template Manager
43 | and open the template in the editor.
44 |
45 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/lexer/TSLexerState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.lexer;
40 |
41 | /**
42 | * Enum with the possible states for TypoScript scanner.
43 | *
44 | * @author Daniel Franek
45 | */
46 | public enum TSLexerState {
47 | IN_VALUE,
48 | IN_COMMENT,
49 | IN_PARANTHESE,
50 | IN_REGEXP,
51 | DEFAULT
52 | }
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/TSResolver.xml:
--------------------------------------------------------------------------------
1 |
2 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/indent/TSBracesMatcherFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.indent;
40 |
41 | import org.netbeans.spi.editor.bracesmatching.BracesMatcher;
42 | import org.netbeans.spi.editor.bracesmatching.BracesMatcherFactory;
43 | import org.netbeans.spi.editor.bracesmatching.MatcherContext;
44 |
45 | /**
46 | *
47 | * @author Daniel Franek
48 | */
49 | public class TSBracesMatcherFactory implements BracesMatcherFactory{
50 |
51 | @Override
52 | public BracesMatcher createMatcher(MatcherContext mc) {
53 | return new TSBracesMatcher(mc);
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/completion/tsref/TSRefProperty.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.completion.tsref;
40 |
41 | /**
42 | *
43 | * @author Daniel Franek
44 | */
45 | public class TSRefProperty {
46 | private String defaultValue;
47 | private String description;
48 | private String type;
49 |
50 | /**
51 | * @return the defaultValue
52 | */
53 | public String getDefaultValue() {
54 | return defaultValue;
55 | }
56 |
57 | /**
58 | * @return the description
59 | */
60 | public String getDescription() {
61 | return description;
62 | }
63 |
64 | /**
65 | * @return the type
66 | */
67 | public String getType() {
68 | return type;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/templates/TSTemplateHTML5Advanced.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Project: ${project.displayName} - ${project.name}
3 | * Version: 1.0.0
4 | * Date: ${date} ${time}
5 | * Author: ${user}
6 | *
7 | * Coded with Netbeans!
8 | */
9 |
10 | #| --- Plugin ----------------------------------------------------------------------------------------- |#
11 |
12 |
13 | #| --- Libs ------------------------------------------------------------------------------------------- |#
14 |
15 |
16 | #| --- tt_content ------------------------------------------------------------------------------------- |#
17 |
18 |
19 | #| --- Code Cleanup ----------------------------------------------------------------------------------- |#
20 | lib.parseFunc_RTE.nonTypoTagStdWrap.encapsLines.addAttributes.P.class =
21 |
22 |
23 | #| --- System & Page Config --------------------------------------------------------------------------- |#
24 | config {
25 | uniqueLinkVars = 1
26 | sys_language_uid = 0
27 | language = de
28 | locale_all = de_DE
29 | meaningfulTempFilePrefix = 64
30 | }
31 |
32 | page = PAGE
33 | page {
34 | config {
35 | doctype = html5
36 | disableImgBorderAttr = 1
37 | disablePrefixComment = 1
38 | htmlTag_langKey = de-DE
39 | meta.language = de
40 | spamProtectEmailAddresses = 2
41 | spamProtectEmailAddresses_atSubst = (at)
42 | spamProtectEmailAddresses_lastDotSubst = (dot)
43 | pageTitleFirst = 1
44 | removeDefaultJS = 1
45 | inlineStyle2TempFile = 1
46 | }
47 |
48 |
49 | #| --- Header & Body ---------------------------------------------------------------------------------- |#
50 | meta {
51 | keywords.field = keywords
52 | keywords.ifEmpty (
53 | // Enter default keywords of the website here
54 | )
55 | description.field = description
56 | description.ifEmpty (
57 | // Enter default description of the website here
58 | )
59 | FLAGS.DC = 0
60 | robots =
61 | author =
62 | revisited-after = 14
63 | audience =
64 | page-topic =
65 | MSSmartTagsPreventParsing = true
66 | imagetoolbar = false
67 | }
68 | includeCSS {
69 | screen = fileadmin/
70 | mobil = fileadmin/
71 | print = fileadmin/
72 | print.media = print
73 | }
74 | includeJS {
75 | jQuery = fileadmin/
76 | }
77 | includeJSFooter {
78 | tracking = fileadmin/
79 | }
80 | }
81 |
82 |
83 | #| --- Template --------------------------------------------------------------------------------------- |#
84 | page.10 = TEMPLATE
85 | page.10 {
86 | template = FILE
87 | workOnSubpart = DOC
88 | template.file = fileadmin/templates/standard.html
89 | }
90 |
91 |
92 | #| --- Markers & Subparts ----------------------------------------------------------------------------- |#
93 |
94 |
--------------------------------------------------------------------------------
/test/unit/src/net/dfranek/typoscript/parser/TSParserTestUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.parser;
40 |
41 | import junit.framework.TestCase;
42 | import net.dfranek.typoscript.parser.ast.TSASTNode;
43 | import net.dfranek.typoscript.parser.ast.TSASTNodeType;
44 |
45 | /**
46 | *
47 | * @author Daniel Franek
48 | */
49 | public class TSParserTestUtils extends TestCase {
50 |
51 | public static void assertNodeEquals(TSASTNode node, String nodeName, TSASTNodeType type, String value, int size) {
52 | assertEquals(node.getName(), nodeName);
53 | assertEquals(node.getType(), type);
54 | assertEquals(node.getValue(), value);
55 | assertTrue(node.getChildren().size() == size);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/completion/tsref/TSRefType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.completion.tsref;
40 |
41 | import java.util.HashMap;
42 | import java.util.Map;
43 |
44 | /**
45 | *
46 | * @author Daniel Franek
47 | */
48 | public class TSRefType {
49 | private final HashMap properties = new HashMap<>();
50 | private String extendsType;
51 |
52 | /**
53 | * @return the properties
54 | */
55 | public TSRefProperty getProperty(String name) {
56 | return getProperties().get(name);
57 | }
58 |
59 | /**
60 | * @return the extendsType
61 | */
62 | public String getExtends() {
63 | return extendsType;
64 | }
65 |
66 | public void setExtends(String extendsStr) {
67 | this.extendsType = extendsStr;
68 | }
69 |
70 | /**
71 | * @return the properties
72 | */
73 | public HashMap getProperties() {
74 | return properties;
75 | }
76 |
77 | public void addProperties(HashMap properties) {
78 | for (Map.Entry entry : properties.entrySet()) {
79 | String name = entry.getKey();
80 | TSRefProperty tSRefProperty = entry.getValue();
81 | this.properties.put(name, tSRefProperty);
82 | }
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/templates/TSTemplateHTML5Multilingual.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Project: ${project.displayName} - ${project.name}
3 | * Version: 1.0.0
4 | * Date: ${date} ${time}
5 | * Author: ${user}
6 | *
7 | * Coded with Netbeans!
8 | */
9 |
10 | #| --- Plugin ----------------------------------------------------------------------------------------- |#
11 |
12 |
13 | #| --- Libs ------------------------------------------------------------------------------------------- |#
14 |
15 |
16 | #| --- tt_content ------------------------------------------------------------------------------------- |#
17 |
18 |
19 | #| --- Code Cleanup ----------------------------------------------------------------------------------- |#
20 | lib.parseFunc_RTE.nonTypoTagStdWrap.encapsLines.addAttributes.P.class =
21 |
22 |
23 | #| --- System & Page Config --------------------------------------------------------------------------- |#
24 | config {
25 | linkVars = L(0-3)
26 | uniqueLinkVars = 1
27 | language = de
28 | locale_all = de_DE
29 | sys_language_uid = 0
30 | sys_language_mode = content_fallback
31 | meaningfulTempFilePrefix = 64
32 | }
33 | [globalVar = GP:L = 1]
34 | config {
35 | sys_language_uid = 1
36 | language = en
37 | locale_all = en_EN
38 | }
39 | [global]
40 | [globalVar = GP:L = 2]
41 | config {
42 | sys_language_uid = 2
43 | language = es
44 | locale_all = es_ES
45 | }
46 | [global]
47 | [globalVar = GP:L = 3]
48 | config {
49 | sys_language_uid = 3
50 | language = fr
51 | locale_all = fr_FR
52 | }
53 | [global]
54 |
55 | page = PAGE
56 | page {
57 | config {
58 | doctype = html5
59 | disableImgBorderAttr = 1
60 | disablePrefixComment = 1
61 | htmlTag_langKey = de-DE
62 | meta.language = de
63 | spamProtectEmailAddresses = 2
64 | spamProtectEmailAddresses_atSubst = (at)
65 | spamProtectEmailAddresses_lastDotSubst = (dot)
66 | pageTitleFirst = 1
67 | removeDefaultJS = 1
68 | inlineStyle2TempFile = 1
69 | }
70 |
71 |
72 | #| --- Header & Body ---------------------------------------------------------------------------------- |#
73 | meta {
74 | keywords.field = keywords
75 | keywords.ifEmpty (
76 | // Enter default keywords of the website here
77 | )
78 | description.field = description
79 | description.ifEmpty (
80 | // Enter default description of the website here
81 | )
82 | FLAGS.DC = 0
83 | robots =
84 | author =
85 | revisited-after = 14
86 | audience =
87 | page-topic =
88 | MSSmartTagsPreventParsing = true
89 | imagetoolbar = false
90 | }
91 | includeCSS {
92 | screen = fileadmin/
93 | mobil = fileadmin/
94 | print = fileadmin/
95 | print.media = print
96 | }
97 | includeJS {
98 | jQuery = fileadmin/
99 | }
100 | includeJSFooter {
101 | tracking = fileadmin/
102 | }
103 | }
104 |
105 |
106 | #| --- Template --------------------------------------------------------------------------------------- |#
107 | page.10 = TEMPLATE
108 | page.10 {
109 | template = FILE
110 | workOnSubpart = DOC
111 | template.file = fileadmin/templates/standard.html
112 | }
113 |
114 |
115 | #| --- Markers & Subparts ----------------------------------------------------------------------------- |#
116 |
117 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/completion/tsref/TSRef.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.completion.tsref;
40 |
41 | import com.google.gson.Gson;
42 | import com.google.gson.reflect.TypeToken;
43 | import java.io.InputStreamReader;
44 | import java.lang.reflect.Type;
45 | import java.util.HashMap;
46 | import net.dfranek.typoscript.lexer.TSLexerUtils;
47 |
48 | /**
49 | *
50 | * @author Daniel Franek
51 | */
52 | public class TSRef {
53 |
54 | protected static HashMap tsref;
55 |
56 | public static void initTSRef() {
57 | Gson gson = new Gson();
58 | Type tsrefType = new TypeToken>(){}.getType();
59 | tsref = gson.fromJson(new InputStreamReader(TSLexerUtils.class.getResourceAsStream("/net/dfranek/typoscript/resources/tsref.json")), tsrefType);
60 | }
61 |
62 | public static TSRefType getHelpForType(String type) {
63 | TSRefType t = null;
64 | if (tsref.containsKey(type)) {
65 | t = tsref.get(type);
66 | t = addBaseType(t);
67 | }
68 |
69 | return t;
70 | }
71 |
72 | private static TSRefType addBaseType(TSRefType t) {
73 | if (!t.getExtends().isEmpty()) {
74 | TSRefType baseType = tsref.get(t.getExtends());
75 | t.addProperties(baseType.getProperties());
76 | t.setExtends(baseType.getExtends());
77 | t = addBaseType(t);
78 | }
79 | return t;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/embedding/HtmlEmbeddingProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 |
40 | package net.dfranek.typoscript.embedding;
41 |
42 | import java.util.ArrayList;
43 | import java.util.List;
44 | import net.dfranek.typoscript.lexer.TSTokenId;
45 | import org.netbeans.api.lexer.Token;
46 | import org.netbeans.api.lexer.TokenSequence;
47 | import org.netbeans.modules.parsing.api.Embedding;
48 | import org.netbeans.modules.parsing.api.Snapshot;
49 | import org.netbeans.modules.parsing.spi.EmbeddingProvider;
50 |
51 | /**
52 | *
53 | * @author Daniel Franek
54 | */
55 | @EmbeddingProvider.Registration(
56 | mimeType="text/x-typoscript",
57 | targetMimeType="text/html"
58 | )
59 | public class HtmlEmbeddingProvider extends EmbeddingProvider {
60 |
61 | private final String HTML_MIME_TYPE = "text/html";
62 |
63 | @Override
64 | public List getEmbeddings(Snapshot snapshot) {
65 | final List embeddings = new ArrayList<>();
66 | final TokenSequence ts = snapshot.getTokenHierarchy().tokenSequence(TSTokenId.language());
67 |
68 | while (ts.moveNext()) {
69 | Token token = ts.token();
70 | if(token.id() == TSTokenId.TS_MULTILINE_VALUE) {
71 | embeddings.add(snapshot.create(ts.offset(), token.length(), HTML_MIME_TYPE));
72 | }
73 | }
74 |
75 | return embeddings;
76 | }
77 |
78 | @Override
79 | public int getPriority() {
80 | return 50;
81 | }
82 |
83 | @Override
84 | public void cancel() {
85 | // do nothing
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/completion/TSCompletionResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.completion;
40 |
41 | import java.util.ArrayList;
42 | import java.util.Collection;
43 | import java.util.logging.Logger;
44 | import javax.swing.text.BadLocationException;
45 | import javax.swing.text.Document;
46 | import org.netbeans.modules.csl.api.CodeCompletionContext;
47 | import org.netbeans.modules.csl.api.CompletionProposal;
48 | import org.netbeans.modules.csl.spi.DefaultCompletionResult;
49 | import org.openide.util.Exceptions;
50 | /**
51 | *
52 | * @author daniel
53 | */
54 | class TSCompletionResult extends DefaultCompletionResult {
55 |
56 | private final CodeCompletionContext context;
57 |
58 | public TSCompletionResult(CodeCompletionContext completionContext) {
59 | super(new ArrayList(), false);
60 | context = completionContext;
61 | }
62 |
63 | public void addAll(final Collection proposals) {
64 | list.addAll(proposals);
65 | }
66 |
67 | public void add(CompletionProposal proposal) {
68 | list.add(proposal);
69 | }
70 |
71 | @Override
72 | public void afterInsert(CompletionProposal cp) {
73 | Document doc = context.getParserResult().getSnapshot().getSource().getDocument(true);
74 | try {
75 | // Remove typed characters
76 | Logger.getLogger(TSCompletionResult.class.getName()).finest(doc.getText(cp.getAnchorOffset()-context.getPrefix().length(), context.getPrefix().length()));
77 | doc.remove(cp.getAnchorOffset()-context.getPrefix().length(), context.getPrefix().length());
78 | } catch (BadLocationException ex) {
79 | Exceptions.printStackTrace(ex);
80 | }
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/parser/TSBracketNode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.parser;
40 |
41 | /**
42 | *
43 | * @author Eric Waldburger
44 | */
45 | public class TSBracketNode {
46 |
47 | private TSBracketNode next;
48 | private TSBracketNode prev;
49 | private String value;
50 | private int offset;
51 |
52 | public TSBracketNode() {
53 | this.next = null;
54 | this.prev = null;
55 | this.value = "";
56 | }
57 |
58 | public TSBracketNode(String inVal, TSBracketNode inPrev) {
59 | this.next = null;
60 | this.prev = inPrev;
61 | this.value = inVal;
62 | this.offset = 0;
63 | }
64 |
65 | public TSBracketNode(String inVal, TSBracketNode inPrev, int offset) {
66 | this.next = null;
67 | this.prev = inPrev;
68 | this.value = inVal;
69 | this.offset = offset;
70 | }
71 |
72 | public TSBracketNode(String inVal, TSBracketNode inNext, TSBracketNode inPrev) {
73 | this.next = inNext;
74 | this.prev = inPrev;
75 | this.value = inVal;
76 | this.offset = 0;
77 | }
78 |
79 | public TSBracketNode(String inVal, TSBracketNode inNext, TSBracketNode inPrev, int offset) {
80 | this.next = inNext;
81 | this.prev = inPrev;
82 | this.value = inVal;
83 | this.offset = offset;
84 | }
85 |
86 | public TSBracketNode getNext() {
87 | return next;
88 | }
89 |
90 | public TSBracketNode getPrev() {
91 | return prev;
92 | }
93 |
94 | public void setPrev(TSBracketNode prev) {
95 | this.prev = prev;
96 | }
97 |
98 | public void setNext(TSBracketNode next) {
99 | this.next = next;
100 | }
101 |
102 | public String getValue() {
103 | return value;
104 | }
105 |
106 | public void setValue(String value) {
107 | this.value = value;
108 | }
109 |
110 | /**
111 | * @return the offset
112 | */
113 | public int getOffset() {
114 | return offset;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/parser/TSError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.parser;
40 |
41 | import org.netbeans.modules.csl.api.Severity;
42 | import org.openide.filesystems.FileObject;
43 |
44 | /**
45 | *
46 | * @author Daniel Franek
47 | */
48 | public class TSError implements org.netbeans.modules.csl.api.Error{
49 |
50 | private final String displayName;
51 |
52 | private final FileObject file;
53 | private final int startPosition;
54 | private final int endPosition;
55 | private final Severity severity;
56 | private final Object[] parameters;
57 |
58 | public TSError(String name, FileObject file, int start, int end, Severity severity, Object[] params) {
59 | displayName = name;
60 | this.file = file;
61 | startPosition = start;
62 | endPosition = end;
63 | this.severity = severity;
64 | this.parameters = params;
65 | }
66 |
67 | @Override
68 | public String getDisplayName() {
69 | return displayName;
70 | }
71 |
72 | @Override
73 | public String getDescription() {
74 | return null;
75 | }
76 |
77 | @Override
78 | public String getKey() {
79 | return "[" + startPosition + "," + endPosition + "]-" + displayName ;
80 | }
81 |
82 | @Override
83 | public FileObject getFile() {
84 | return this.file;
85 | }
86 |
87 | @Override
88 | public int getStartPosition() {
89 | return startPosition;
90 | }
91 |
92 | @Override
93 | public int getEndPosition() {
94 | return endPosition;
95 | }
96 |
97 | @Override
98 | public boolean isLineError() {
99 | return true;
100 | }
101 |
102 | @Override
103 | public Severity getSeverity() {
104 | return severity;
105 | }
106 |
107 | @Override
108 | public Object[] getParameters() {
109 | return parameters;
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/completion/TSElement.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.completion;
40 |
41 | import java.util.Collections;
42 | import java.util.Set;
43 | import net.dfranek.typoscript.TSLanguage;
44 | import org.netbeans.modules.csl.api.ElementHandle;
45 | import org.netbeans.modules.csl.api.ElementKind;
46 | import org.netbeans.modules.csl.api.Modifier;
47 | import org.netbeans.modules.csl.api.OffsetRange;
48 | import org.netbeans.modules.csl.spi.ParserResult;
49 | import org.openide.filesystems.FileObject;
50 |
51 | /**
52 | *
53 | * @author Daniel Franek
54 | */
55 | public class TSElement implements ElementHandle {
56 |
57 | private final CharSequence name;
58 | private final String doc;
59 |
60 | public TSElement(CharSequence name) {
61 | this.name = name;
62 | this.doc = null;
63 | }
64 |
65 | public TSElement(CharSequence name, String doc) {
66 | this.name = name;
67 | this.doc = doc;
68 | }
69 |
70 | @Override
71 | public FileObject getFileObject() {
72 | return null;
73 | }
74 |
75 | @Override
76 | public String getMimeType() {
77 | return TSLanguage.TS_MIME_TYPE;
78 | }
79 |
80 | @Override
81 | public String getName() {
82 | return name.toString();
83 | }
84 |
85 | @Override
86 | public String getIn() {
87 | return null;
88 | }
89 |
90 | @Override
91 | public ElementKind getKind() {
92 | return ElementKind.VARIABLE;
93 | }
94 |
95 | @Override
96 | public Set getModifiers() {
97 | return Collections.emptySet();
98 | }
99 |
100 | @Override
101 | public boolean signatureEquals(ElementHandle eh) {
102 | return false;
103 | }
104 |
105 | @Override
106 | public OffsetRange getOffsetRange(ParserResult pr) {
107 | return null;
108 | }
109 |
110 | public String getDocumentation() {
111 | return doc;
112 | }
113 |
114 | }
115 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/parser/TSParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.parser;
40 |
41 | import java.util.logging.Level;
42 | import java.util.logging.Logger;
43 | import javax.swing.event.ChangeListener;
44 | import net.dfranek.typoscript.lexer.TSTokenId;
45 | import org.netbeans.api.lexer.TokenSequence;
46 | import org.netbeans.modules.csl.spi.ParserResult;
47 | import org.netbeans.modules.parsing.api.Snapshot;
48 | import org.netbeans.modules.parsing.api.Task;
49 | import org.netbeans.modules.parsing.spi.ParseException;
50 | import org.netbeans.modules.parsing.spi.Parser;
51 | import org.netbeans.modules.parsing.spi.SourceModificationEvent;
52 |
53 | /**
54 | *
55 | * @author Daniel Franek
56 | */
57 | public class TSParser extends Parser {
58 |
59 | private Snapshot snapshot;
60 | private ParserResult result = null;
61 | private static final Logger LOGGER = Logger.getLogger(TSParser.class.getName());
62 |
63 | @Override
64 | public void parse(Snapshot snapshot, Task task, SourceModificationEvent sme) throws ParseException {
65 | this.snapshot = snapshot;
66 | //File split into tokens
67 | TokenSequence sequence = snapshot.getTokenHierarchy().tokenSequence(TSTokenId.getLanguage());
68 | try {
69 | result = parseSource(sequence);
70 | } catch (Exception e) {
71 | LOGGER.log(Level.FINE, "Exception during parsing: {0}", e);
72 | result = new TSParserResult(snapshot);
73 | }
74 | }
75 |
76 | @Override
77 | public Result getResult(Task task) throws ParseException {
78 | return result;
79 | }
80 |
81 | @Override
82 | public void addChangeListener(ChangeListener cl) {
83 | }
84 |
85 | @Override
86 | public void removeChangeListener(ChangeListener cl) {
87 | }
88 |
89 | private ParserResult parseSource(TokenSequence source) {
90 | ParserResult pResult;
91 | TSTokenParser p = new TSTokenParser(source, snapshot);
92 | pResult = p.analyze();
93 |
94 | return pResult;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/lexer/TSLanguageHierarchy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.lexer;
40 | import java.util.*;
41 | import net.dfranek.typoscript.TSLanguage;
42 | import org.netbeans.api.lexer.InputAttributes;
43 | import org.netbeans.api.lexer.Language;
44 | import org.netbeans.api.lexer.LanguagePath;
45 | import org.netbeans.api.lexer.Token;
46 | import org.netbeans.spi.lexer.*;
47 |
48 | /**
49 | *
50 | * @author Daniel Franek
51 | */
52 | public class TSLanguageHierarchy extends LanguageHierarchy {
53 |
54 | private static EnumSet tokens;
55 | private static Map idToToken;
56 |
57 | private static void init () {
58 | tokens = EnumSet.allOf(TSTokenId.class);
59 | idToToken = new HashMap<> ();
60 | for (TSTokenId token : tokens)
61 | idToToken.put (token.ordinal (), token);
62 | }
63 |
64 | static synchronized TSTokenId getToken (int id) {
65 | if (idToToken == null)
66 | init ();
67 | return idToToken.get (id);
68 | }
69 |
70 | @Override
71 | protected synchronized Collection createTokenIds() {
72 | if (tokens == null)
73 | init ();
74 | return tokens;
75 | }
76 |
77 | @Override
78 | protected synchronized Lexer createLexer(LexerRestartInfo lri) {
79 | return new TSLexer (lri);
80 | }
81 |
82 | @Override
83 | protected String mimeType() {
84 | return TSLanguage.TS_MIME_TYPE;
85 | }
86 |
87 | @Override
88 | protected LanguageEmbedding> embedding(Token token, LanguagePath languagePath, InputAttributes inputAttributes) {
89 | if(token.id() == TSTokenId.TS_MULTILINE_VALUE) {
90 | Language language = Language.find("text/html");
91 | if(language != null) {
92 | return LanguageEmbedding.create(language, 0, 0);
93 | }
94 | }
95 | return null;
96 | }
97 |
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/lexer/TSLexer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.lexer;
40 |
41 | import java.io.IOException;
42 | import java.util.logging.Level;
43 | import java.util.logging.Logger;
44 | import org.netbeans.api.lexer.Token;
45 | import org.netbeans.spi.lexer.Lexer;
46 | import org.netbeans.spi.lexer.LexerRestartInfo;
47 | import org.netbeans.spi.lexer.TokenFactory;
48 |
49 | /**
50 | *
51 | * @author Daniel Franek
52 | */
53 | public class TSLexer implements Lexer {
54 |
55 | private final LexerRestartInfo info;
56 | private final TokenFactory tokenFactory;
57 | private final TSScanner scanner;
58 |
59 | TSLexer(LexerRestartInfo info) {
60 | this.info = info;
61 | scanner = new TSScanner(info);
62 | tokenFactory = info.tokenFactory();
63 | TSLexerUtils.initKeywords();
64 | }
65 |
66 | /**
67 | * Returns the next Token. Calls TSScanner.nextToken to determine type of the token.
68 | *
69 | * @return the next token
70 | */
71 | @Override
72 | public Token nextToken() {
73 |
74 | try {
75 | TSTokenId tokenId = scanner.nextToken();
76 | int readLen = scanner.getReadLength();
77 | Token token = null;
78 | if (readLen < 1) return null;
79 |
80 | if (tokenId != null) {
81 | token = tokenFactory.createToken(tokenId);
82 | }
83 | return token;
84 | } catch (IOException ex) {
85 | Logger.getLogger(TSLexer.class.getName()).log(Level.SEVERE, null, ex);
86 | }
87 |
88 | return null;
89 | }
90 |
91 | /**
92 | * Returns the current state of the scanner.
93 | * @see TSLexerState
94 | *
95 | * @return the state of the scanner
96 | */
97 | @Override
98 | public Object state() {
99 | return scanner.getState();
100 | }
101 |
102 | @Override
103 | public void release() {}
104 | }
105 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/resources/templates/TSTemplateRTE.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Project: ${project.displayName} - ${project.name}
3 | * Version: 1.0.0
4 | * Date: ${date} ${time}
5 | * Author: ${user}
6 | *
7 | * Coded with Netbeans!
8 | */
9 |
10 | # RTE_for_all_users
11 | setup.default.edit_RTE = 1
12 |
13 | RTE.default {
14 | # Markup_Options_(Word_cleanup_etc.)
15 | //enableWordClean = 1
16 | //removeTrailingBR = 1
17 | //removeComments = 1
18 | //removeTags = sdfield
19 | //blindImageOptions = magic,plain,dragdrop
20 | //disablePCexamples = 1
21 | //disableTYPO3Browsers = 1
22 |
23 | # Show_Hide_Color_Picker
24 | disableColorPicker = 1
25 |
26 | # Show_Hide_Statusbar_of_HTMLarea
27 | //showStatusBar = 0
28 |
29 | # Show_Hide_Table_Options_Buttons
30 | //hideTableOperationsInToolbar = 0
31 |
32 | # Options_for_Table_Editing_(cellspacing_cellpadding_border)
33 | //disableSpacingFieldsetInTableOperations = 0
34 | //disableAlignmentFieldsetInTableOperations = 0
35 | //disableColorFieldsetInTableOperations = 0
36 | //disableLayoutFieldsetInTableOperations = 0
37 | //disableBordersFieldsetInTableOperations = 0
38 |
39 | # Show_Hide_Buttons
40 | showButtons = formatblock, blockstyle, headline, textstylelabel, blockstylelabel, bold, italic, underline, unorderedlist, insertcharacter, link, image, removeformat, table, toggleborders, tableproperties, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, columninsertbefore, columninsertafter, columndelete, columnsplit, cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge, findreplace, insertcharacter, undo, redo, chMode, showhelp,
41 | hideButtons = fontstyle, fontsize, size, textstyle strikethrough,lefttoright, righttoleft, textindicator, emoticon, user, spellcheck, inserttag, outdent, indent, justifyfull, subscript, superscript, acronym, copy, cut, paste, about, textcolor, left, center, right, orderedlist, line;
42 |
43 | # Show_Hide_additional_Buttons
44 | //showButtons := addToList(textcolor, bgcolor, size, fontsize )
45 |
46 | # Sorting_of_Buttons
47 | toolbarOrder = headline,textstyle,formatblock,blockstylelabel, blockstyle, bold, italic, underline, orderedlist, unorderedlist, findreplace, insertcharacter, undo, redo, showhelp, textstylelabel, image, link, line, table, toggleborders, tableproperties,rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, columninsertbefore, columninsertafter, columndelete, columnsplit, cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge, textcolor,chMode,removeformat,about
48 |
49 | # Grouping_of_Buttons
50 | //keepButtonGroupTogether = 1
51 | //keepToggleBordersInToolbar = 1
52 | }
53 |
54 |
55 | # Setup_RTE
56 | RTE.default {
57 | # RTE_CSS_to_use
58 | contentCSS = fileadmin/templates/rte.css
59 |
60 | # Show_all_Classes
61 | showTagFreeClasses = 1
62 |
63 | # Overwrite_RTE_Styles_and_use_Custom_Styles
64 | ignoreMainStyleOverride = 1
65 |
66 | # Definitions_of_Classes_for_Anchors_Characters_Images_Paragraphs_Tables
67 | classesAnchor = YourClassname1, YourClassname2
68 | classesCharacter = YourClassname1, YourClassname2
69 | classesImage = YourClassname1, YourClassname2
70 | classesParagraph = YourClassname1, YourClassname2
71 | classesTable = YourClassname1, YourClassname2
72 | classesTR = YourClassname1, YourClassname2
73 | classesTH = YourClassname1, YourClassname2
74 | classesTD = YourClassname1, YourClassname2
75 | }
76 |
77 |
78 | # Allowed_span_Classes
79 | RTE.config.tt_content.bodytext.proc.allowedClasses = author
80 |
81 |
82 | RTE.default.proc {
83 | # Overwrite_TypoScript_Styles_and_use_Custom_Styles
84 | overruleMode = ts_css
85 |
86 | # Allowed_Denied_Tags
87 | allowTags = table, tbody, tr, th, td, h1, h2, h3, h4, h5, h6, div, p, br, span, ul, ol, li, re, blockquote, strong, em, b, i, u, sub, sup, strike, a, img, nobr, hr, tt, q, cite, abbr, acronym, center, bgcolor, bg, color, underline
88 | denyTags = font
89 |
90 | # Don't_convert_BR_to_P
91 | dontConvBRtoParagraph = 1
92 |
93 | # Allowed_outside_of_P_and_DIV
94 | allowTagsOutside = img,hr,center
95 |
96 | # Allowed_Attributes_of_P_and_DIV
97 | keepPDIVattribs = class,style,id
98 | }
99 |
100 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/nav/TSDeclarationFinder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.nav;
40 |
41 | import javax.swing.text.Document;
42 | import net.dfranek.typoscript.lexer.TSLexerUtils;
43 | import net.dfranek.typoscript.lexer.TSTokenId;
44 | import net.dfranek.typoscript.parser.TSParserResult;
45 | import net.dfranek.typoscript.parser.ast.TSASTNode;
46 | import org.netbeans.api.lexer.Token;
47 | import org.netbeans.api.lexer.TokenHierarchy;
48 | import org.netbeans.api.lexer.TokenSequence;
49 | import org.netbeans.modules.csl.api.DeclarationFinder;
50 | import org.netbeans.modules.csl.api.OffsetRange;
51 | import org.netbeans.modules.csl.spi.ParserResult;
52 | import org.openide.filesystems.FileObject;
53 |
54 | /**
55 | *
56 | * @author Daniel Franek
57 | */
58 | public class TSDeclarationFinder implements DeclarationFinder {
59 |
60 | @Override
61 | public DeclarationLocation findDeclaration(ParserResult info, int caretOffset) {
62 | DeclarationLocation declLocation = DeclarationLocation.NONE;
63 | if (!(info instanceof TSParserResult)) return DeclarationLocation.NONE;
64 | TSParserResult result = (TSParserResult) info;
65 |
66 | TokenHierarchy> th = result.getSnapshot().getTokenHierarchy();
67 | TokenSequence ts = th.tokenSequence(TSTokenId.getLanguage());
68 | TSASTNode tree = result.getTree();
69 | ts.move(caretOffset);
70 | ts.moveNext();
71 | Token token = ts.token();
72 | TSASTNode item = tree.getChild(token.text().toString());
73 | FileObject fo = result.getSnapshot().getSource().getFileObject();
74 | if(fo != null && item != null) {
75 | declLocation = new DeclarationLocation(result.getSnapshot().getSource().getFileObject(), item.getOffset());
76 | }
77 |
78 | return declLocation;
79 | }
80 |
81 | @Override
82 | public OffsetRange getReferenceSpan(final Document doc, final int caretOffset) {
83 | TokenSequence ts = TSLexerUtils.getTSTokenSequence(doc, caretOffset);
84 | ts.move(caretOffset);
85 | if (ts.moveNext()) {
86 | int offset = ts.offset();
87 | Token token = ts.token();
88 | TSTokenId id = token.id();
89 | if(id.equals(TSTokenId.TS_PROPERTY)) {
90 | Token extends TSTokenId> opVal = TSLexerUtils.findBwdNonSpace(ts);
91 | if ((opVal.id().equals(TSTokenId.TS_OPERATOR) && opVal.text().toString().equals("<"))) {
92 | return new OffsetRange(offset, offset + token.length());
93 | }
94 | }
95 | }
96 |
97 |
98 |
99 | return OffsetRange.NONE;
100 | }
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/test/unit/src/net/dfranek/typoscript/parser/TSTokenParserTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.parser;
40 |
41 | import java.io.File;
42 | import java.net.URISyntaxException;
43 | import junit.framework.TestCase;
44 | import net.dfranek.typoscript.lexer.TSLexerTestUtils;
45 | import net.dfranek.typoscript.lexer.TSTokenId;
46 | import net.dfranek.typoscript.parser.ast.TSASTNode;
47 | import net.dfranek.typoscript.parser.ast.TSASTNodeType;
48 | import org.netbeans.api.lexer.TokenSequence;
49 |
50 | /**
51 | *
52 | * @author Daniel
53 | */
54 | public class TSTokenParserTest extends TestCase {
55 |
56 | public TSTokenParserTest(String name) {
57 | super(name);
58 | }
59 |
60 | public void testParser() throws URISyntaxException, Exception {
61 | TokenSequence ts = (TokenSequence) TSLexerTestUtils.seqForText(TSLexerTestUtils.getFileContent(new File(TSTokenParserTest.class.getResource("/net/dfranek/typoscript/parser/test.ts").toURI())), TSTokenId.getLanguage());
62 | TSTokenParser tp = new TSTokenParser(ts);
63 | TSASTNode tree = tp.buildTree();
64 | TSParserTestUtils.assertNodeEquals(tree.getChild("seite"), "seite", TSASTNodeType.PAGE, "", 7);
65 | TSParserTestUtils.assertNodeEquals(tree.getChild("seite").getChild("headerData"), "headerData", TSASTNodeType.UNKNOWN, "", 1);
66 | TSParserTestUtils.assertNodeEquals(tree.getChild("seite").getChild("headerData").getChild("10"), "10", TSASTNodeType.UNKNOWN, "", 1);
67 | TSParserTestUtils.assertNodeEquals(tree.getChild("seite").getChild("headerData").getChild("10").getChild("value"), "value", TSASTNodeType.VALUE, "test", 0);
68 | TSParserTestUtils.assertNodeEquals(tree.getChild("seite").getChild("config"), "config", TSASTNodeType.CONFIG, "", 1);
69 | TSParserTestUtils.assertNodeEquals(tree.getChild("seite").getChild("config").getChild("test"), "test", TSASTNodeType.VALUE, "129", 0);
70 | TSParserTestUtils.assertNodeEquals(tree.getChild("seite").getChild("test2"), "test2", TSASTNodeType.VALUE, "[10.w] + 16,19", 0);
71 | TSParserTestUtils.assertNodeEquals(tree.getChild("seite").getChild("test3"), "test3", TSASTNodeType.UNKNOWN, "", 1);
72 | TSParserTestUtils.assertNodeEquals(tree.getChild("seite").getChild("test3").getChild("test"), "test", TSASTNodeType.VALUE, "4", 0);
73 | TSParserTestUtils.assertNodeEquals(tree.getChild("seite").getChild("test4"), "test4", TSASTNodeType.VALUE, "3", 0);
74 | TSParserTestUtils.assertNodeEquals(tree.getChild("seite").getChild("test8"), "test8", TSASTNodeType.COPIED_PROPERTY, "seite.config.test", 0);
75 | TSParserTestUtils.assertNodeEquals(tree.getChild("seite").getChild("test5"), "test5", TSASTNodeType.VALUE, "asdasdasdasdasdsa", 0);
76 |
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/lexer/TSTokenId.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.lexer;
40 |
41 | import org.netbeans.api.lexer.Language;
42 | import org.netbeans.api.lexer.TokenId;
43 |
44 | /**
45 | * Enum with possible tokens for the TypoScript Language
46 | *
47 | * @author Daniel Franek
48 | */
49 | public enum TSTokenId implements TokenId {
50 |
51 | TS_CURLY_OPEN(null, "brace"),
52 | TS_CURLY_CLOSE(null, "brace"),
53 | TS_COMMENT(null, "comment"),
54 | TS_MULTILINE_COMMENT(null, "comment"),
55 | TS_VALUE(null, "value"),
56 | TS_MULTILINE_VALUE(null, "value"),
57 | TS_PROPERTY(null, "ts"),
58 | TS_CONDITION(null, "condition"),
59 | TS_CONSTANT(null, "constant"),
60 | TS_STRING(null, "string"),
61 | TS_NUMBER(null, "number"),
62 | TS_REGEXP(null, "string"),
63 | TS_OPERATOR(null, "operator"),
64 | TS_KEYWORD(null, "keyword"),
65 | TS_RESERVED(null, "reserved"),
66 | TS_OBJECT(null, "keyword"),
67 | TS_FUNCTION(null, "keyword"),
68 | TS_EXTENSION(null, "extension"),
69 | TS_NL(null, "whitespace"),
70 | TS_PARANTHESE_OPEN(null, "brace"),
71 | TS_PARANTHESE_CLOSE(null, "brace"),
72 | WHITESPACE(null, "whitespace"),
73 | UNKNOWN_TOKEN(null, "error");
74 |
75 | private final String primaryCategory;
76 | private final String fixedText;
77 | private static final Language language = new TSLanguageHierarchy().language();
78 | private int start;
79 | private int end;
80 |
81 | TSTokenId(String fixedText, String primaryCategory) {
82 | this.fixedText = fixedText;
83 | this.primaryCategory = primaryCategory;
84 | }
85 |
86 | public static Language getLanguage() {
87 | return language;
88 | }
89 |
90 | @Override
91 | public String primaryCategory() {
92 | return primaryCategory;
93 | }
94 |
95 | /**
96 | * @return the start
97 | */
98 | public int getStart() {
99 | return start;
100 | }
101 |
102 | /**
103 | * @param start the start to set
104 | */
105 | public void setStart(int start) {
106 | this.start = start;
107 | }
108 |
109 | /**
110 | * @return the end
111 | */
112 | public int getEnd() {
113 | return end;
114 | }
115 |
116 | /**
117 | * @param end the end to set
118 | */
119 | public void setEnd(int end) {
120 | this.end = end;
121 | }
122 |
123 | /** Gets a LanguageDescription describing a set of token ids
124 | * that comprise the given language.
125 | *
126 | * @return non-null LanguageDescription
127 | */
128 | public static Language language() {
129 | return language;
130 | }
131 |
132 | }
133 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/parser/ast/TSASTNode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.parser.ast;
40 |
41 | import java.util.Collection;
42 | import java.util.HashMap;
43 |
44 | /**
45 | *
46 | * @author Daniel Franek
47 | */
48 | public class TSASTNode {
49 | private final String name;
50 | private String value;
51 | private TSASTNodeType type;
52 | private final HashMap children = new HashMap<>();
53 | private TSASTNode parent;
54 |
55 | private final int length;
56 | private final int offset;
57 | private String suffix = "";
58 |
59 | public TSASTNode(String name, String value, TSASTNodeType type, int offset, int length) {
60 | this.name = name;
61 | this.value = value;
62 | this.type = type;
63 | this.length = length;
64 | this.offset = offset;
65 | }
66 |
67 | public TSASTNode(String name, String value, TSASTNodeType type, int offset, int length, String suffix) {
68 | this.name = name;
69 | this.value = value;
70 | this.type = type;
71 | this.length = length;
72 | this.offset = offset;
73 | this.suffix = suffix;
74 | }
75 |
76 | /**
77 | * @return the name
78 | */
79 | public String getName() {
80 | return name;
81 | }
82 |
83 | public void addChild(TSASTNode node) {
84 | node.setParent(this);
85 | children.put(node.getNodeName(), node);
86 | }
87 |
88 | public void removeChild(TSASTNode node) {
89 | children.remove(node.getName());
90 | }
91 |
92 | public Collection getChildren() {
93 | return children.values();
94 | }
95 |
96 | public boolean hasChild(TSASTNode node) {
97 | return children.containsKey(node.getName());
98 | }
99 |
100 | public boolean hasChild(String name) {
101 | return children.containsKey(name);
102 | }
103 |
104 | public boolean hasChildren() {
105 | return !children.isEmpty();
106 | }
107 |
108 | /**
109 | * @return the value
110 | */
111 | public String getValue() {
112 | return value;
113 | }
114 |
115 | /**
116 | * @return the type
117 | */
118 | public TSASTNodeType getType() {
119 | return type;
120 | }
121 |
122 | /**
123 | * @param value the value to set
124 | */
125 | public void setValue(String value) {
126 | this.value = value;
127 | }
128 |
129 | /**
130 | * @param type the type to set
131 | */
132 | public void setType(TSASTNodeType type) {
133 | this.type = type;
134 | }
135 |
136 | public void setParent(TSASTNode node) {
137 | this.parent = node;
138 | }
139 |
140 | public TSASTNode getParent() {
141 | return this.parent;
142 | }
143 |
144 | /**
145 | * @return the length
146 | */
147 | public int getLength() {
148 | return length;
149 | }
150 |
151 | /**
152 | * @return the offset
153 | */
154 | public int getOffset() {
155 | return offset;
156 | }
157 |
158 | public TSASTNode getChild(String name) {
159 | return children.get(name);
160 | }
161 |
162 | private String getNodeName() {
163 | return name + suffix;
164 | }
165 |
166 | public boolean isTypeSet() {
167 | return !(getType() == TSASTNodeType.UNKNOWN);
168 | }
169 |
170 | }
171 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/completion/TSCompletionItem.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.completion;
40 |
41 | import java.util.Collections;
42 | import java.util.Set;
43 | import java.util.logging.Level;
44 | import java.util.logging.Logger;
45 | import javax.swing.ImageIcon;
46 | import org.netbeans.modules.csl.api.*;
47 | import org.openide.util.ImageUtilities;
48 |
49 | /**
50 | *
51 | * @author Daniel Franek
52 | */
53 | public class TSCompletionItem implements CompletionProposal {
54 |
55 | private final int anchor;
56 | private final String name;
57 | private final ElementKind kind;
58 | private final String prefix;
59 | private static final Logger logger = Logger.getLogger(TSCodeCompletion.class.getName());
60 | private final boolean smart;
61 | private String typeName;
62 | private final ElementHandle element;
63 |
64 | public TSCompletionItem(int anchor, String name, ElementKind kind, String prefix, boolean smart) {
65 | logger.setLevel(Level.ALL);
66 | this.anchor = anchor;
67 | this.name = name;
68 | this.kind = kind;
69 | this.prefix = prefix;
70 | this.smart = smart;
71 | this.element = new TSElement(name);
72 | }
73 |
74 | public TSCompletionItem(int anchor, String name, ElementKind kind, String prefix, boolean smart, String type) {
75 | logger.setLevel(Level.ALL);
76 | this.anchor = anchor;
77 | this.name = name;
78 | this.kind = kind;
79 | this.prefix = prefix;
80 | this.smart = smart;
81 | this.typeName = type;
82 | this.element = new TSElement(name);
83 | }
84 |
85 | public TSCompletionItem(int anchor, String name, ElementKind kind, String prefix, boolean smart, String type, String documentation) {
86 | logger.setLevel(Level.ALL);
87 | this.anchor = anchor;
88 | this.name = name;
89 | this.kind = kind;
90 | this.prefix = prefix;
91 | this.smart = smart;
92 | this.typeName = type;
93 | this.element = new TSElement(name, documentation);
94 | }
95 |
96 | @Override
97 | public int getAnchorOffset() {
98 | return anchor;
99 | }
100 |
101 | @Override
102 | public ElementHandle getElement() {
103 | return element;
104 | }
105 |
106 | @Override
107 | public String getName() {
108 | return this.name;
109 | }
110 |
111 | @Override
112 | public String getInsertPrefix() {
113 | String prefixL;
114 | final String insertPrefix = getName();
115 | int indexOf = (this.prefix != null && insertPrefix != null) ? insertPrefix.toLowerCase().indexOf(this.prefix.toLowerCase()) : -1;
116 | prefixL = indexOf > 0 ? insertPrefix.substring(indexOf) : insertPrefix;
117 | logger.log(Level.FINEST, "insert Prefix for item {0} with completion prefix \"{1}\" :{2}", new Object[]{insertPrefix, this.prefix, prefixL});
118 | return prefixL;
119 | }
120 |
121 | @Override
122 | public String getSortText() {
123 | return getName();
124 | }
125 |
126 | @Override
127 | public String getLhsHtml(HtmlFormatter hf) {
128 | return getName();
129 | }
130 |
131 | @Override
132 | public String getRhsHtml(HtmlFormatter hf) {
133 | return this.typeName == null ? this.kind.toString() : this.typeName;
134 | }
135 |
136 | @Override
137 | public ElementKind getKind() {
138 | return this.kind;
139 | }
140 |
141 | @Override
142 | public ImageIcon getIcon() {
143 | return new ImageIcon(ImageUtilities.loadImage("net/dfranek/typoscript/resources/ts.png"));
144 | }
145 |
146 | @Override
147 | public Set getModifiers() {
148 | return Collections.emptySet();
149 | }
150 |
151 | @Override
152 | public boolean isSmart() {
153 | return smart;
154 | }
155 |
156 | @Override
157 | public int getSortPrioOverride() {
158 | return 0;
159 | }
160 |
161 | @Override
162 | public String getCustomInsertTemplate() {
163 | return getName();
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/parser/TSParserUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.parser;
40 |
41 | import java.util.List;
42 | import javax.swing.text.BadLocationException;
43 | import net.dfranek.typoscript.lexer.TSLexerUtils;
44 | import net.dfranek.typoscript.lexer.TSTokenId;
45 | import net.dfranek.typoscript.parser.ast.TSASTNode;
46 | import org.netbeans.api.lexer.Token;
47 | import org.netbeans.api.lexer.TokenSequence;
48 | import org.netbeans.editor.BaseDocument;
49 | import org.netbeans.editor.Utilities;
50 |
51 | /**
52 | *
53 | * @author Daniel Franek
54 | */
55 | public class TSParserUtils {
56 |
57 | public static int findHierarchyStart(TokenSequence ts, int caretOffset) {
58 | ts.move(caretOffset);
59 | ts.moveNext();
60 | ts.movePrevious();
61 | Token t = ts.token();
62 | // causes an error if care is at the end of a token -> move back
63 | if (ts.offset() + t.length() == caretOffset && !t.id().equals(TSTokenId.TS_NL)) {
64 | ts.movePrevious();
65 | t = ts.token();
66 | }
67 | while (!TSLexerUtils.tokenIsKeyword(t.id()) && !t.id().equals(TSTokenId.TS_NL) && ts.movePrevious()) {
68 | t = ts.token();
69 | }
70 |
71 | if (t.id().equals(TSTokenId.TS_NL)) {
72 | int balance = 0;
73 | ts.movePrevious();
74 |
75 | do {
76 | if (balance > 0 && t.id().equals(TSTokenId.TS_CURLY_OPEN)) {
77 | balance--;
78 | }
79 | t = ts.token();
80 | if (t.id().equals(TSTokenId.TS_CURLY_CLOSE)) {
81 | balance++;
82 | }
83 | } while (ts.movePrevious() && (!t.id().equals(TSTokenId.TS_CURLY_OPEN) || balance != 0));
84 |
85 | t = ts.token();
86 | while (t.id().equals(TSTokenId.WHITESPACE) && ts.movePrevious()) {
87 | t = ts.token();
88 | }
89 | }
90 | return ts.offset();
91 | }
92 |
93 | public static List> getCurrentHierarchy(int caretOffset, BaseDocument doc, TokenSequence ts, TSASTNode tree, List> h) throws BadLocationException {
94 | if (caretOffset == 0) {
95 | return h;
96 | }
97 | int lineStart = Utilities.getRowFirstNonWhite(doc, caretOffset);
98 | ts.move(caretOffset);
99 | ts.moveNext();
100 | Token token = ts.token();
101 | if (token == null) {
102 | ts.movePrevious();
103 | token = ts.token();
104 | }
105 |
106 | if (token.text().toString().equals(".")) {
107 | ts.movePrevious();
108 | token = ts.token();
109 | }
110 |
111 | if (TSLexerUtils.tokenIsKeyword(token.id())) {
112 | h.add(token);
113 | }
114 | while (ts.offset() > lineStart) {
115 | ts.movePrevious();
116 | token = ts.token();
117 | if (token.id().equals(TSTokenId.TS_OPERATOR) && token.text().toString().equals("<")) {
118 | return h;
119 | }
120 | if (TSLexerUtils.tokenIsKeyword(token.id())) {
121 | h.add(token);
122 | }
123 | }
124 | if (tree.getChild(token.text().toString()) != null && getCurlyBalance(ts) == 0) {
125 | return h;
126 | } else {
127 | ts.movePrevious();
128 | do {
129 | token = ts.token();
130 | } while (!token.id().equals(TSTokenId.TS_CURLY_OPEN) && ts.movePrevious());
131 | ts.movePrevious();
132 | token = ts.token();
133 | while (token.id().equals(TSTokenId.WHITESPACE) && ts.movePrevious()) {
134 | token = ts.token();
135 | }
136 |
137 | if (tree.getChild(token.text().toString()) != null && getCurlyBalance(ts) == 0) {
138 | h.add(token);
139 | return h;
140 | } else {
141 | return getCurrentHierarchy(ts.offset(), doc, ts, tree, h);
142 | }
143 | }
144 | }
145 |
146 | private static int getCurlyBalance(TokenSequence ts) {
147 | int balance = 0;
148 | int curOffset = ts.offset();
149 | Token t;
150 | while (ts.movePrevious()) {
151 | t = ts.token();
152 | if (t.id().equals(TSTokenId.TS_CURLY_OPEN)) {
153 | balance--;
154 | }
155 | if (t.id().equals(TSTokenId.TS_CURLY_CLOSE)) {
156 | balance++;
157 | }
158 | }
159 | ts.move(curOffset);
160 | ts.movePrevious();
161 |
162 | return balance;
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/parser/ast/TSASTNodeType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.parser.ast;
40 |
41 | import java.util.Arrays;
42 | import java.util.List;
43 |
44 | /**
45 | *
46 | * @author Daniel Franek
47 | */
48 | public enum TSASTNodeType {
49 |
50 | // Top Level Objects
51 | PLUGIN,
52 | CONFIG,
53 | CONSTANTS,
54 | PAGE,
55 | FE_DATA,
56 | FE_TABLE,
57 | FRAMESET,
58 | FRAME,
59 | META,
60 | CARRAY,
61 |
62 | // Graphic Functions
63 | GIFBUILDER,
64 | GIFBUILDER_TEXT("TEXT"),
65 | GIFBUILDER_IMAGE("IMAGE"),
66 | SHADOW,
67 | EMBOSS,
68 | OUTLINE,
69 | BOX,
70 | EFFECT,
71 | WORKAREA,
72 | CROP,
73 | SCALE,
74 | ADJUST,
75 | IMGMAP,
76 |
77 | // Menu Objects
78 | GMENU,
79 | GMENU_LAYERS,
80 | TMENU,
81 | TMENU_LAYERS,
82 | GMENU_FOLDOUT,
83 | TMENUITEM,
84 | TMENUITEM_LOGIC("TMENUITEM"),
85 | IMGMENU,
86 | IMGMENUITEM,
87 | JSMENU,
88 | JSMENUITEM,
89 |
90 | // Content Objects
91 | HTML,
92 | TEXT,
93 | COBJ_ARRAY,
94 | COA,
95 | COA_INT,
96 | FILE,
97 | IMAGE,
98 | IMG_RESOURCE,
99 | CLEARGIF,
100 | CONTENT,
101 | RECORDS,
102 | HMENU,
103 | CTABLE,
104 | OTABLE,
105 | COLUMNS,
106 | HRULER,
107 | IMGTEXT,
108 | CASE,
109 | LOAD_REGISTER,
110 | RESTORE_REGISTER,
111 | FORM,
112 | SEARCHRESULT,
113 | USER,
114 | USER_INT,
115 | PHP_SCRIPT,
116 | PHP_SCRIPT_INT,
117 | PHP_SCRIPT_EXT,
118 | TEMPLATE,
119 | MULTIMEDIA,
120 | EDITPANEL,
121 | STDWRAP("stdWrap"),
122 |
123 | // Relevant for Parsing
124 | UNKNOWN,
125 | VALUE,
126 | LOGIC_PROPERTY("if"),
127 | ROOTLEVEL,
128 | COPIED_PROPERTY,
129 | CLEARED_PROPERY,
130 | CONDITION,
131 | WRAP("");
132 |
133 | TSASTNodeType() {
134 | typeName = this.name();
135 | }
136 |
137 | TSASTNodeType(String name) {
138 | typeName = name;
139 | }
140 |
141 | @Override
142 | public String toString() {
143 | return typeName;
144 | }
145 | protected String typeName;
146 |
147 | public static TSASTNodeType getNodeTypeForObject(String name) {
148 | if (name.equals("config")) {
149 | return CONFIG;
150 | }
151 | if (name.equals("stdWrap") || name.equals("stdWrap2") || name.equals("allStdWrap")) {
152 | return STDWRAP;
153 | }
154 |
155 | List t = Arrays.asList(new String[]{"allWrap", "beforeWrap", "commentWrap", "dontWrapInTable", "imageLinkWrap", "ATagBeforeWrap", "encapsLinesStdWrap", "tagStdWrap", "tableStdWrap", "fieldWrap", "labelStdWrap", "labelWrap", "linkWrap", "wrapNonWrappedLines", "nonTypoTagStdWrap", "nonWrappedTag", "plainTextStdWrap", "dataWrap", "innerWrap", "innerWrap2", "noTrimWrap", "outerWrap", "wrap", "wrap1", "wrap2", "wrap3", "wrapAfterTags", "wrapAlign", "wrapFieldName", "wrapItemAndSub", "wrapNonWrappedLines", "wraps", "wrapSplitChar", "radioWrap", "radioInputWrap", "accessibilityWrap", "noWrapAttr"});
156 | if (t.contains(name)) {
157 | return WRAP;
158 | }
159 |
160 | if (name.equals("if") || name.equals("ifBlank") || name.equals("ifEmpty")) {
161 | return TSASTNodeType.LOGIC_PROPERTY;
162 | }
163 |
164 | t = Arrays.asList(new String[]{"ACT", "NO", "RO", "CUR", "USR", "SPC", "ACTRO", "USERDEF1RO", "USERDEF2RO", "USERDEF1", "USERDEF2","CURRO"});
165 | if (t.contains(name)) {
166 | return TMENUITEM;
167 | }
168 |
169 | t = Arrays.asList(new String[]{"IFSUB","IFSUBRO", "ACTIFSUB", "ACTIFSUBRO", "CURIFSUB", "CURIFSUBRO"});
170 | if (t.contains(name)) {
171 | return TMENUITEM_LOGIC;
172 | }
173 | for (TSASTNodeType type : TSASTNodeType.values()) {
174 | if (type.name().equals(name)) {
175 | return type;
176 | }
177 | }
178 | return TSASTNodeType.UNKNOWN;
179 | }
180 |
181 | public static TSASTNodeType getNodeTypeForObject(String name, TSASTNode actNode) {
182 | for (TSASTNodeType type : TSASTNodeType.values()) {
183 | if (type.name().equals(name)) {
184 | if (actNode.getType() == TSASTNodeType.GIFBUILDER && type.name().equals("IMAGE")) {
185 | return GIFBUILDER_IMAGE;
186 | }
187 | if (actNode.getType() == TSASTNodeType.GIFBUILDER && type.name().equals("TEXT")) {
188 | return GIFBUILDER_TEXT;
189 | }
190 | return type;
191 | }
192 | }
193 | return getNodeTypeForObject(name);
194 | }
195 |
196 | public String getTypeString() {
197 | return this.name();
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/typinghooks/TSTypedTextInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2013 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.typinghooks;
40 |
41 | import javax.swing.text.BadLocationException;
42 | import javax.swing.text.Document;
43 | import net.dfranek.typoscript.TSLanguage;
44 | import net.dfranek.typoscript.lexer.TSLexerUtils;
45 | import net.dfranek.typoscript.lexer.TSTokenId;
46 | import org.netbeans.api.editor.mimelookup.MimePath;
47 | import org.netbeans.api.editor.mimelookup.MimeRegistration;
48 | import org.netbeans.api.lexer.Token;
49 | import org.netbeans.api.lexer.TokenId;
50 | import org.netbeans.api.lexer.TokenSequence;
51 | import org.netbeans.editor.BaseDocument;
52 | import org.netbeans.spi.editor.typinghooks.TypedTextInterceptor;
53 |
54 | /**
55 | *
56 | * @author Daniel Franek
57 | */
58 | public class TSTypedTextInterceptor implements TypedTextInterceptor {
59 |
60 | @Override
61 | public boolean beforeInsert(Context cntxt) throws BadLocationException {
62 | return false;
63 | }
64 |
65 | @Override
66 | public void insert(MutableContext context) throws BadLocationException {
67 | Document document = context.getDocument();
68 | BaseDocument doc = (BaseDocument) document;
69 | int caretOffset = context.getOffset();
70 | char ch = context.getText().charAt(0);
71 | if (doNotAutoComplete(ch) || caretOffset == 0) {
72 | return;
73 | }
74 | String selection = context.getReplacedText();
75 | if (selection != null && selection.length() > 0) {
76 | if ((ch == '[' || ch == '{')) {
77 | char firstChar = selection.charAt(0);
78 | if (firstChar != ch) {
79 |
80 | int lastChar = selection.charAt(selection.length() - 1);
81 | // Replace the surround-with chars?
82 | if (selection.length() > 1
83 | && ((firstChar == '"' || firstChar == '\'' || firstChar == '('
84 | || firstChar == '{' || firstChar == '[')
85 | && lastChar == matching(firstChar))) {
86 | String innerText = selection.substring(1, selection.length() - 1);
87 | String text = Character.toString(ch) + innerText + Character.toString(matching(ch));
88 | context.setText(text, text.length());
89 | } else {
90 | String text = ch + selection + matching(ch);
91 | context.setText(text, text.length());
92 | }
93 | }
94 | }
95 | }
96 | if (ch == '[') {
97 | completeOpeningBracket(context, ch);
98 | }
99 | }
100 |
101 | private boolean doNotAutoComplete(final char ch) {
102 | return (ch != '[' && ch != '{');
103 | }
104 |
105 | /**
106 | * Returns for an opening bracket or quote the appropriate closing
107 | * character.
108 | */
109 | private char matching(char bracket) {
110 | switch (bracket) {
111 | case '(':
112 | return ')';
113 | case '/':
114 | return '/';
115 | case '[':
116 | return ']';
117 | case '\"':
118 | return '\"'; // NOI18N
119 | case '\'':
120 | return '\'';
121 | case '{':
122 | return '}';
123 | case '}':
124 | return '{';
125 | default:
126 | return bracket;
127 | }
128 | }
129 |
130 | /**
131 | * Check for various conditions and possibly add a pairing bracket to the
132 | * already inserted.
133 | *
134 | * @param doc the document
135 | * @param dotPos position of the opening bracket (already in the doc)
136 | * @param caret caret
137 | * @param bracket the bracket that was inserted
138 | */
139 | private void completeOpeningBracket(MutableContext context, char bracket) throws BadLocationException {
140 | if(completeBracket(context)) {
141 | StringBuilder sb = new StringBuilder();
142 | sb.append(bracket);
143 | sb.append(matching(bracket));
144 | context.setText(sb.toString(), 1);
145 | }
146 | }
147 |
148 | private boolean completeBracket(MutableContext context) {
149 | int offset = context.getOffset();
150 | final BaseDocument doc = (BaseDocument) context.getDocument();
151 | TokenSequence extends TSTokenId> ts = TSLexerUtils.getTSTokenSequence(doc, offset);
152 | if (ts == null) {
153 | return true;
154 | }
155 | ts.move(offset);
156 | if (!ts.moveNext() && !ts.movePrevious()) {
157 | return true;
158 | }
159 | Token extends TSTokenId> token = ts.token();
160 | TokenId id = token.id();
161 |
162 | return id != TSTokenId.TS_CURLY_OPEN;
163 | }
164 |
165 | @Override
166 | public void afterInsert(Context cntxt) throws BadLocationException {
167 | // deliberatly empty
168 | }
169 |
170 | @Override
171 | public void cancelled(Context cntxt) {
172 | // deliberatly empty
173 | }
174 |
175 | @MimeRegistration(mimeType = TSLanguage.TS_MIME_TYPE, service = TypedTextInterceptor.Factory.class)
176 | public static class Factory implements TypedTextInterceptor.Factory {
177 |
178 | @Override
179 | public TypedTextInterceptor createTypedTextInterceptor(MimePath mimePath) {
180 | return new TSTypedTextInterceptor();
181 | }
182 | }
183 |
184 | }
185 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/indent/TSBracesMatcher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.indent;
40 |
41 | import javax.swing.text.AbstractDocument;
42 | import javax.swing.text.BadLocationException;
43 | import net.dfranek.typoscript.lexer.TSLexerUtils;
44 | import net.dfranek.typoscript.lexer.TSTokenId;
45 | import org.netbeans.api.lexer.Token;
46 | import org.netbeans.api.lexer.TokenId;
47 | import org.netbeans.api.lexer.TokenSequence;
48 | import org.netbeans.editor.BaseDocument;
49 | import org.netbeans.modules.csl.api.OffsetRange;
50 | import org.netbeans.spi.editor.bracesmatching.BracesMatcher;
51 | import org.netbeans.spi.editor.bracesmatching.MatcherContext;
52 |
53 | /**
54 | *
55 | * @author Daniel Franek
56 | */
57 | public class TSBracesMatcher implements BracesMatcher {
58 |
59 | MatcherContext context;
60 |
61 | TSBracesMatcher(MatcherContext mc) {
62 | context = mc;
63 | }
64 |
65 | @Override
66 | public int[] findOrigin() throws InterruptedException, BadLocationException {
67 | ((AbstractDocument) context.getDocument()).readLock();
68 | try {
69 | BaseDocument doc = (BaseDocument) context.getDocument();
70 | int offset = context.getSearchOffset();
71 |
72 | TokenSequence ts = TSLexerUtils.getTSTokenSequence(doc, offset);
73 |
74 | if (ts != null) {
75 | ts.move(offset);
76 |
77 | if (!ts.moveNext()) {
78 | return null;
79 | }
80 |
81 | Token token = ts.token();
82 |
83 | if (token == null) {
84 | return null;
85 | }
86 |
87 | TokenId id = token.id();
88 |
89 | if (TSLexerUtils.textEquals(token.text(), '(')) {
90 | return new int [] { ts.offset(), ts.offset() + token.length() };
91 | } else if (TSLexerUtils.textEquals(token.text(), ')')) {
92 | return new int [] { ts.offset(), ts.offset() + token.length() };
93 | } else if (id == TSTokenId.TS_CURLY_OPEN) {
94 | return new int [] { ts.offset(), ts.offset() + token.length() };
95 | } else if (id == TSTokenId.TS_CURLY_CLOSE) {
96 | return new int [] { ts.offset(), ts.offset() + token.length() };
97 | } else if (TSLexerUtils.textEquals(token.text(), '[')) {
98 | return new int [] { ts.offset(), ts.offset() + token.length() };
99 | } else if (TSLexerUtils.textEquals(token.text(), ']')) {
100 | return new int [] { ts.offset(), ts.offset() + token.length() };
101 | }
102 |
103 | }
104 | return null;
105 | } finally {
106 | ((AbstractDocument) context.getDocument()).readUnlock();
107 | }
108 | }
109 |
110 | @Override
111 | public int[] findMatches() throws InterruptedException, BadLocationException {
112 | ((AbstractDocument) context.getDocument()).readLock();
113 | try {
114 | BaseDocument doc = (BaseDocument) context.getDocument();
115 | int offset = context.getSearchOffset();
116 |
117 | TokenSequence ts = TSLexerUtils.getTSTokenSequence(doc, offset);
118 |
119 | if (ts != null) {
120 | ts.move(offset);
121 |
122 | if (!ts.moveNext()) {
123 | return null;
124 | }
125 |
126 | Token token = ts.token();
127 |
128 | if (token == null) {
129 | return null;
130 | }
131 |
132 | TokenId id = token.id();
133 |
134 | OffsetRange r;
135 | if (TSLexerUtils.textEquals(token.text(), '(')) {
136 | r = TSLexerUtils.findFwd(ts, TSTokenId.TS_PARANTHESE_OPEN, '(', TSTokenId.TS_PARANTHESE_CLOSE, ')');
137 | return new int [] {r.getStart(), r.getEnd() };
138 | } else if (TSLexerUtils.textEquals(token.text(), ')')) {
139 | r = TSLexerUtils.findBwd(ts, TSTokenId.TS_PARANTHESE_OPEN, '(', TSTokenId.TS_PARANTHESE_CLOSE, ')');
140 | return new int [] {r.getStart(), r.getEnd() };
141 | } else if (id == TSTokenId.TS_CURLY_OPEN) {
142 | r= TSLexerUtils.findFwd(ts, TSTokenId.TS_CURLY_OPEN ,'{', TSTokenId.TS_CURLY_CLOSE, '}');
143 | return new int [] {r.getStart(), r.getEnd() };
144 | } else if (id == TSTokenId.TS_CURLY_CLOSE) {
145 | r = TSLexerUtils.findBwd(ts, TSTokenId.TS_CURLY_OPEN, '{', TSTokenId.TS_CURLY_CLOSE, '}');
146 | return new int [] {r.getStart(), r.getEnd() };
147 | } else if (TSLexerUtils.textEquals(token.text(), '[')) {
148 | r = TSLexerUtils.findFwd(ts, TSTokenId.TS_OPERATOR, '[', TSTokenId.TS_OPERATOR, ']');
149 | return new int [] {r.getStart(), r.getEnd() };
150 | } else if (TSLexerUtils.textEquals(token.text(), ']')) {
151 | r = TSLexerUtils.findBwd(ts, TSTokenId.TS_OPERATOR, '[', TSTokenId.TS_OPERATOR, ']');
152 | return new int [] {r.getStart(), r.getEnd() };
153 | }
154 | }
155 | return null;
156 | } finally {
157 | ((AbstractDocument) context.getDocument()).readUnlock();
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/test/unit/src/net/dfranek/typoscript/lexer/TSLexerTestUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.lexer;
40 |
41 | import java.io.BufferedReader;
42 | import java.io.File;
43 | import java.io.FileInputStream;
44 | import java.io.InputStreamReader;
45 | import junit.framework.TestCase;
46 | import org.netbeans.api.lexer.*;
47 | import org.netbeans.lib.lexer.LexerUtilsConstants;
48 |
49 | /**
50 | *
51 | * @author Daniel Franek
52 | *
53 | * parts of the code are from LexerTestUtilities (org.netbeans.lib.lexer.test)
54 | */
55 | public class TSLexerTestUtils extends TestCase{
56 |
57 | public static TokenSequence> seqForText(String text, Language language) {
58 | TokenHierarchy> hi = TokenHierarchy.create(text, language);
59 | return hi.tokenSequence(language);
60 | }
61 |
62 | public static void next(TokenSequence> ts, TokenId id, String fixedText) {
63 | assertTrue(ts.moveNext());
64 | TSLexerTestUtils.assertTokenEquals("Token index[" + ts.index() + "]", ts, id, fixedText, -1);
65 | }
66 |
67 | /**
68 | * Compare TokenSequence.token() to the given
69 | * token id, text and offset.
70 | *
71 | * @param message
72 | * @param ts
73 | * @param id
74 | * @param text
75 | * @param offset expected offset. It may be -1 to prevent offset testing.
76 | */
77 | public static void assertTokenEquals(String message, TokenSequence> ts, TokenId id, String text, int offset) {
78 | message = messagePrefix(message);
79 | Token> t = ts.token();
80 | TestCase.assertNotNull("Token is null", t);
81 | TokenId tId = t.id();
82 | TestCase.assertEquals(message + "Invalid token.id() for text=\"" + debugTextOrNull(t.text()) + '"', id, tId);
83 | CharSequence tText = t.text();
84 | assertTextEquals(message + "Invalid token.text() for id=" + LexerUtilsConstants.idToString(id), text, tText);
85 | // The token's length must correspond to text.length()
86 | TestCase.assertEquals(message + "Invalid token.length()", text.length(), t.length());
87 |
88 | if (offset != -1) {
89 | int tsOffset = ts.offset();
90 | TestCase.assertEquals(message + "Invalid tokenSequence.offset()", offset, tsOffset);
91 |
92 | // It should also be true that if the token is non-flyweight then
93 | // ts.offset() == t.offset()
94 | // and if it's flyweight then t.offset() == -1
95 | int tOffset = t.offset(null);
96 | assertTokenOffsetMinusOneForFlyweight(t.isFlyweight(), tOffset);
97 | if (!t.isFlyweight()) {
98 | assertTokenOffsetsEqual(message, tOffset, offset);
99 | }
100 | }
101 | }
102 |
103 | private static String messagePrefix(String message) {
104 | if (message != null) {
105 | message = message + ": ";
106 | } else {
107 | message = "";
108 | }
109 | return message;
110 | }
111 |
112 | /**
113 | * Return the given text as String
114 | * translating the special characters (and '\') into escape sequences.
115 | *
116 | * @param text non-null text to be debugged.
117 | * @return non-null string containing the debug text or "null".
118 | */
119 | public static String debugTextOrNull(CharSequence text) {
120 | return (text != null) ? debugText(text) : "";
121 | }
122 |
123 | public static void assertTextEquals(String message, CharSequence expected, CharSequence actual) {
124 | if (!textEquals(expected, actual)) {
125 | TestCase.fail(messagePrefix(message) +
126 | " expected:\"" + expected + "\" but was:\"" + actual + "\"");
127 | }
128 | }
129 |
130 | /**
131 | * Return the given text as String
132 | * translating the special characters (and '\') into escape sequences.
133 | *
134 | * @param text non-null text to be debugged.
135 | * @return non-null string containing the debug text.
136 | */
137 | public static String debugText(CharSequence text) {
138 | return TokenUtilities.debugText(text);
139 | }
140 |
141 | /**
142 | * Compare whether the two character sequences represent the same text.
143 | * @param text1
144 | * @param text2
145 | * @return
146 | */
147 | public static boolean textEquals(CharSequence text1, CharSequence text2) {
148 | return TokenUtilities.equals(text1, text2);
149 | }
150 |
151 | private static void assertTokenOffsetMinusOneForFlyweight(boolean tokenFlyweight, int offset) {
152 | if (tokenFlyweight) {
153 | TestCase.assertEquals("Flyweight token => token.offset()=-1", -1, offset);
154 | } else { // non-flyweight
155 | TestCase.assertTrue("Non-flyweight token => token.offset()!=-1 but " + offset, (offset != -1));
156 | }
157 | }
158 |
159 | public static void assertTokenOffsetsEqual(String message, int offset1, int offset2) {
160 | if (offset1 != -1 && offset2 != -1) { // both non-flyweight
161 | TestCase.assertEquals(messagePrefix(message)
162 | + "Offsets equal", offset1, offset2);
163 | }
164 | }
165 |
166 | public static String getFileContent (File file) throws Exception{
167 | StringBuilder sb = new StringBuilder();
168 | String lineSep = "\n";//NOI18N
169 | try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))) {
170 | String line = br.readLine();
171 | while (line != null) {
172 | sb.append(line);
173 | sb.append(lineSep);
174 | line = br.readLine();
175 | }
176 | }
177 | return sb.toString();
178 | }
179 |
180 | }
181 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/TSLanguage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript;
40 |
41 | import static net.dfranek.typoscript.TSLanguage.TS_MIME_TYPE;
42 | import net.dfranek.typoscript.completion.TSCodeCompletion;
43 | import net.dfranek.typoscript.lexer.TSTokenId;
44 | import net.dfranek.typoscript.nav.TSDeclarationFinder;
45 | import net.dfranek.typoscript.parser.TSParser;
46 | import net.dfranek.typoscript.parser.TSStructureScanner;
47 | import org.netbeans.api.lexer.Language;
48 | import org.netbeans.api.templates.TemplateRegistration;
49 | import org.netbeans.api.templates.TemplateRegistrations;
50 | import org.netbeans.core.spi.multiview.MultiViewElement;
51 | import org.netbeans.core.spi.multiview.text.MultiViewEditorElement;
52 | import org.netbeans.modules.csl.api.CodeCompletionHandler;
53 | import org.netbeans.modules.csl.api.DeclarationFinder;
54 | import org.netbeans.modules.csl.api.StructureScanner;
55 | import org.netbeans.modules.csl.spi.DefaultLanguageConfig;
56 | import org.netbeans.modules.csl.spi.LanguageRegistration;
57 | import org.netbeans.modules.parsing.spi.Parser;
58 | import org.netbeans.modules.parsing.spi.indexing.PathRecognizerRegistration;
59 | import org.openide.WizardDescriptor;
60 | import org.openide.awt.ActionID;
61 | import org.openide.awt.ActionReference;
62 | import org.openide.awt.ActionReferences;
63 | import org.openide.filesystems.MIMEResolver;
64 | import org.openide.util.Lookup;
65 | import org.openide.windows.TopComponent;
66 |
67 | /**
68 | *
69 | * @author Daniel Franek
70 | */
71 |
72 | @LanguageRegistration(mimeType=TSLanguage.TS_MIME_TYPE, useMultiview = true)
73 | @PathRecognizerRegistration(mimeTypes = TSLanguage.TS_MIME_TYPE, libraryPathIds = {}, binaryLibraryPathIds = {}) //NOI18N
74 | @ActionReferences({
75 | @ActionReference(
76 | path = "Loaders/text/x-typoscript/Actions",
77 | id = @ActionID(category = "System", id = "org.openide.actions.PropertiesAction"),
78 | position = 100,
79 | separatorAfter = 200
80 | ),
81 | @ActionReference(
82 | path = "Loaders/text/x-typoscript/Actions",
83 | id = @ActionID(category = "Edit", id = "org.openide.actions.DeleteAction"),
84 | position = 300
85 | ),
86 | @ActionReference(
87 | path = "Loaders/text/x-typoscript/Actions",
88 | id = @ActionID(category = "Edit", id = "org.openide.actions.CopyAction"),
89 | position = 400,
90 | separatorAfter = 500
91 | ),
92 | @ActionReference(
93 | path = "Loaders/text/x-typoscript/Actions",
94 | id = @ActionID(category = "System", id = "org.openide.actions.FileSystemAction"),
95 | position = 600
96 | ),
97 | @ActionReference(
98 | path = "Loaders/text/x-typoscript/Actions",
99 | id = @ActionID(category = "System", id = "org.openide.actions.SaveAsTemplateAction"),
100 | position = 700,
101 | separatorAfter = 800
102 | ),
103 | @ActionReference(
104 | path = "Loaders/text/x-typoscript/Actions",
105 | id = @ActionID(category = "System", id = "org.openide.actions.ToolsAction"),
106 | position = 900,
107 | separatorAfter = 1000
108 | ),
109 | @ActionReference(
110 | path = "Loaders/text/x-typoscript/Actions",
111 | id = @ActionID(category = "System", id = "org.openide.actions.OpenAction"),
112 | position = 1100,
113 | separatorAfter = 1200
114 | ),
115 | @ActionReference(
116 | path = "Loaders/text/x-typoscript/Actions",
117 | id = @ActionID(category = "System", id = "org.openide.actions.RenameAction"),
118 | position = 1400
119 | ),
120 | })
121 | @MIMEResolver.Registration(
122 | displayName = "#text/x-typoscript",
123 | resource = "resources/TSResolver.xml"
124 | )
125 | public class TSLanguage extends DefaultLanguageConfig {
126 |
127 | private static final String LINE_COMMENT_PREFIX = "#";//NOI18N
128 | public static final String TS_MIME_TYPE = "text/x-typoscript";//NOI18N
129 |
130 | @MultiViewElement.Registration(
131 | displayName="#LBL_TSEditorTab",
132 | iconBase="net/dfranek/typoscript/resources/ts_file_16.png",
133 | persistenceType=TopComponent.PERSISTENCE_ONLY_OPENED,
134 | preferredID="ts.source",
135 | mimeType=TS_MIME_TYPE,
136 | position=1
137 | )
138 | public static MultiViewEditorElement createMultiViewEditorElement(Lookup context) {
139 | return new MultiViewEditorElement(context);
140 | }
141 |
142 | @TemplateRegistrations({
143 | @TemplateRegistration(folder = "TypoScript", content = "resources/templates/TSTemplate.ts", description = "resources/templates/TSTemplate.html", displayName = "#Templates/TypoScript/TSTemplate.ts", scriptEngine = "freemarker"),
144 | @TemplateRegistration(folder = "TypoScript", content = "resources/templates/TSTemplateComments.ts", description = "resources/templates/TSTemplateComments.html", displayName = "#Templates/TypoScript/TSTemplateComments.ts", scriptEngine = "freemarker"),
145 | @TemplateRegistration(folder = "TypoScript", content = "resources/templates/TSTemplateHTML5Advanced.ts", description = "resources/templates/TSTemplateHTML5Advanced.html", displayName = "#Templates/TypoScript/TSTemplateHTML5Advanced.ts", scriptEngine = "freemarker"),
146 | @TemplateRegistration(folder = "TypoScript", content = "resources/templates/TSTemplateHTML5Multilingual.ts", description = "resources/templates/TSTemplateHTML5Multilingual.html", displayName = "#Templates/TypoScript/TSTemplateHTML5Multilingual.ts", scriptEngine = "freemarker"),
147 | @TemplateRegistration(folder = "TypoScript", content = "resources/templates/TSTemplateRTE.ts", description = "resources/templates/TSTemplateRTE.html", displayName = "#Templates/TypoScript/TSTemplateRTE.ts", scriptEngine = "freemarker")
148 | })
149 | @SuppressWarnings("rawtypes")
150 | public static WizardDescriptor.InstantiatingIterator templateIterator() {
151 | return null;
152 | }
153 |
154 | @Override
155 | public Language getLexerLanguage() {
156 | return TSTokenId.getLanguage();
157 | }
158 |
159 | @Override
160 | public String getDisplayName() {
161 | return "TypoScript";
162 | }
163 |
164 | @Override
165 | public String getLineCommentPrefix() {
166 | return LINE_COMMENT_PREFIX;
167 | }
168 |
169 | @Override
170 | public String getPreferredExtension() {
171 | return "ts";
172 | }
173 |
174 |
175 | @Override
176 | public boolean isIdentifierChar(char c) {
177 | return Character.isJavaIdentifierPart(c);
178 | }
179 |
180 | @Override
181 | public CodeCompletionHandler getCompletionHandler() {
182 | return new TSCodeCompletion();
183 | }
184 |
185 | @Override
186 | public Parser getParser() {
187 | return new TSParser();
188 | }
189 |
190 | @Override
191 | public boolean hasStructureScanner() {
192 | return true;
193 | }
194 |
195 | @Override
196 | public StructureScanner getStructureScanner() {
197 | return new TSStructureScanner();
198 | }
199 |
200 | @Override
201 | public DeclarationFinder getDeclarationFinder() {
202 | return new TSDeclarationFinder();
203 | }
204 |
205 | }
206 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/typinghooks/TSTypedBreakInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2013 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.typinghooks;
40 |
41 | import java.util.Arrays;
42 | import java.util.List;
43 | import javax.swing.text.BadLocationException;
44 | import net.dfranek.typoscript.TSLanguage;
45 | import net.dfranek.typoscript.lexer.TSLexerUtils;
46 | import net.dfranek.typoscript.lexer.TSTokenId;
47 | import org.netbeans.api.editor.mimelookup.MimePath;
48 | import org.netbeans.api.editor.mimelookup.MimeRegistration;
49 | import org.netbeans.api.lexer.Token;
50 | import org.netbeans.api.lexer.TokenId;
51 | import org.netbeans.api.lexer.TokenSequence;
52 | import org.netbeans.editor.BaseDocument;
53 | import org.netbeans.editor.Utilities;
54 | import org.netbeans.modules.csl.api.OffsetRange;
55 | import org.netbeans.modules.editor.indent.api.IndentUtils;
56 | import org.netbeans.spi.editor.typinghooks.TypedBreakInterceptor;
57 |
58 | /**
59 | *
60 | * @author Daniel Franek
61 | */
62 | public class TSTypedBreakInterceptor implements TypedBreakInterceptor {
63 |
64 | @Override
65 | public boolean beforeInsert(Context cntxt) throws BadLocationException {
66 | return false;
67 | }
68 |
69 | @Override
70 | public void insert(MutableContext context) throws BadLocationException {
71 | final BaseDocument doc = (BaseDocument) context.getDocument();
72 | int offset = context.getCaretOffset();
73 | int lineBegin = Utilities.getRowStart(doc, offset);
74 | int lineEnd = Utilities.getRowEnd(doc, offset);
75 | if (lineBegin == offset && lineEnd == offset) {
76 | // Pressed return on a blank newline - do nothing
77 | return;
78 | }
79 | TokenSequence extends TSTokenId> ts = TSLexerUtils.getTSTokenSequence(doc, offset);
80 | if (ts == null) {
81 | return;
82 | }
83 | ts.move(offset);
84 | if (!ts.moveNext() && !ts.movePrevious()) {
85 | return;
86 | }
87 | Token extends TSTokenId> token = ts.token();
88 | TokenId id = token.id();
89 |
90 | // Insert an end statement? Insert a } marker?
91 | int[] startOfContext = new int[1];
92 | TSTokenId completeIn = findContextForEnd(ts, offset, startOfContext);
93 | boolean insert = completeIn != null && isEndMissing(doc, offset, completeIn);
94 | if (insert) {
95 | int indent = IndentUtils.lineIndent(doc, IndentUtils.lineStartOffset(doc, startOfContext[0]));
96 | int afterLastNonWhite = Utilities.getRowLastNonWhite(doc, offset);
97 |
98 | int newIndent = ((indent / IndentUtils.tabSize(doc)) + 1) * IndentUtils.tabSize(doc);
99 |
100 | StringBuilder sb = new StringBuilder("\n");
101 | String restOfLine = doc.getText(offset, Utilities.getRowEnd(doc, afterLastNonWhite) - offset);
102 | sb.append(restOfLine);
103 | sb.append(IndentUtils.createIndentString(doc, newIndent));
104 | sb.append("\n"); //NOI18N
105 | sb.append(IndentUtils.createIndentString(doc, indent));
106 | doc.remove(offset, restOfLine.length());
107 | if(completeIn == TSTokenId.TS_CURLY_OPEN) {
108 | sb.append('}');
109 | }
110 | if(completeIn == TSTokenId.TS_PARANTHESE_OPEN) {
111 | sb.append(')');
112 | }
113 |
114 | context.setText(sb.toString(), 0, IndentUtils.createIndentString(doc, newIndent).length()+1);
115 | }
116 | }
117 |
118 | private TSTokenId findContextForEnd(TokenSequence extends TSTokenId> ts, int offset, int[] startOfContext) {
119 | if (ts == null) {
120 | return null;
121 | }
122 | if (ts.offset() != offset) {
123 | ts.move(offset);
124 |
125 | if (!ts.moveNext() && !ts.movePrevious()) {
126 | return null;
127 | }
128 | }
129 | TSTokenId result = null;
130 |
131 | // at fist there should be find a bracket '{' or column ':'
132 | Token extends TSTokenId> bracketColumnToken = TSLexerUtils.findPrevious(ts,
133 | Arrays.asList(TSTokenId.TS_COMMENT, TSTokenId.WHITESPACE, TSTokenId.TS_NL, TSTokenId.TS_VALUE, TSTokenId.TS_MULTILINE_VALUE)
134 | );
135 |
136 | if (bracketColumnToken != null
137 | && (bracketColumnToken.id() == TSTokenId.TS_CURLY_OPEN ||
138 | bracketColumnToken.id() == TSTokenId.TS_PARANTHESE_OPEN
139 | )) {
140 | startOfContext[0] = ts.offset();
141 | // we are interested only in adding end for { or alternative syntax :
142 | List lookFor = Arrays.asList(TSTokenId.TS_CURLY_CLOSE, TSTokenId.TS_CURLY_OPEN, TSTokenId.TS_PARANTHESE_CLOSE, TSTokenId.TS_PARANTHESE_OPEN);
143 | Token extends TSTokenId> keyToken = TSLexerUtils.findPreviousToken(ts, lookFor);
144 |
145 | if (bracketColumnToken.id() == TSTokenId.TS_CURLY_OPEN) {
146 | result = TSTokenId.TS_CURLY_OPEN;
147 | }
148 |
149 | if (bracketColumnToken.id() == TSTokenId.TS_PARANTHESE_OPEN) {
150 | result = TSTokenId.TS_PARANTHESE_OPEN;
151 | }
152 |
153 | if (keyToken.id() != TSTokenId.TS_CURLY_CLOSE && keyToken.id() != TSTokenId.TS_PARANTHESE_CLOSE) {
154 | startOfContext[0] = ts.offset();
155 | }
156 | }
157 | ts.move(offset);
158 | if (!ts.moveNext() && !ts.movePrevious()) {
159 | return null;
160 | }
161 | return result;
162 | }
163 |
164 | private boolean isEndMissing(BaseDocument doc, int offset, TSTokenId startTokenId) throws BadLocationException {
165 | TokenSequence extends TSTokenId> ts = TSLexerUtils.getTSTokenSequence(doc, offset);
166 | if (ts == null) {
167 | return false;
168 | }
169 | ts.move(0);
170 | if (!ts.moveNext() && !ts.movePrevious()) {
171 | return false;
172 | }
173 | Token extends TSTokenId> token;
174 | int curlyBalance = 0;
175 | boolean curlyProcessed = false;
176 | if (startTokenId == TSTokenId.TS_CURLY_OPEN) {
177 | do {
178 | token = ts.token();
179 | if (token.id() == TSTokenId.TS_CURLY_CLOSE) {
180 | curlyBalance--;
181 | curlyProcessed = true;
182 | } else if (token.id() == TSTokenId.TS_CURLY_OPEN) { //NOI18N
183 | curlyBalance++;
184 | curlyProcessed = true;
185 | }
186 |
187 | if (curlyBalance == 0 && curlyProcessed && ts.offset() > offset) {
188 | break;
189 | }
190 | } while (ts.moveNext());
191 | return curlyBalance > 0;
192 | }
193 |
194 | ts.move(offset);
195 | if (startTokenId == TSTokenId.TS_PARANTHESE_OPEN) {
196 | OffsetRange r = TSLexerUtils.findFwd(ts, TSTokenId.TS_PARANTHESE_OPEN, '(', TSTokenId.TS_PARANTHESE_CLOSE, ')');
197 | if (r == OffsetRange.NONE) {
198 | return true;
199 | }
200 | }
201 |
202 | return false;
203 | }
204 |
205 | @Override
206 | public void afterInsert(Context cntxt) throws BadLocationException {
207 | // deliberatly empty
208 | }
209 |
210 | @Override
211 | public void cancelled(Context cntxt) {
212 | // deliberatly empty
213 | }
214 |
215 | @MimeRegistration(mimeType = TSLanguage.TS_MIME_TYPE, service = TypedBreakInterceptor.Factory.class)
216 | public static class PhpFactory implements TypedBreakInterceptor.Factory {
217 |
218 | @Override
219 | public TypedBreakInterceptor createTypedBreakInterceptor(MimePath mimePath) {
220 | return new TSTypedBreakInterceptor();
221 | }
222 | }
223 |
224 | }
225 |
--------------------------------------------------------------------------------
/test/unit/src/net/dfranek/typoscript/lexer/TSScannerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.lexer;
40 |
41 | import junit.framework.TestCase;
42 | import org.junit.Test;
43 | import org.netbeans.api.lexer.TokenSequence;
44 | import org.openide.util.Utilities;
45 |
46 | /**
47 | *
48 | * @author Daniel Franek
49 | */
50 | public class TSScannerTest extends TestCase {
51 |
52 | @Test
53 | public void testLineComment() {
54 | TokenSequence> ts = TSLexerTestUtils.seqForText("# comment\n", TSTokenId.getLanguage());
55 | TSLexerTestUtils.next(ts, TSTokenId.TS_COMMENT, "# comment");
56 | TSLexerTestUtils.next(ts, TSTokenId.TS_NL, "\n");
57 | }
58 |
59 | @Test
60 | public void testMultiLineComment() {
61 | TokenSequence> ts = TSLexerTestUtils.seqForText("/* first line\n*second line\n*/\n", TSTokenId.getLanguage());
62 | TSLexerTestUtils.next(ts, TSTokenId.TS_MULTILINE_COMMENT, "/* first line\n");
63 | TSLexerTestUtils.next(ts, TSTokenId.TS_MULTILINE_COMMENT, "*second line\n");
64 | TSLexerTestUtils.next(ts, TSTokenId.TS_MULTILINE_COMMENT, "*/");
65 | TSLexerTestUtils.next(ts, TSTokenId.TS_NL, "\n");
66 | }
67 |
68 | @Test
69 | public void testProperty() {
70 | TokenSequence> ts = TSLexerTestUtils.seqForText("page.10.marks.TEST = something", TSTokenId.getLanguage());
71 | TSLexerTestUtils.next(ts, TSTokenId.TS_KEYWORD, "page");
72 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
73 | TSLexerTestUtils.next(ts, TSTokenId.TS_NUMBER, "10");
74 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
75 | TSLexerTestUtils.next(ts, TSTokenId.TS_KEYWORD, "marks");
76 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
77 | TSLexerTestUtils.next(ts, TSTokenId.TS_PROPERTY, "TEST");
78 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, " ");
79 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, "=");
80 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, " ");
81 | TSLexerTestUtils.next(ts, TSTokenId.TS_VALUE, "something");
82 | }
83 |
84 | @Test
85 | public void testExampleFile() throws Exception {
86 | TokenSequence> ts = TSLexerTestUtils.seqForText(TSLexerTestUtils.getFileContent(Utilities.toFile(TSScannerTest.class.getResource("/net/dfranek/typoscript/lexer/TSExample").toURI())), TSTokenId.getLanguage());
87 | TSLexerTestUtils.next(ts, TSTokenId.TS_PROPERTY, "headerimg");
88 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
89 | TSLexerTestUtils.next(ts, TSTokenId.TS_RESERVED, "file");
90 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, " ");
91 | TSLexerTestUtils.next(ts, TSTokenId.TS_CURLY_OPEN, "{");
92 | TSLexerTestUtils.next(ts, TSTokenId.TS_NL, "\n");
93 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, "\t");
94 | TSLexerTestUtils.next(ts, TSTokenId.TS_KEYWORD, "XY");
95 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, " ");
96 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, "=");
97 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, " ");
98 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, "[");
99 | TSLexerTestUtils.next(ts, TSTokenId.TS_NUMBER, "10");
100 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
101 | TSLexerTestUtils.next(ts, TSTokenId.TS_VALUE, "w");
102 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, "]");
103 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, "+");
104 | TSLexerTestUtils.next(ts, TSTokenId.TS_NUMBER, "2");
105 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ",");
106 | TSLexerTestUtils.next(ts, TSTokenId.TS_NUMBER, "20");
107 | TSLexerTestUtils.next(ts, TSTokenId.TS_NL, "\n");
108 | TSLexerTestUtils.next(ts, TSTokenId.TS_CURLY_CLOSE, "}");
109 | TSLexerTestUtils.next(ts, TSTokenId.TS_NL, "\n");
110 | TSLexerTestUtils.next(ts, TSTokenId.TS_NL, "\n");
111 | TSLexerTestUtils.next(ts, TSTokenId.TS_CONDITION, "[globalVar=TSFE:type = 0]");
112 | TSLexerTestUtils.next(ts, TSTokenId.TS_NL, "\n");
113 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, "\t");
114 | TSLexerTestUtils.next(ts, TSTokenId.TS_KEYWORD, "page");
115 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
116 | TSLexerTestUtils.next(ts, TSTokenId.TS_RESERVED, "typeNum");
117 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, " ");
118 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, "=");
119 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, " ");
120 | TSLexerTestUtils.next(ts, TSTokenId.TS_NUMBER, "0");
121 | TSLexerTestUtils.next(ts, TSTokenId.TS_NL, "\n");
122 | TSLexerTestUtils.next(ts, TSTokenId.TS_CONDITION, "[global]");
123 | TSLexerTestUtils.next(ts, TSTokenId.TS_NL, "\n");
124 | TSLexerTestUtils.next(ts, TSTokenId.TS_NL, "\n");
125 | TSLexerTestUtils.next(ts, TSTokenId.TS_KEYWORD, "page");
126 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
127 | TSLexerTestUtils.next(ts, TSTokenId.TS_NUMBER, "10");
128 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
129 | TSLexerTestUtils.next(ts, TSTokenId.TS_RESERVED, "value");
130 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, " ");
131 | TSLexerTestUtils.next(ts, TSTokenId.TS_PARANTHESE_OPEN, "(");
132 | TSLexerTestUtils.next(ts, TSTokenId.TS_MULTILINE_VALUE, "\n\tMulti\n\tLine\n\tValue\n");
133 | TSLexerTestUtils.next(ts, TSTokenId.TS_PARANTHESE_CLOSE, ")");
134 | }
135 |
136 | @Test
137 | public void testEqualsInValue() {
138 | TokenSequence> ts = TSLexerTestUtils.seqForText("page.10.marks.TEST.select.where = colPos=0\npage.typeNum=0", TSTokenId.getLanguage());
139 | TSLexerTestUtils.next(ts, TSTokenId.TS_KEYWORD, "page");
140 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
141 | TSLexerTestUtils.next(ts, TSTokenId.TS_NUMBER, "10");
142 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
143 | TSLexerTestUtils.next(ts, TSTokenId.TS_KEYWORD, "marks");
144 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
145 | TSLexerTestUtils.next(ts, TSTokenId.TS_PROPERTY, "TEST");
146 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
147 | TSLexerTestUtils.next(ts, TSTokenId.TS_FUNCTION, "select");
148 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
149 | TSLexerTestUtils.next(ts, TSTokenId.TS_RESERVED, "where");
150 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, " ");
151 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, "=");
152 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, " ");
153 | TSLexerTestUtils.next(ts, TSTokenId.TS_VALUE, "colPos");
154 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, "=");
155 | TSLexerTestUtils.next(ts, TSTokenId.TS_NUMBER, "0");
156 | TSLexerTestUtils.next(ts, TSTokenId.TS_NL, "\n");
157 | TSLexerTestUtils.next(ts, TSTokenId.TS_KEYWORD, "page");
158 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
159 | TSLexerTestUtils.next(ts, TSTokenId.TS_RESERVED, "typeNum");
160 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, "=");
161 | TSLexerTestUtils.next(ts, TSTokenId.TS_NUMBER, "0");
162 | }
163 |
164 | public void testOpeningCurly() {
165 | TokenSequence> ts = TSLexerTestUtils.seqForText("page{", TSTokenId.getLanguage());
166 | TSLexerTestUtils.next(ts, TSTokenId.TS_KEYWORD, "page");
167 | TSLexerTestUtils.next(ts, TSTokenId.TS_CURLY_OPEN, "{");
168 | }
169 |
170 | public void testConstantAndComment() {
171 | TokenSequence> ts = TSLexerTestUtils.seqForText("shortcutIcon = {$filepaths.templates.images}favicon.icon # But doesn't work ofcourse", TSTokenId.getLanguage());
172 | TSLexerTestUtils.next(ts, TSTokenId.TS_RESERVED, "shortcutIcon");
173 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, " ");
174 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, "=");
175 | TSLexerTestUtils.next(ts, TSTokenId.WHITESPACE, " ");
176 | TSLexerTestUtils.next(ts, TSTokenId.TS_CONSTANT, "{$filepaths.templates.images}");
177 | TSLexerTestUtils.next(ts, TSTokenId.TS_VALUE, "favicon");
178 | TSLexerTestUtils.next(ts, TSTokenId.TS_OPERATOR, ".");
179 | TSLexerTestUtils.next(ts, TSTokenId.TS_RESERVED, "icon");
180 | }
181 |
182 | }
183 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/lexer/TSLexerUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.lexer;
40 |
41 | import com.google.gson.Gson;
42 | import java.io.InputStreamReader;
43 | import java.util.ArrayList;
44 | import java.util.Collection;
45 | import java.util.HashMap;
46 | import java.util.List;
47 | import java.util.Map;
48 | import javax.swing.text.Document;
49 | import org.netbeans.api.lexer.Token;
50 | import org.netbeans.api.lexer.TokenHierarchy;
51 | import org.netbeans.api.lexer.TokenId;
52 | import org.netbeans.api.lexer.TokenSequence;
53 | import org.netbeans.modules.csl.api.OffsetRange;
54 |
55 | /**
56 | *
57 | * @author Daniel Franek
58 | */
59 | public class TSLexerUtils {
60 |
61 | protected static HashMap> completionList = new HashMap<>();
62 | protected static HashMap keywords;
63 |
64 |
65 | @SuppressWarnings("unchecked")
66 | public static TokenSequence getTSTokenSequence(TokenHierarchy> th, int offset) {
67 | TokenSequence ts = th == null ? null : th.tokenSequence(TSTokenId.getLanguage());
68 | if (ts == null) {
69 | // Possibly an embedding scenario such as an RHTML file
70 | // First try with backward bias true
71 | List> list = th.embeddedTokenSequences(offset, true);
72 | for (TokenSequence> t : list) {
73 | if (t.language() == TSTokenId.getLanguage()) {
74 | ts = (TokenSequence) t;
75 | break;
76 | }
77 | }
78 | if (ts == null) {
79 | list = th.embeddedTokenSequences(offset, false);
80 | for (TokenSequence> t : list) {
81 | if (t.language() == TSTokenId.getLanguage()) {
82 | ts = (TokenSequence) t;
83 | break;
84 | }
85 | }
86 | }
87 | }
88 | return ts;
89 | }
90 |
91 | @SuppressWarnings("unchecked")
92 | public static TokenSequence getTSTokenSequence(Document doc, int offset) {
93 | TokenHierarchy th = TokenHierarchy.get(doc);
94 | return getTSTokenSequence(th, offset);
95 | }
96 |
97 | public static boolean textEquals(CharSequence text1, char... text2) {
98 | int len = text1.length();
99 | if (len == text2.length) {
100 | for (int i = len - 1; i >= 0; i--) {
101 | if (text1.charAt(i) != text2[i]) {
102 | return false;
103 | }
104 | }
105 | return true;
106 | }
107 | return false;
108 | }
109 |
110 | /**
111 | * Search forwards in the token sequence until a token of type
112 | * down is found
113 | */
114 | public static OffsetRange findFwd(TokenSequence extends TSTokenId> ts, TSTokenId tokenUpId, char up, TSTokenId tokenDownId, char down) {
115 | int balance = 0;
116 |
117 | while (ts.moveNext()) {
118 | Token extends TSTokenId> token = ts.token();
119 |
120 | if ((token.id() == tokenUpId && textEquals(token.text(), up))/*
121 | * || (tokenUpId == TSTokenId.TS_CURLY_OPEN && token.id() ==
122 | * TSTokenId.PHP_TOKEN &&
123 | * token.text().charAt(token.text().length() - 1) == '{')
124 | */) {
125 | balance++;
126 | } else if (token.id() == tokenDownId && textEquals(token.text(), down)) {
127 | if (balance == 0) {
128 | return new OffsetRange(ts.offset(), ts.offset() + token.length());
129 | }
130 |
131 | balance--;
132 | }
133 | }
134 |
135 | return OffsetRange.NONE;
136 | }
137 |
138 | /**
139 | * Search backwards in the token sequence until a token of type
140 | * up is found
141 | */
142 | public static OffsetRange findBwd(TokenSequence extends TSTokenId> ts, TSTokenId tokenUpId, char up, TSTokenId tokenDownId, char down) {
143 | int balance = 0;
144 |
145 | while (ts.movePrevious()) {
146 | Token extends TSTokenId> token = ts.token();
147 | TokenId id = token.id();
148 |
149 | if (token.id() == tokenUpId && textEquals(token.text(), up)/*
150 | * || (tokenUpId == PHPTokenId.PHP_CURLY_OPEN && token.id()
151 | * == PHPTokenId.PHP_TOKEN &&
152 | * token.text().charAt(token.text().length() - 1) == '{')
153 | */) {
154 | if (balance == 0) {
155 | return new OffsetRange(ts.offset(), ts.offset() + token.length());
156 | }
157 |
158 | balance++;
159 | } else if (token.id() == tokenDownId && textEquals(token.text(), down)) {
160 | balance--;
161 | }
162 | }
163 |
164 | return OffsetRange.NONE;
165 | }
166 |
167 | public static OffsetRange findNextStartsWith(TokenSequence extends TSTokenId> ts, TSTokenId tokenId, String startsWith) {
168 | while (ts.moveNext()) {
169 | Token extends TSTokenId> token = ts.token();
170 | TokenId id = token.id();
171 | if (token.id() == tokenId && token.text().toString().startsWith(startsWith)) {
172 | return new OffsetRange(ts.offset(), ts.offset() + token.length());
173 | }
174 | }
175 | return OffsetRange.NONE;
176 | }
177 |
178 |
179 | public static OffsetRange findNextEndsWith(TokenSequence extends TSTokenId> ts, TSTokenId tokenId, String endsWith) {
180 | while (ts.moveNext()) {
181 | Token extends TSTokenId> token = ts.token();
182 | TokenId id = token.id();
183 | if (token.id() == tokenId && token.text().toString().endsWith(endsWith)) {
184 | return new OffsetRange(ts.offset(), ts.offset() + token.length());
185 | }
186 | }
187 | return OffsetRange.NONE;
188 | }
189 |
190 |
191 | public static Token extends TSTokenId> findFwdNonSpace(TokenSequence extends TSTokenId> ts) {
192 | while (ts.moveNext() && ts.token().id().equals(TSTokenId.WHITESPACE)) {}
193 | return ts.token();
194 | }
195 |
196 | public static Token extends TSTokenId> findBwdNonSpace(TokenSequence extends TSTokenId> ts) {
197 | while (ts.movePrevious() && ts.token().id().equals(TSTokenId.WHITESPACE)) {}
198 | return ts.token();
199 | }
200 |
201 | public static String getWordFromXML(String word) {
202 | String propertyType = "";
203 | if(keywords.containsKey(word)) {
204 | propertyType = keywords.get(word);
205 | }
206 |
207 | return propertyType;
208 | }
209 |
210 | public static Collection getAllKeywordsOfType(String type) {
211 | if(completionList.containsKey(type)) {
212 | return completionList.get(type);
213 | }
214 | Collection properties = new ArrayList<>();
215 | for (Map.Entry entry : keywords.entrySet()) {
216 | String property = entry.getKey();
217 | if (entry.getValue().equals(type)) {
218 | properties.add(property);
219 | }
220 | }
221 | completionList.put(type, properties);
222 |
223 | return properties;
224 | }
225 |
226 | @SuppressWarnings("unchecked")
227 | static void initKeywords() {
228 | Gson gson = new Gson();
229 | keywords = gson.fromJson(new InputStreamReader(TSLexerUtils.class.getResourceAsStream("/net/dfranek/typoscript/resources/properties.json")), HashMap.class);
230 | }
231 |
232 | public static boolean tokenIsKeyword(TSTokenId id) {
233 | return id.equals(TSTokenId.TS_OBJECT) || id.equals(TSTokenId.TS_EXTENSION) || id.equals(TSTokenId.TS_PROPERTY) || id.equals(TSTokenId.TS_NUMBER) || id.equals(TSTokenId.TS_KEYWORD) || id.equals(TSTokenId.TS_RESERVED) || id.equals(TSTokenId.TS_FUNCTION);
234 | }
235 |
236 | public static Token findPrevious(TokenSequence ts, List ignores) {
237 | if (ignores.contains(ts.token().id())) {
238 | while (ts.movePrevious() && ignores.contains(ts.token().id())) {
239 | }
240 | }
241 | return ts.token();
242 | }
243 |
244 | public static Token findPreviousToken(TokenSequence ts, List lookfor) {
245 | if (!lookfor.contains(ts.token().id())) {
246 | while (ts.movePrevious() && !lookfor.contains(ts.token().id())) {
247 | }
248 | }
249 | return ts.token();
250 | }
251 |
252 | }
253 |
--------------------------------------------------------------------------------
/src/net/dfranek/typoscript/parser/TSTokenParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 | *
4 | * Copyright 2011 Daniel Franek.
5 | *
6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 | * Other names may be trademarks of their respective owners.
8 | *
9 | * The contents of this file are subject to the terms of either the GNU
10 | * General Public License Version 2 only ("GPL") or the Common
11 | * Development and Distribution License("CDDL") (collectively, the
12 | * "License"). You may not use this file except in compliance with the
13 | * License. You can obtain a copy of the License at
14 | * http://www.netbeans.org/cddl-gplv2.html
15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 | * specific language governing permissions and limitations under the
17 | * License. When distributing the software, include this License Header
18 | * Notice in each file and include the License file at
19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 | * particular file as subject to the "Classpath" exception as provided
21 | * by Oracle in the GPL Version 2 section of the License file that
22 | * accompanied this code. If applicable, add the following below the
23 | * License Header, with the fields enclosed by brackets [] replaced by
24 | * your own identifying information:
25 | * "Portions Copyrighted [year] [name of copyright owner]"
26 | *
27 | * If you wish your version of this file to be governed by only the CDDL
28 | * or only the GPL Version 2, indicate your decision by adding
29 | * "[Contributor] elects to include this software in this distribution
30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 | * single choice of license, a recipient has the option to distribute
32 | * your version of this file under either the CDDL, the GPL Version 2 or
33 | * to extend the choice of license to its licensees as provided above.
34 | * However, if you add GPL Version 2 code and therefore, elected the GPL
35 | * Version 2 license, then the option applies only if the new code is
36 | * made subject to such option by the copyright holder.
37 | *
38 | */
39 | package net.dfranek.typoscript.parser;
40 |
41 | import java.util.Arrays;
42 | import java.util.HashMap;
43 | import java.util.List;
44 | import java.util.Map;
45 | import net.dfranek.typoscript.lexer.TSLexerUtils;
46 | import net.dfranek.typoscript.lexer.TSTokenId;
47 | import net.dfranek.typoscript.parser.ast.TSASTNode;
48 | import net.dfranek.typoscript.parser.ast.TSASTNodeType;
49 | import org.netbeans.api.lexer.Token;
50 | import org.netbeans.api.lexer.TokenSequence;
51 | import org.netbeans.modules.csl.api.OffsetRange;
52 | import org.netbeans.modules.csl.api.Severity;
53 | import org.netbeans.modules.parsing.api.Snapshot;
54 |
55 | /**
56 | *
57 | * @author Daniel Franek, Eric Waldburger
58 | */
59 | public class TSTokenParser {
60 |
61 | private final TokenSequence sequence;
62 | private Snapshot snapshot;
63 | private TSBracketNode last = new TSBracketNode("root", null);
64 | private final TSBracketNode root = last;
65 | private final TSASTNode tree;
66 | private boolean conditionOpen;
67 | private final TSParserResult result;
68 |
69 | TSTokenParser(TokenSequence source, Snapshot snapshot) {
70 | this.conditionOpen = false;
71 | sequence = source;
72 | this.snapshot = snapshot;
73 | result = new TSParserResult(snapshot);
74 | tree = new TSASTNode("", "", TSASTNodeType.ROOTLEVEL, 0, 1);
75 | }
76 |
77 | TSTokenParser(TokenSequence source) {
78 | this.conditionOpen = false;
79 | sequence = source;
80 | result = new TSParserResult(snapshot);
81 | tree = new TSASTNode("", "", TSASTNodeType.ROOTLEVEL, 0, 1);
82 | }
83 |
84 | public TSParserResult analyze() {
85 | result.setSequence(sequence);
86 |
87 | checkErrors();
88 | buildTree();
89 |
90 | return result;
91 | }
92 |
93 | private void checkBraces(TSTokenId id, Token t, TokenSequence ts) {
94 | List tokensToCheck = Arrays.asList(
95 | TSTokenId.TS_CURLY_OPEN,
96 | TSTokenId.TS_CURLY_CLOSE,
97 | TSTokenId.TS_PARANTHESE_OPEN,
98 | TSTokenId.TS_PARANTHESE_CLOSE,
99 | TSTokenId.TS_CONDITION,
100 | TSTokenId.TS_VALUE,
101 | TSTokenId.TS_MULTILINE_VALUE,
102 | TSTokenId.TS_OPERATOR
103 | );
104 |
105 | //Bracket Handling
106 | if(tokensToCheck.contains(id)) {
107 | String tokenText = t.text().toString();
108 | if (id == TSTokenId.TS_CURLY_OPEN) {
109 | if (last == null) {
110 | last = new TSBracketNode("{", null, ts.offset());
111 | } else {
112 | last.setNext(new TSBracketNode("{", last, ts.offset()));
113 | last = last.getNext();
114 | }
115 | result.addCodeBlock(new OffsetRange(last.getOffset(), ts.offset()));
116 | } else if (id == TSTokenId.TS_CURLY_CLOSE) {
117 | if (last.getValue().equals("{")) {
118 | last = last.getPrev();
119 | last.setNext(null);
120 | } else {
121 | result.addError(new TSError("No matching brace found for " + last.getValue(), snapshot.getSource().getFileObject(), id.getStart(), id.getEnd(), Severity.ERROR, new Object[]{this}));
122 | }
123 | } else if (id == TSTokenId.TS_PARANTHESE_OPEN) {
124 | if (last == null) {
125 | last = new TSBracketNode("(", null, ts.offset());
126 | } else {
127 | last.setNext(new TSBracketNode("(", last, ts.offset()));
128 | last = last.getNext();
129 | }
130 | result.addCodeBlock(new OffsetRange(last.getOffset(), ts.offset()));
131 | } else if (id == TSTokenId.TS_PARANTHESE_CLOSE) {
132 | if (last.getValue().equals("(")) {
133 | last = last.getPrev();
134 | last.setNext(null);
135 | } else {
136 | result.addError(new TSError("No matching paranthese found for " + last.getValue(), snapshot.getSource().getFileObject(), id.getStart(), id.getEnd(), Severity.ERROR, new Object[]{this}));
137 | }
138 | } else if (tokenText.equals("[")) {
139 | if (last == null) {
140 | last = new TSBracketNode("[", null, ts.offset());
141 | } else {
142 | last.setNext(new TSBracketNode("[", last, ts.offset()));
143 | last = last.getNext();
144 | }
145 | } else if (tokenText.equals("]")) {
146 | if (last.getValue().equals("[")) {
147 | last = last.getPrev();
148 | last.setNext(null);
149 | } else {
150 | result.addError(new TSError("No matching bracket found for " + last.getValue(), snapshot.getSource().getFileObject(), id.getStart(), id.getEnd(), Severity.ERROR, new Object[]{this}));
151 | }
152 | } else if (id == TSTokenId.TS_CONDITION && (!tokenText.equals("[global]") && !tokenText.equals("[end]"))) {
153 | conditionOpen = true;
154 | result.addCodeBlock(new OffsetRange(ts.offset(), ts.offset() + t.length()));
155 | } else if (id == TSTokenId.TS_CONDITION && tokenText.equals("[global]")) {
156 | conditionOpen = false;
157 | }
158 | }
159 | }
160 |
161 | public TSASTNode buildTree() {
162 | TSASTNode node;
163 | Token t;
164 | TSTokenId id;
165 | TSASTNode actNode = tree;
166 |
167 | sequence.moveStart();
168 | int curlyDepth = 0;
169 | Map curlyHierarchy = new HashMap<>();
170 | curlyHierarchy.put(curlyDepth, tree);
171 | while (sequence.moveNext()) {
172 | //content of token
173 | t = sequence.token();
174 | //type of token
175 | id = t.id();
176 | if (isPossibleParent(id)) {
177 | TSASTNode newActNode = actNode;
178 | node = new TSASTNode(t.text().toString(), "", TSASTNodeType.getNodeTypeForObject(t.text().toString()), sequence.offset(), t.length());
179 | if (actNode.hasChild(node)) {
180 | node = actNode.getChild(node.getName());
181 | }
182 |
183 | Token extends TSTokenId> tVal = TSLexerUtils.findFwdNonSpace(sequence);
184 | if (tVal.id().equals(TSTokenId.TS_OPERATOR) && tVal.text().toString().equals("=")) {
185 | tVal = TSLexerUtils.findFwdNonSpace(sequence);
186 | if (tVal.id().equals(TSTokenId.TS_OBJECT)) {
187 | node.setType(TSASTNodeType.getNodeTypeForObject(tVal.text().toString(), actNode));
188 | } else {
189 | String tokenText = "";
190 | sequence.movePrevious();
191 | while (sequence.moveNext() && !sequence.token().id().equals(TSTokenId.TS_NL)) {
192 | tokenText += sequence.token().text().toString();
193 | }
194 | sequence.movePrevious();
195 | node.setValue(tokenText);
196 | if(!node.isTypeSet()) {
197 | node.setType(TSASTNodeType.VALUE);
198 | }
199 | }
200 | newActNode = actNode;
201 | } else if (tVal.id().equals(TSTokenId.TS_PARANTHESE_OPEN)||tVal.id().equals(TSTokenId.TS_PARANTHESE_CLOSE)) {
202 | tVal = TSLexerUtils.findFwdNonSpace(sequence);
203 | node.setValue(tVal.text().toString().trim());
204 | node.setType(TSASTNodeType.VALUE);
205 | } else if ((tVal.id().equals(TSTokenId.TS_OPERATOR) && tVal.text().toString().equals("."))) {
206 | newActNode = node;
207 | } else if ((tVal.id().equals(TSTokenId.TS_OPERATOR) && tVal.text().toString().equals(">"))) {
208 | node.setType(TSASTNodeType.CLEARED_PROPERY);
209 | } else if ((tVal.id().equals(TSTokenId.TS_OPERATOR) && tVal.text().toString().equals("<"))) {
210 | String tokenText = "";
211 | while (sequence.moveNext() && !sequence.token().id().equals(TSTokenId.TS_NL)) {
212 | tokenText += sequence.token().text().toString();
213 | }
214 | sequence.movePrevious();
215 | node.setValue(tokenText.trim());
216 | node.setType(TSASTNodeType.COPIED_PROPERTY);
217 | } else if (tVal.id().equals(TSTokenId.TS_CURLY_OPEN)) {
218 | newActNode = node;
219 | curlyDepth++;
220 | curlyHierarchy.put(curlyDepth, node);
221 | }
222 | if (!actNode.hasChild(node)) {
223 | actNode.addChild(node);
224 | actNode = newActNode;
225 | } else {
226 | actNode = newActNode;
227 | }
228 | }
229 | if (id.equals(TSTokenId.TS_NL)) {
230 | actNode = curlyHierarchy.get(curlyDepth);
231 | }
232 | if (curlyDepth > 0 && id.equals(TSTokenId.TS_CURLY_CLOSE)) {
233 | curlyDepth--;
234 | actNode = curlyHierarchy.get(curlyDepth);
235 | } else if(id.equals(TSTokenId.TS_CONDITION)) {
236 | if (t.text().toString().equals("[global]")) {
237 | actNode = tree;
238 | curlyHierarchy.put(curlyDepth, tree);
239 | } else {
240 | node = new TSASTNode(t.text().toString(), "", TSASTNodeType.CONDITION, sequence.offset(), t.length(), String.valueOf(sequence.offset()));
241 | tree.addChild(node);
242 | curlyHierarchy.put(0, node);
243 | }
244 | }
245 | }
246 |
247 | result.setTree(tree);
248 | return tree;
249 | }
250 |
251 | public void checkErrors() {
252 | Token t;
253 | TSTokenId id;
254 |
255 | while (sequence.moveNext()) {
256 | //content of token
257 | t = sequence.token();
258 | //type of token
259 | id = t.id();
260 |
261 | if (id == TSTokenId.TS_MULTILINE_COMMENT && t.text().toString().startsWith("/*")) {
262 | result.addCodeBlock(new OffsetRange(sequence.offset(), sequence.offset() + 1));
263 | }
264 |
265 | // DF: ausgelagert in eigene Funktion
266 | checkBraces(id, t, sequence);
267 | }
268 |
269 | if (conditionOpen) {
270 | result.addError(new TSError("Not all conditions were ended with [global]", snapshot.getSource().getFileObject(), snapshot.getSource().getDocument(true).getLength() - 1, snapshot.getSource().getDocument(true).getLength(), Severity.WARNING, new Object[]{this}));
271 | }
272 |
273 | TSBracketNode end = root.getNext();
274 | if (end != null) {
275 | String message;
276 | if ("(".equals(end.getValue())) {
277 | message = "A multiline value section is not ended with a parenthesis!";
278 | } else {
279 | message = "An end brace is in excess.";
280 | }
281 | result.addError(new TSError(message, snapshot.getSource().getFileObject(), snapshot.getSource().getDocument(true).getLength() - 1, snapshot.getSource().getDocument(true).getLength(), Severity.ERROR, new Object[]{this}));
282 | }
283 |
284 | }
285 |
286 | protected boolean isPossibleParent(TSTokenId id) {
287 | return TSLexerUtils.tokenIsKeyword(id);
288 | }
289 |
290 | }
291 |
--------------------------------------------------------------------------------
/nbproject/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.netbeans.modules.apisupport.project
4 |
5 |
6 | net.dfranek.typoscript
7 |
8 |
9 |
10 | org.netbeans.api.templates
11 |
12 |
13 |
14 | 1.5.1
15 |
16 |
17 |
18 | org.netbeans.core.multiview
19 |
20 |
21 |
22 | 1
23 | 1.29.1
24 |
25 |
26 |
27 | org.netbeans.modules.autoupdate.services
28 |
29 |
30 |
31 | 1.33.1
32 |
33 |
34 |
35 | org.netbeans.modules.csl.api
36 |
37 |
38 |
39 | 2
40 | 2.28.1.2.1.1.6
41 |
42 |
43 |
44 | org.netbeans.modules.editor.bracesmatching
45 |
46 |
47 |
48 | 0-1
49 | 1.22.1
50 |
51 |
52 |
53 | org.netbeans.modules.editor.fold
54 |
55 |
56 |
57 | 1
58 | 1.29.1.31
59 |
60 |
61 |
62 | org.netbeans.modules.editor.indent
63 |
64 |
65 |
66 | 2
67 | 1.34.1
68 |
69 |
70 |
71 | org.netbeans.modules.editor.lib
72 |
73 |
74 |
75 | 3
76 | 3.24.1.19.31
77 |
78 |
79 |
80 | org.netbeans.modules.editor.lib2
81 |
82 |
83 |
84 | 1
85 | 1.81.1.43
86 |
87 |
88 |
89 | org.netbeans.modules.editor.mimelookup
90 |
91 |
92 |
93 | 1
94 | 1.26.1
95 |
96 |
97 |
98 | org.netbeans.modules.lexer
99 |
100 |
101 |
102 | 2
103 | 1.46.1.1
104 |
105 |
106 |
107 | org.netbeans.modules.parsing.api
108 |
109 |
110 |
111 | 1
112 | 1.55.1.6
113 |
114 |
115 |
116 | org.netbeans.modules.parsing.indexing
117 |
118 |
119 |
120 | 9.6.1.1.1.8
121 |
122 |
123 |
124 | org.netbeans.spi.navigator
125 |
126 |
127 |
128 | 1
129 | 1.23.1
130 |
131 |
132 |
133 | org.openide.awt
134 |
135 |
136 |
137 | 7.62.1
138 |
139 |
140 |
141 | org.openide.dialogs
142 |
143 |
144 |
145 | 7.38.1
146 |
147 |
148 |
149 | org.openide.filesystems
150 |
151 |
152 |
153 | 7.62.1
154 |
155 |
156 |
157 | org.openide.loaders
158 |
159 |
160 |
161 | 7.57.1
162 |
163 |
164 |
165 | org.openide.modules
166 |
167 |
168 |
169 | 7.32.1
170 |
171 |
172 |
173 | org.openide.nodes
174 |
175 |
176 |
177 | 7.28.1
178 |
179 |
180 |
181 | org.openide.util
182 |
183 |
184 |
185 | 8.25.1
186 |
187 |
188 |
189 | org.openide.util.lookup
190 |
191 |
192 |
193 | 8.15.1
194 |
195 |
196 |
197 | org.openide.util.ui
198 |
199 |
200 |
201 | 9.3.1
202 |
203 |
204 |
205 | org.openide.windows
206 |
207 |
208 |
209 | 6.55.1
210 |
211 |
212 |
213 |
214 |
215 | unit
216 |
217 | org.netbeans.libs.junit4
218 |
219 |
220 |
221 | org.netbeans.modules.csl.api
222 |
223 |
224 |
225 | org.netbeans.modules.nbjunit
226 |
227 |
228 |
229 |
230 |
231 |
232 | ext/gson-2.2.2.jar
233 | release/modules/ext/gson-2.2.2.jar
234 |
235 |
236 |
237 |
238 |
--------------------------------------------------------------------------------