diff --git a/lib/linguist/heuristics.yml b/lib/linguist/heuristics.yml index 67891bd2ab..3368b3a801 100644 --- a/lib/linguist/heuristics.yml +++ b/lib/linguist/heuristics.yml @@ -340,6 +340,11 @@ disambiguations: - language: C++ named_pattern: cpp - language: C +- extensions: ['.hb'] + rules: + - language: Handlebars + pattern: '\{\{' + - language: Harbour - extensions: ['.hh'] rules: - language: Hack diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index 9bde77235a..a8fa123b3a 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -2933,6 +2933,7 @@ Handlebars: - htmlbars extensions: - ".handlebars" + - ".hb" - ".hbs" tm_scope: text.html.handlebars ace_mode: handlebars @@ -2945,6 +2946,8 @@ Harbour: tm_scope: source.harbour ace_mode: text language_id: 156 + interpreters: + - hbmk2 Haskell: type: programming color: "#5e5086" diff --git a/samples/Handlebars/html.hb b/samples/Handlebars/html.hb new file mode 100644 index 0000000000..c2e137a6d9 --- /dev/null +++ b/samples/Handlebars/html.hb @@ -0,0 +1,34 @@ +{{!-- Generate a simple HTML report --}} + + + System Summary + + + +

System Summary

+

Generated at {{ctime}}

