Page 86 of 99

Posted: Tue Mar 01, 2016 11:18 am
by Skif_off
InFive
У себя сделал простенько, с панелью вывода не стал возиться

после строки

Code: Select all

var extInfo = t.toLocaleTimeString() + " " + (AkelPad.GetEditFile(0) || "*") + " -> ";
добавил

Code: Select all

if (text.indexOf(">>") >= 0)
  output(extInfo + "\">>\" was found!", 48 /*MB_ICONEXCLAMATION*/);


А зачем вам tidy от гражданина Paehl? Он берёт те же исходники и компилит, забив на WinXP. К слову, в зависимостях msvcr120.dll, а у официалльных версий отсюда - msvcr100.dll: кб ~200 разница :)

Posted: Tue Mar 01, 2016 12:13 pm
by InFive
Skif_off wrote: У себя сделал простенько, с панелью вывода не стал возиться

после строки

Code: Select all

var extInfo = t.toLocaleTimeString() + " " + (AkelPad.GetEditFile(0) || "*") + " -> ";
добавил

Code: Select all

if (text.indexOf(">>") >= 0)
  output(extInfo + "">>" was found!", 48 /*MB_ICONEXCLAMATION*/);
вариант, конечно, не практичный, но вариант... добавил себе, а там посмотрим... спасибо...
Skif_off wrote:А зачем вам tidy от гражданина Paehl?
мне не зачем... просто он был указан в сообщении со скриптом tidy.js, поэтому пробы с него и начинал...

Posted: Tue Mar 01, 2016 2:41 pm
by VladSh
Skif_off
Идея хорошая (я тоже это буду добавлять, как раз над этим сейчас работаю), но не совсем верная. Здесь нужны регулярки. Поясню.
При таком варианте:
<тэг></тэг>><тэг></тэг>
это есть ошибка.
А вот при таком:
<тэг>></тэг>
нет.
Т.е. надо искать, чтобы после ">>" и любого последующего текста шло не "</".

Кстати, такой вариант MSXML-валидатор обрабатывает успешно:
<PRODUCTS>>
<PRODUCT>
...
Выводится сообщение об ошибке:
Согласно DTD и схеме в данном контексте текст не допускается.
Требуется: PRODUCT.
Ещё вопросы в тему:
1. Как определить номер строки, если известна позиция в файле? С перебросом туда курсора получилось, но может быть есть вариант без переброса курсора?
2. Как определить номер позиции в строке, если известены позиция в файле и номер строки?

Skif_off wrote:А зачем вам tidy от гражданина Paehl?
Изначально взял из скрипта камрада se7h. Спасибо за ссылку на оригинальные версии.

Posted: Tue Mar 01, 2016 3:27 pm
by VladSh
Cuprum
По Punto.
Несмотря на то, что где-то с пол года назад добавляли функционал, который предотвращает срабатывание переключение в полях-паролях, у себя давно поставил язык ввода по умолчанию английский. С этим тоже есть некоторые неудобства, например первое слово, особенно если оно состоит из одной буквы, часто не переключается, приходится это помнить и, если не услышал звука переключения, использовать клавишу Break (Insert на ноуте).
Сейчас вышла 4.2.2, в которой заявлена переработка механизма переключения. Поглядим.

Posted: Tue Mar 01, 2016 5:27 pm
by Skif_off
VladSh
Если ошибка - на неё укажет валидатор. Так понимаю, схемы есть разные, вот для InFive обязательно, чтобы не было ">>", сам не сталкивался пока, но решил добавить на всякий случай предупреждение.
С регулярками не получится двойной как будто проверки: сначала скрипт проигнорирует, ведь в некоторых случаях допустимо, потом собственно валидатор проигнорирует?

Posted: Tue Mar 01, 2016 6:28 pm
by VladSh
Skif_off
Я уже опустил это "предупреждение" ниже валидатора - если он не сработал, тогда выполняется наша "ручная" проверка.

От регулярок мне всего лишь нужно чтобы вместо text.indexOf(">>") выполнился более сложный поиск (например text.search(/???/)), который также возвращал бы позицию найденного элемента. Логику описывал:
надо искать, чтобы после ">>" и любого последующего текста шло не "</".
т.е. выбирать случаи:

Code: Select all

>>текст<любой_символ_кроме_слэша
исключая:

Code: Select all

>>текст</

Добавлено:
Предварительная версия (может кто ещё с регуляркой всё-таки поможет):

Code: Select all

///Validates selected XML fragment or whole document, pointing potential error place
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=15256#p15256
// https://github.com/FeyFre/akelpad-customisations/blob/scripts/XMLValidator.js
// Version: ???
// Version: 2.0 (2016.02.28) by VladSh
// Version: 1.9 (2016.02.24) by Skif_off
// Version: 1.8 (2015.04.10) by VladSh
// Version: 1.7 (2014.12.01) by VladSh
// Version: 1.6 (2012.10.24) by VladSh
// Version: 1.0 (2011.10.25) (c) Panych Y.W. aka FeyFre
//
// Arguments:
//   validate:
//      • [true | без параметра] - производить проверку синтаксиса xml и валидацию согласно схеме;
//      • false - только проверку правильности структуры xml
//   parse2gt:
//      • [false | без параметра] - не производить проверку удвоенного символа '>'
//      • true - производить
//   keep:
//      • [0 | без параметра] - не сохранять исходное выделение, устанавливая курсор в место ошибки
//      • 1 - сохранять исходное выделение; если выделения нет, то курсор также будет установлен в место ошибки
//   msgOpts - параметры вывода сообщений:
//      • [0 | без параметра] - в диалоговое окно;
//      • перечень кодов сообщений через запятую, которые выводить в панели вывода Log-плагина:
//         1 - все сообщения/ошибки;
//         16 - критическая ошибка xml-парсера;
//         48 - ошибка xml-синтаксиса (можно выводить только её, т.к. можно переходить на место ошибки);
//         64 - сообщение об успешно пройденной валидации
//   append - параметры вывода в панель Log-плагина:
//      • [0 | без параметра] - очищать содержимое панели перед записью
//      • 1, 2 - не очищать (см. Log-Rus.txt -> вызов с кодом 4 -> параметр "APPEND")
//   lClose - параметры закрытия панели Log-плагина (при msgOpts=1 игнорируется):
//      • [0 | без параметра] - не закрывать (в панели может остаться нужный текст, в т.ч. и от других вкладок программы);
//      • 1 - закрывать только при успешно пройденной валидации;
//      • 2 - закрывать всегда (только при msgOpts=0)
//
// Examples:
//    Call("Scripts::Main", 1, "XMLValidator.js")               - вывод в обычное диалоговое сообщение
//    Call("Scripts::Main", 1, "XMLValidator.js", `-msgOpts=1`) - вывод всех сообщений в панель Log-плагина
//    Call("Scripts::Main", 1, "XMLValidator.js", `-msgOpts=48 -lClose=1`) - вывод в панель Log-плагина только сообщений об ошибках xml-синтаксиса с закрытием панели при успешно пройденной валидации
//    Call("Scripts::Main", 1, "XMLValidator.js", `-msgOpts=48 -append=1`) - вывод в панель Log-плагина только сообщений об ошибках xml-синтаксиса с добавлением их к уже существующим в панели сообщениям

var hWndEdit = AkelPad.GetEditWnd();
var parserName = "msxml2.DOMDocument";
var xml = new ActiveXObject(parserName);
try {
   xml.async = false;
   xml.validateOnParse = AkelPad.GetArgValue("validate", true);
   xml.resolveExternals = false;
} catch (e) {
   output("Internal parser " + parserName + " error: " + e.description, 16 /*MB_ICONSTOP*/);
}

var text = AkelPad.GetSelText();
var selection;
var bKeep = false;
if (!text) {
   text = AkelPad.GetTextRange(0, -1);
   selection = false;
} else {
   selection = true;
   var npStart = AkelPad.GetSelStart();
   var npEnd = AkelPad.GetSelEnd();
   bKeep = AkelPad.GetArgValue("keep", 0);
   var npMin = Math.min(AkelPad.GetSelStart(), AkelPad.GetSelEnd());
}
var filepos, linepos, oLine;
var linenum = 0;

var t = new Date();
var extInfo = t.toLocaleTimeString() + " " + (AkelPad.GetEditFile(0) || "*") + " -> ";