+ +{{#servers}} +

{{name}}

+ {{#inspectors}}{{#alarms}} + {{name}}: {{fired}}
+ {{/alarms}}{{/inspectors}} + {{#inspectors}} +

{{name}}

+

Type: {{type}}

+ +

{{{text}}}

+ {{/inspectors}} +
+{{/servers}} + +

+ Generated by SshSysMon +

+ + + \ No newline at end of file diff --git a/samples/Handlebars/node.js.hb b/samples/Handlebars/node.js.hb new file mode 100644 index 0000000000..ac0a96c5ac --- /dev/null +++ b/samples/Handlebars/node.js.hb @@ -0,0 +1,16 @@ +var exec = require('child_process').exec; + +exec('{{escapeBackslashes command}}{{#if task}} {{escapeBackslashes task}}{{/if}}{{#if args}} {{{escapeBackslashes args}}}{{/if}}', { + cwd: '{{escapeBackslashes gruntfileDirectory}}' + }, function (err, stdout, stderr) { + + var exitCode = 0; + if (err) { + console.log(stderr || err); + exitCode = -1; + }{{#unless preventExit}} + + process.exit(exitCode);{{/unless}} +}).stdout.on('data', function (chunk){ + process.stdout.write(chunk); +}); \ No newline at end of file diff --git a/samples/Harbour/hbmk2_qtgt.hb b/samples/Harbour/hbmk2_qtgt.hb new file mode 100644 index 0000000000..33bcc6bc2c --- /dev/null +++ b/samples/Harbour/hbmk2_qtgt.hb @@ -0,0 +1,218 @@ +/* + * hbmk2 plugin script, implementing support for QT specific features + * + * Copyright 2010 Viktor Szakats (vszakats.net/harbour) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * (or visit their website at https://www.gnu.org/licenses/). + * + */ + +#pragma -w3 +#pragma -km+ +#pragma -ko+ + +#include "directry.ch" +#include "hbclass.ch" +#include "error.ch" + +#define I_( x ) hb_i18n_gettext( x ) + +FUNCTION hbmk_plugin_qt( hbmk ) + + LOCAL cRetVal := "" + + LOCAL cSrc + LOCAL cDst + LOCAL tSrc + LOCAL tDst + + LOCAL cCommand + LOCAL nError + LOCAL lBuildIt + + SWITCH hbmk[ "cSTATE" ] + CASE "init" + + hbmk_Register_Input_File_Extension( hbmk, ".h" ) + + EXIT + + CASE "pre_all" + + /* Gather input parameters */ + + hbmk[ "vars" ][ "aMOC_Src" ] := {} + + FOR EACH cSrc IN hbmk[ "params" ] + IF ! Left( cSrc, 1 ) == "-" .AND. ; + Lower( hb_FNameExt( cSrc ) ) == ".h" + + AAdd( hbmk[ "vars" ][ "aMOC_Src" ], cSrc ) + ENDIF + NEXT + + /* Create output file lists */ + + hbmk[ "vars" ][ "aMOC_Dst" ] := {} + FOR EACH cSrc IN hbmk[ "vars" ][ "aMOC_Src" ] + cDst := hbmk_FNameDirExtSet( "moc_" + hb_FNameName( cSrc ), hbmk[ "cWorkDir" ], ".cpp" ) + AAdd( hbmk[ "vars" ][ "aMOC_Dst" ], cDst ) + hbmk_AddInput_CPP( hbmk, cDst ) + NEXT + + /* Detect tool locations */ + + IF ! hbmk[ "lCLEAN" ] + IF ! Empty( hbmk[ "vars" ][ "aMOC_Src" ] ) + hbmk[ "vars" ][ "cMOC_BIN" ] := qt_tool_detect( hbmk, "moc", "MOC_BIN", .T. ) + IF Empty( hbmk[ "vars" ][ "cMOC_BIN" ] ) + cRetVal := I_( "Required QT tool not found" ) + ENDIF + ENDIF + ENDIF + + EXIT + + CASE "pre_c" + + IF ! hbmk[ "lCLEAN" ] .AND. ; + ! Empty( hbmk[ "vars" ][ "aMOC_Src" ] ) + + IF ! Empty( hbmk[ "vars" ][ "cMOC_BIN" ] ) + + /* Execute 'moc' commands on input files */ + + FOR EACH cSrc, cDst IN hbmk[ "vars" ][ "aMOC_Src" ], hbmk[ "vars" ][ "aMOC_Dst" ] + + IF hbmk[ "lINC" ] .AND. ! hbmk[ "lREBUILD" ] + lBuildIt := ! hb_FGetDateTime( cDst, @tDst ) .OR. ; + ! hb_FGetDateTime( cSrc, @tSrc ) .OR. ; + tSrc > tDst + ELSE + lBuildIt := .T. + ENDIF + + IF lBuildIt + + cCommand := hbmk[ "vars" ][ "cMOC_BIN" ] +; + " " + hbmk_FNameEscape( hbmk, hbmk_PathSepToTarget( hbmk, cSrc ) ) +; + " -o " + hbmk_FNameEscape( hbmk, hbmk_PathSepToTarget( hbmk, cDst ) ) + + IF hbmk[ "lTRACE" ] + IF ! hbmk[ "lQUIET" ] + hbmk_OutStd( hbmk, I_( "'moc' command:" ) ) + ENDIF + hbmk_OutStdRaw( hbmk, cCommand ) + ENDIF + + IF ! hbmk[ "lDONTEXEC" ] .AND. ( nError := hb_processRun( cCommand ) ) != 0 + hbmk_OutErr( hbmk, hb_StrFormat( I_( "Error: Running 'moc' executable. %1$d" ), nError ) ) + IF ! hbmk[ "lQUIET" ] + hbmk_OutErrRaw( hbmk, cCommand ) + ENDIF + IF ! hbmk[ "lIGNOREERROR" ] + cRetVal := "error" + EXIT + ENDIF + ENDIF + ENDIF + NEXT + ENDIF + ENDIF + + EXIT + + CASE "post_all" + + IF ! hbmk[ "lINC" ] .OR. hbmk[ "lCLEAN" ] + AEval( hbmk[ "vars" ][ "aMOC_Dst" ], {| tmp | FErase( tmp ) } ) + ENDIF + + EXIT + + ENDSWITCH + + RETURN cRetVal + +STATIC FUNCTION qt_tool_detect( hbmk, cName, cEnvQT, lSuffix ) + LOCAL cBIN + LOCAL cEnv + LOCAL aEnvList + LOCAL cStdErr + + cBIN := GetEnv( cEnvQT ) + IF Empty( cBIN ) + + IF lSuffix + IF ! ( cEnv := GetEnv( "HB_QTPOSTFIX" ) ) == "" /* Compatibility */ + hb_SetEnv( "HB_QTSUFFIX", cEnv ) + ENDIF + cName += GetEnv( "HB_QTSUFFIX" ) + aEnvList := { "HB_QTPATH", "HB_QTSUFFIX" } + ELSE + aEnvList := { "HB_QTPATH" } + ENDIF + cName += hbmk[ "cCCEXT" ] + + IF Empty( cEnv := GetEnv( "HB_QTPATH" ) ) .OR. ; + ! hb_FileExists( cBIN := hb_DirSepAdd( cEnv ) + cName ) + + #if ! defined( __PLATFORM__UNIX ) + + hb_AIns( aEnvList, 1, "HB_WITH_QT", .T. ) + + IF ! Empty( cEnv := GetEnv( "HB_WITH_QT" ) ) + + IF cEnv == "no" + /* Return silently. It shall fail at dependency detection inside hbmk2 */ + RETURN NIL + ELSE + IF ! hb_FileExists( cBIN := hb_PathNormalize( hb_DirSepAdd( cEnv ) + "..\bin\" + cName ) ) + hbmk_OutErr( hbmk, hb_StrFormat( "Warning: HB_WITH_QT points to incomplete QT installation. '%1$s' executable not found.", cName ) ) + cBIN := "" + ENDIF + ENDIF + ELSE + cBIN := hb_DirSepAdd( hb_DirBase() ) + cName + IF ! hb_FileExists( cBIN ) + cBIN := "" + ENDIF + ENDIF + #else + cBIN := "" + #endif + + IF Empty( cBIN ) + cBIN := hbmk_FindInPath( cName, GetEnv( "PATH" ) + hb_osPathListSeparator() + "/opt/qtsdk/qt/bin" ) + IF Empty( cBIN ) + hbmk_OutErr( hbmk, hb_StrFormat( "%1$s not set, could not autodetect '%2$s' executable", hbmk_ArrayToList( aEnvList, ", " ), cName ) ) + RETURN NIL + ENDIF + ENDIF + ENDIF + IF hbmk[ "lINFO" ] + cStdErr := "" + IF ! hbmk[ "lDONTEXEC" ] + hb_processRun( cBIN + " -v",,, @cStdErr ) + IF ! Empty( cStdErr ) + cStdErr := " [" + StrTran( StrTran( cStdErr, Chr( 13 ) ), Chr( 10 ) ) + "]" + ENDIF + ENDIF + hbmk_OutStd( hbmk, hb_StrFormat( "Using QT '%1$s' executable: %2$s%3$s (autodetected)", cName, cBIN, cStdErr ) ) + ENDIF + ENDIF + + RETURN cBIN \ No newline at end of file diff --git a/samples/Harbour/langchk.hb b/samples/Harbour/langchk.hb new file mode 100644 index 0000000000..a4a309127b --- /dev/null +++ b/samples/Harbour/langchk.hb @@ -0,0 +1,44 @@ +/* + * Check alignment dependent lang item(s) + * + * Copyright 2013 Viktor Szakats (vszakats.net/harbour) + * + */ + +#pragma -w3 +#pragma -km+ +#pragma -ko+ + +#include "hblang.ch" + +#define LEFTEQUAL( l, r ) ( Left( l, Len( r ) ) == r ) + +PROCEDURE Main() + + LOCAL tmp + LOCAL nCount + LOCAL cName + LOCAL cPO + + cPO := ; + PadR( "en", 6 ) + ' "' + ; + PadR( "", 15, "*" ) + ; + Str( 999999999999, 12 ) + " " + ; + DToC( Date() ) + ; + Str( 999999999999, 12 ) + '"' + hb_eol() + + nCount := __dynsCount() + FOR tmp := 1 TO nCount + cName := __dynsGetName( tmp ) + IF LEFTEQUAL( cName, "HB_LANG_" ) + cName := SubStr( cName, Len( "HB_LANG_" ) + 1 ) + IF ( Len( cName ) != 5 .OR. "_" $ cName ) .AND. ; + ! "|" + cName + "|" $ "|RUKOI8|UAKOI8|ZHB5|ZHGB|" + cPO += PadR( Lower( cName ), 6 ) + ' "' + hb_langMessage( HB_LANG_ITEM_BASE_NATMSG, cName ) + '"' + hb_eol() + ENDIF + ENDIF + NEXT + + hb_MemoWrit( hb_FNameExtSet( __FILE__, ".txt" ), cPO ) + + RETURN \ No newline at end of file diff --git a/samples/Harbour/po2lang.hb b/samples/Harbour/po2lang.hb new file mode 100644 index 0000000000..74699d295f --- /dev/null +++ b/samples/Harbour/po2lang.hb @@ -0,0 +1,143 @@ +#!/usr/bin/env hbmk2 + +/* + * Converts .po files to core lang modules + * + * Copyright 2013 Viktor Szakats (vszakats.net/harbour) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * (or visit their website at https://www.gnu.org/licenses/). + * + */ + +#pragma -w3 +#pragma -km+ +#pragma -ko+ + +#include "hblang.ch" + +PROCEDURE Main_po2lang() + + POToLang( "hu.po", "l_hu.c", "hu" ) + POToLang( "el.po", "l_el.c", "el" ) + + RETURN + +STATIC FUNCTION POToLang( cFileIn, cFileOut, cLang ) + + LOCAL aTrans + LOCAL cErrorMsg + + LOCAL cContent + LOCAL cTranslator + LOCAL nPos + + IF ( aTrans := __i18n_potArrayLoad( cFileIn, @cErrorMsg ) ) != NIL + + cContent := StrTran( _begin(), e"\n", hb_eol() ) + nPos := 0 + + __i18n_potArrayClean( aTrans,,, {| cTrs, cOri | ProcessTrs( @cContent, cTrs, cOri, @cTranslator, @nPos, cLang ) } ) + + cContent := "/* Last Translator: " + MaskEMail( cTranslator ) + " */" + hb_eol() + ; + hb_StrShrink( cContent, Len( "," ) + Len( hb_eol() ) ) + hb_eol() + ; + StrTran( StrTran( _end(), e"\n", hb_eol() ), "{LNG}", Upper( cLang ) ) + + hb_MemoWrit( cFileOut, cContent ) + + RETURN .T. + ENDIF + + ? "i18n error", cErrorMsg + + RETURN .F. + +STATIC FUNCTION MaskEMail( cEMail ) + RETURN hb_StrReplace( cEMail, { ; + "@" => " " , ; + "<" => "(" , ; + ">" => ")" } ) + +STATIC PROCEDURE ProcessTrs( /* @ */ cContent, cTrs, cOri, /* @ */ cTranslator, /* @ */ nPos, cLang ) + + STATIC sc_hEmpty := { ; + 3 => { "", "UTF8", "" }, ; + 47 => { "", "" }, ; + 57 => { "" }, ; + 64 => { "", "", "", "" }, ; + 80 => { "", "", "" } } + + LOCAL tmp + + SWITCH nPos + CASE HB_LANG_ITEM_BASE_ID ; tmp := "/* Identification */" ; EXIT + CASE HB_LANG_ITEM_BASE_MONTH ; tmp := "/* Month names */" ; EXIT + CASE HB_LANG_ITEM_BASE_DAY ; tmp := "/* Day names */" ; EXIT + CASE HB_LANG_ITEM_BASE_NATMSG ; tmp := "/* CA-Cl*pper compatible natmsg items */" ; EXIT + CASE HB_LANG_ITEM_BASE_ERRDESC ; tmp := "/* Error description names */" ; EXIT + CASE HB_LANG_ITEM_BASE_ERRINTR ; tmp := "/* Internal error names */" ; EXIT + CASE HB_LANG_ITEM_BASE_TEXT ; tmp := "/* Texts */" ; EXIT + OTHERWISE ; tmp := NIL + ENDSWITCH + + IF tmp != NIL + cContent += iif( nPos > 0, hb_eol(), "" ) + Space( 2 * 3 ) + tmp + hb_eol() + hb_eol() + ENDIF + + IF nPos == 0 + cTranslator := hb_regexAll( "Last-Translator: ([^\n]*)", cTrs,,,,, .T. )[ 1 ][ 2 ] + IF cTranslator == "foo bar " + cTranslator := "" + ENDIF + cContent += Space( 2 * 3 ) + ConvToC( cLang ) + "," + hb_eol() + ++nPos + ELSE + IF cTrs == "" + cTrs := cOri + ENDIF + cContent += Space( 2 * 3 ) + ConvToC( cTrs ) + "," + hb_eol() + ++nPos + + IF nPos $ sc_hEmpty + FOR EACH tmp IN sc_hEmpty[ nPos ] + cContent += Space( 2 * 3 ) + ConvToC( tmp ) + "," + hb_eol() + NEXT + nPos += Len( sc_hEmpty[ nPos ] ) + ENDIF + ENDIF + + RETURN + +STATIC FUNCTION ConvToC( cStr ) + RETURN '"' + hb_StrReplace( cStr, { '"' => '\"' } ) + '"' + +STATIC FUNCTION _begin() +#pragma __cstream | RETURN %s + +#include "hbapilng.h" + +static HB_LANG s_lang = +{ + { +#pragma __endtext + +STATIC FUNCTION _end() +#pragma __cstream | RETURN %s + } +}; + +#define HB_LANG_ID {LNG} +#include "hbmsgreg.h" +#pragma __endtext \ No newline at end of file diff --git a/test/test_heuristics.rb b/test/test_heuristics.rb index 8277ceba53..e3fffcbbb0 100755 --- a/test/test_heuristics.rb +++ b/test/test_heuristics.rb @@ -537,6 +537,13 @@ def test_h_by_heuristics }) end + def test_hb_by_heuristics + assert_heuristics({ + "Handlebars" => all_fixtures("Handlebars", "*.hb"), + "Harbour" => all_fixtures("Harbour", "*.hb") + }) + end + def test_hh_by_heuristics assert_heuristics({ "Hack" => all_fixtures("Hack", "*.hh"),