xml.loadXML(text);
if (xml.parseError.errorCode !== 0) {
   var err = xml.parseError;
   linepos = err.linepos;
   if (selection) {
      filepos = npMin + err.filepos;
      oLine = getLogLine(filepos);
      linenum = oLine.linenum;
   }
   else {
		linenum = err.line;
		filepos = err.filepos;
   }
   if (!bKeep)
   	AkelPad.SetSel(filepos, filepos);
   output(extInfo + "XML validation error:\r(" + linenum + "," + linepos + ")\t\t" + err.reason, 48 /*MB_ICONEXCLAMATION*/);
   
} else {
   if (AkelPad.GetArgValue("parse2gt", false)) {
//      filepos = text.search(/>>.*<[^\/]/);
		filepos = AkelPad.TextFind(0, "<([^>\\s]++)\\s*\\K>>++(?![^<]*+</\\1)", 0x00280001);
      if (filepos >= 0) {
         filepos += 1;
//         if (selection)
//            filepos = npMin + filepos;
         oLine = getLogLine(filepos);
         linenum = oLine.linenum;
         linepos = filepos - oLine.startpos;
         if (!bKeep)
         	AkelPad.SetSel(filepos, filepos);
         output(extInfo + "XML parsing error:\r(" + linenum + "," + linepos + ")\t\t'>>' was found.", 48 /*MB_ICONEXCLAMATION*/);
      }
   }
   output(extInfo + "XML fragment is valid.\r", 64 /*MB_ICONINFORMATION*/);
}

function output(msg, nIcon /*MB_ICON...*/) {
   var slog = AkelPad.GetArgValue("msgOpts", "0");
   if (slog == "1" || (slog != "0" && slog.indexOf(nIcon.toString()) != -1)) {
      var fLogOutput = "Log::Output";
      if (AkelPad.Call(fLogOutput, 1, "", "", "^\\((\\d+),(\\d+)\\)", "/GOTOLINE=\\1:\\2") != -1) {
         var nAppend = AkelPad.GetArgValue("append", 0);
         AkelPad.Call(fLogOutput, 4, msg, -1, nAppend);
      }
   } else {
      var lClose = AkelPad.GetArgValue("lClose", 0);
      if ((lClose == 1 && nIcon == 64) || lClose == 2)
         AkelPad.Call("Log::Output", 6);
      AkelPad.MessageBox(hWndEdit, msg, WScript.ScriptName, nIcon);
   }
   WScript.Quit();
}

// Function returns a LineObject for Log-panel
function getLogLine(filepos) {
   var wrpLine = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, filepos);
   var start = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/, wrpLine, 0);
	var unwrpLine = AkelPad.SendMessage(hWndEdit, 3143 /*AEM_GETUNWRAPLINE*/, wrpLine, 0);
	return {
		linenum: unwrpLine + 1,
		startpos: start - 1
	};
}

Posted: Tue Mar 01, 2016 6:31 pm
by KDJ
InFive wrote:

Code: Select all

Usage in menu or toolbar: 
   Call("Scripts::Main", 1, "EvalCmd.js", `if (AkelPad.Include("TextReplace_function.js")) TextReplace(sFindIt, ReplaceWith[, sFlags[, nRangeStart[, nRangeEnd]]]);`)
а что собственно должно происходить? вываливается ошибка и бросает в скрипт EvalCmd.js на строку 84 eval(pArgLine);
It seems to me that you forgot to specify the function arguments, eg:

Code: Select all

Call("Scripts::Main", 1, "EvalCmd.js", `if (AkelPad.Include("TextReplace_function.js")) TextReplace("a", "b", "g");`)

Posted: Tue Mar 01, 2016 8:17 pm
by InFive
KDJ wrote:It seems to me that you forgot to specify the function arguments, eg:

Code: Select all

Call("Scripts::Main", 1, "EvalCmd.js", `if (AkelPad.Include("TextReplace_function.js")) TextReplace("a", "b", "g");`)
спасибо, надо запомнить решение...

но я давно пользуюсь другим решением... по моему заказу на другом форуме был сделан скрипт ScriptTemplate.vbs... в нем я создаю любое количество "Case" с любой комбинацией текстовых замен, хоть простые замены, хоть с помощью регулярок... в одном "Case" может быть хоть одна подобная вашей команда, хоть сотни... вызывается любой "Case" просто

Code: Select all

Call("Scripts::Main", 1, "ScriptTemplate.vbs", `"2"`)
мой этот файл весит 40 мегов с огромным количеством шаблонов замен... уже решил дублировать файлы данного скрипта чтобы они не были столь большими...

ваш вариант запуска комбинации замены из меню лично для меня может быть полезен, но пока не могу понять для чего, но запомню...

я же предлагаю другой вариант, которым я пользуюсь...

правда, то, что я предложил, касается вызова команд замен из меню, а не использования в других скриптах...

Posted: Tue Mar 01, 2016 8:28 pm
by VladSh
InFive wrote:мой этот файл весит 40 мегов с огромным количеством шаблонов замен...
Зачем 40 "мегов"??? Ну пусть даже 100 шаблонов = 100 килобайт, но не 40 метров же...
InFive wrote:уже решил дублировать файлы данного скрипта чтобы они не были столь большими...
Зачем дублировать файлы скрипта? Чтобы ещё больше объём был?

Но замена по указанному сохранённому шаблону без поднятия GUI конечно же очень удобна.

Posted: Tue Mar 01, 2016 9:08 pm
by InFive
VladSh wrote:Зачем 40 "мегов"??? Ну пусть даже 100 шаблонов = 100 килобайт, но не 40 метров же....
к сожалению, столько много я делаю замен в текстах, поэтому много готовых шаблонов у меня...
VladSh wrote:Зачем дублировать файлы скрипта?
чем меньше файл скрипта с шаблонами тем быстрее запускается выполнение команды и меньше ест оперативку... под словом дублировать я имел ввиду что новые шаблоны свои прописывать в новую копию данного скрипта, и не доводить каждую копию до бльших размеров, лучше создавать новую копию... и каждая новая копия скрипта запускается независимо от другой копии, это просто будут самостоятельные скрипты...

немного касательно ">>" - мне думается, что зря поднял я этот вопрос... это частный случай, и никому это не понадобится... просто мне казалось что такое должно пределяться как ошибка... ну раз не определяется, так, мне думается, и не надо столь много усилий прилагать... есть много других полезных для всех у вас задач... а такую мелочь мне не так уж и сложно отдельно решить, благо в AkelPad всё под рукой...

я просто не помню случаи когда ">>" были ошибкой, может ">>" были в комбинации с такими символами, с которыми такое недопустимо, ибо я раньше проверял xml в программе XML Copy Editor... ваши примеры попробовал проверить в XML Copy Editor - так он не посчитал это ошибкой...

еще раз приношу извинения, просто я считал что ">>" - это ошибка... но если подойти логически, то лучше такое из текста убирать, особенно когда я компилирую много текстовых модулей под Андроид, он вообще копризен в правильности xml и чуть что сразу плюётся...

но это если подойти логически, а так, может быть оно и не стоит ваших усилий!? другие как думают?

Posted: Tue Mar 01, 2016 11:03 pm
by VladSh
InFive wrote:чем меньше файл скрипта с шаблонами тем быстрее запускается выполнение команды и меньше ест оперативку... под словом дублировать я имел ввиду что новые шаблоны свои прописывать в новую копию данного скрипта, и не доводить каждую копию до бльших размеров, лучше создавать новую копию... и каждая новая копия скрипта запускается независимо от другой копии, это просто будут самостоятельные скрипты...
Вы извините, но, по моему, это какое-то извращение...
По нормальному настройки и данные должны быть отделены от программного кода. Т.е. шаблоны не должны быть в скрипте, а желательно или в отдельных файлах или в одном отдельном файле. Для этого достаточно обычного ini-файла:
<название шаблона> = параметры
Тогда пользователю вообще ненужно видеть скрипт.
InFive wrote:касательно ">>"
Почти всё уже готово. Осталось правильную регулярку запилить.
Большая часть времени у меня ушла как раз не на это, а на восстановление возможности проверки выделения с правильным выводом сообщений об ошибках в консоль (получение номера строки и номера позиции места ошибки в строке).
Так что не стоит переживать, это всё равно нужно было сделать.

Posted: Wed Mar 02, 2016 10:09 pm
by VladSh
Интересный момент обнаружился.

Строка

Code: Select all

var line = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, filepos);
возвращает номер не абзаца, а строки. Это ведёт к тому, что при коротких строках их номера вычисляются корректно, и переход в панели лога происходит правильно, а если же абзац занимает 2 и более строки, то переход осуществляется в неверное место.

Может кто знает, как в Акеле по номеру позиции в файле получить не номер "линии", а соответствующего абзаца?

Posted: Wed Mar 02, 2016 10:58 pm
by FeyFre
AEM_GETLINENUMBER + AEGI_UNWRAPLINEFROMRICHOFFSET ???

Posted: Wed Mar 02, 2016 11:11 pm
by VladSh
У Infocatcher'а в openFileIn.js выкопал :) :

Code: Select all

function getLine() {
	var hWndEdit = AkelPad.GetEditWnd();
	var wrpLine = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, AkelPad.GetSelStart());
	var unwrpLine = AkelPad.SendMessage(hWndEdit, 3143 /*AEM_GETUNWRAPLINE*/, wrpLine, 0);
	return unwrpLine + 1;
}
8)

Posted: Thu Mar 03, 2016 8:55 pm
by KDJ
TextReplace_function.js
Added: ability to use predefined variables _s0, _s1, ..., _n0, _n1 in ReplaceWith function passed as string.
Fixed: bug in count of changes.