Лайфхаки BAS


  • administrators

    Но лайфхак всё же добавлю в общую копилку.

    Что бы открыть в браузере у пользователя нужный url можно воспользоваться этим методом.

    1. Создаём шаблон вида:
    [InternetShortcut]
    IDList=
    URL=http://www.yandex.ru/
    

    где - http://www.yandex.ru/ - это адрес, который будет открываться при запуске этого файла.

    1. Сохраняем этот файл под любым именем с расширением .url
    2. Запускаем его через Запустить Процесс
      0_1525192828394_на форум 31.png

    Вот тестовый скрипт



  • Спрашивал про кнопку "Выход" в новом интерфейсе у @support`а дал вот такой способ

    CloseApplication() - закрывает БАС из интерфейса
    


  • Цветной лог в новом интерфейсе

    $("#Logs").prepend("<div><span style='color:blue'>Текст</span></div>");
    $("#Logs").prepend("<div><span style='color:blue'>Тест [[NEW_VARIABLE]]</span></div>");
    

    0_1529321257202_Screenshot_3.png



  • запущенная локализация проекта

    VAR_LANG = _K
    


  • Спасибо @support`y выручает всегда когда нужно
    Объяснил и показал как выводит результаты в новом интерфейсе без скачивания
    Я сделал чтоб выводил в спойлер вот html/css/js
    Результаты.txt
    0_1529606682647_1.gif



  • У многих начинающих пользователей возникают трудности с json. А именно с тем, чтобы правильно построить путь к нужному значению. В этом может помочь очень удобный плагин для Notepad++ JSONViewer Да и продвинутым пользователям он поможет сильно с экономить время!0_1530128716932_2018-06-28_015846.png


  • administrators

    Добавлю немного описания, чем же удобен этот плагин для работы с json. В нём можно выбрать нужный элемент, и внизу появится готовый код, который можно вставить в JSON.parse()
    0_1530136182548_2.png



  • This post is deleted!


  • Добавлена информация о TSV файлах (пункт 9).


  • administrators

    Долго думал в какой ветке выложить этот пост, решил, что ему в Лайфхаках будет самое место. Опишу весь процесс, возможно кому нибудь пригодится промежуточный этап.


    Обратились тут ко мне в личку с нестандартным вопросом, можно ли менять количество потоков в зависимости от условий значений ресурсов. (без "вызова функции в несколько потоков")

    {{test_res}} == "хочу два потока" //запускается 2 потока
    или
    {{test_res}} == "хочу пять потоков" //запускается 5 потоков
    

    Я ответил, что так делать нельзя, но это не совсем так :D


    Чтобы запустить скрипт с количеством потоков равном количеству ресурсов, надо в графе "количество потоков" прописать

    RMap("name").length()
    

    где name это имя ресурса.
    Если ресурс "из файла" то количество потоков будет равно количеству строк в файле, если ресурс "из папки" то количеству файлов в папке и тому подобное.


    После получаса извращенных экспериментов с BAS'ом (да простит меня @support)

    10-5 //сработал
    (2+2)*2 //сработал выдал 8 потоков
    a=10;b=5;a-b //не сработал
    2+2; //не сработал
    2+2*2 //сработал, выдал 6 потоков.. может через евал?
    eval(2+2) //сработал! опа! 
    eval(if(10-5 > 1) {2}) //не сработал
    eval(if(10-5 > 0) {10-8}) //тоже не сработал :(
    eval(a=10;b=5;a-b) //не сработал
    eval("a=10;b=5;a-b") //!! сработало !! :D
    eval("if(10-5 > 1) {2}") //Лол! Сработало :)
    eval("(10-5 > 10) ? 2 : 5") //тоже сработало! Прикольно :)) Вот тебе и иф :))
    eval("{{test}} == 'test' ? 2:5") //не сработало :(
    eval({{test}} + "== 'test' ? 2:5") //тоже не сработало :(
    eval('(10-5 > 10) ? 2 : 5') //сработало..
    

    Пришёл к выводу, что надо применять тот же способ работы с ресурсом, что и в коде проекта

    RS("test", false, false)!
    RESOURCE_1 = _result().get()
    log(RESOURCE_1)
    

    В самом начале скрипта прописал получение значения из ресурса и всё заработало:

    RS("test", false, false)!
    RESOURCE_2 = _result().get()
    section(eval("RESOURCE_2 == 'test' ? 2:5") /*eval("RESOURCE_2 == 'test' ? 2:5")*/,1 /*1*/,1 /*1*/,0,function(){
    

    0_1537265715472_1ff864f2-8db6-48c5-b35b-150379c648a2-изображение.png
    0_1537265939090_на форум34.gif
    Вот тестовый скрипт


    Пока печатал пост подумал, что можно через RMap решить эту задачу без правки руками кода проекта.

    Количество потоков:

    eval("RMap('toster').at(0) == 'tost' ? 2:5")
    

    0_1537266871662_на форум35.gif
    Вот скрипт без ручной правки кода.


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


  • administrators

    Как подсказал @Denis_krsk можно и без eval() :D

    RMap('toster').at(0) == 'tost' ? 2 : 5
    


  • Возможно совсем для новичков, но все же. Для уменьшения количества итоговых действий в скрипте ( когда все отлажено ), можно пойти таким путем.
    Кликаем для редактирования простого действия(работа с xpath,регулярками,рэндомом,датой и тд) и копируем его id
    0_1538592756687_Screenshot_1.png
    далее переходим сюда
    0_1538591780990_Screenshot_3.png
    нажимаем ctrl+f и вставляем наш id (команда для вставки ctrl+v)
    Видим такой текст
    0_1538592910174_Screenshot_2.png
    нас интересует только все что после section_start и зелёных надписей до section_end
    вставляем этот текст в
    0_1538592021865_Screenshot_6.png
    и таким же образом поступаем с остальными не сложными действиями. Соответсвенно добавляя ВСЕ эти действия в один код.
    Итог : количество (элементарных) действий уменьшилось, читаемость повысилась


  • administrators

    Не скажу, кто именно, но кто то на форуме спросил :D
    0_1540930262180_c213a8fd-bcff-46ae-aa49-01bc2ab81433-изображение.png

    И я начал смотреть разные gui, для себя нашёл очень интересную nwjs, но о ней в следующий раз. А потом вспомнил, что есть более простые решения этой задачи на VBScript.

    Код VBS скрипта :

    result = MsgBox ("Fox is a great forum admin?", vbYesNo, "Yes or No?")
    
    Select Case result
    Case vbYes
        WScript.Echo("yes")
    Case vbNo
        WScript.Echo("no")
    End Select
    

    и код действия "Запустить Процесс":

    @echo off
    @ cscript //Nologo Fox.vbs
    

    0_1540930769732_на форум 7.gif


    0_1540930782118_на форум 8.gif

    Вот тестовый скрипт для наглядности.



  • Расширенный spintax.

    Кроме стандартного БАСовского перебора {1|2|3} может менять текст местами, поддерживает любую вложеность.
    Вставить в экшн "Выполнить код"

    /*Спинтакс 
    {текст 1|текст 2|текст 3} - перебор вариантов
    [текст 1|текст 2|текст 3] - перестановки
    [+разделитель+текст 1|текст 2|текст 3] - перестановки с разделителем
    \{ \} \| [ ] \+ \\ - экранизация спецсимволов
    Поддерживается вложенность команд
    */
    function TextRandomizator_Node($parent) {
    	$parent = (typeof $parent !== 'undefined') ? $parent : null;
    	var $this = this;
    	//$this.$_parent = null;
    	$this.$_str = '';
    	$this.$_type = 'mixing';
    	$this.$_subNodes = [];
    	$this.$_usedKeys_s = [];
    	$this.$_usedKeys_m = [];
    	$this.var_num_m = 0;
    	$this.$pset_arr = [];
    	$this.$_separator = '';
    	$this.$_isSeparator = false;
    	$this.$_parent = $parent;
    	if($parent) {
    		$this.$_parent.$_subNodes.push($this);
    	}
    	function shuffle($arr) {
    		function compareRandom(a, b) {
    			return Math.random() - 0.5;
    		}
    		return $arr.sort(compareRandom);
    	}
    	function sort_arr_arr($arr, $key_arr) {
    		var output = [];
    		for(var $i=0; $i<$key_arr.length; $i++) {
    			output.push($arr[$key_arr[$i]]);
    		}
    		return output;
    	}
    	function array_keys(myObject) {
    		var output = [];
    		for(var key in myObject) {
    			output.push(key);
    		}
    		return output;
    	}
    	function swap($i, $j, $arr) {
    		if($i != $j) {
    			var $temp = $arr[$i];
    			$arr[$i] = $arr[$j];
    			$arr[$j] = $temp;
    		}
    		return $arr;
    	}
    	function reverse_arr($k, $arr) {
    		var $i = 0;
    		var $j = $k;
    		while($i < $j) {
    			$arr = swap($i, $j, $arr);
    			$i++;
    			$j--;
    		}
    		return $arr;
    	}
    
    	function gen_mset($arr, $k) {	
    		if ($k == 0) {
    			$this.$pset_arr.push($arr.slice());
    		} else {
    			for(var $i = 0; $i <= $k; $i++) {
    				gen_pvar($k-1, $arr);
    				if($i < $k) {
    					$arr = swap($i, $k, $arr);
    					$arr = reverse_arr($k - 1, $arr);
    				}
    			}
    		}
    	}
    
    	function next_mset($arr, $n) {
    		var $j = $n - 2;
    		while($j != -1 && $arr[$j] >= $arr[$j + 1]) $j--;
    		if ($j == -1)
    			return false;
    		var $k = $n - 1;
    		while ($arr[$j] >= $arr[$k]) $k--;
    		$arr = swap($j, $k, $arr);
    		var $l = $j + 1, $r = $n - 1;
    		while ($l<$r)
    			$arr = swap($l++, $r--, $arr);
    		return $arr;
    	}
    	
        $this.get_text = function($rand) {
    		$rand = (typeof $rand !== 'undefined') ? $rand : false;
            var $result = '';
            switch ($this.$_type) {
                case 'synonyms':
    				if ($this.$_usedKeys_s.length == 0) {
                        $this.$_usedKeys_s = array_keys($this.$_subNodes);
    				}
    				if($rand == true) {
    					var $random_key = Math.floor(Math.random() * ($this.$_usedKeys_s.length));
    					var $key = $this.$_usedKeys_s[$random_key];
    					$result = $this.$_subNodes[$key].get_text($rand);
    					$this.$_usedKeys_s.splice($random_key, 1);				
    				} else {
    					var $key_s = $this.$_usedKeys_s[0];
    					$result = $this.$_subNodes[$key_s].get_text($rand);
    					$this.$_usedKeys_s.splice(0, 1);
    				}
    				break;
                case 'mixing':
    				var $_subNodes_m = $this.$_subNodes;
    				if($this.$_usedKeys_m.length == 0 && $this.$_subNodes.length > 1) {
    					if($rand == true) {
    						$this.$_subNodes = shuffle($this.$_subNodes);
    					}
    					$_subNodes_m = $this.$_subNodes;
    					$this.$_usedKeys_m = array_keys($this.$_subNodes);
    				}
    				if($this.$_usedKeys_m.length > 1) {
    					$this.$_usedKeys_m = next_mset($this.$_usedKeys_m, $this.$_usedKeys_m.length);
    					if($this.$_usedKeys_m == false) {
    						$this.$_usedKeys_m = array_keys($this.$_subNodes);
    					}
    					$_subNodes_m = sort_arr_arr($this.$_subNodes, $this.$_usedKeys_m);
    				}
                    $_subNodes_m.forEach(function($item, $i, $arr) {
                        if($result) {
                            $result += '' + $this.$_separator;
                        }
                        $result += '' + $item.get_text($rand);
                    });
                    break;
                case 'series':
                    $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result += '' + $item.get_text($rand);
                    });
                    break;
                default:
                    $result = $this.$_str;
    		}
    		//$result = $result.trim();
            $result = $result.replace(new RegExp('\\s+', 'g'), ' ');
            $result = $result.replace(' ,', ',');
            $result = $result.replace(' .', '.');
            $result = $result.replace(' !', '!');
            $result = $result.replace(' ?', '?');
            return $result;
        }
    
        $this.num_variant = function() {
            var $result = 1;
            switch ($this.$_type) {
                case 'synonyms':
                    $result = 0;
                    $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result += $item.num_variant();
                    });
                    break;
                case 'mixing':
                    for (var $i=2, $kol=$this.$_subNodes.length; $i<=$kol; ++$i) {
                        $result *= $i;
                    }
                    $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result *= $item.num_variant();
                    });
                    break;
                case 'series':
                   $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result *= $item.num_variant();
                    });
                    break;
            }
            return $result;
        }
    
        $this.concat = function($str) {
            $str = String($str);
            if ($this.$_isSeparator) {
                $this.$_separator += $str;
                return $this;
            }
            if ('string' == $this.$_type) {
                $this.$_str += $str;
                return $this;
            }
            $currentNode = new TextRandomizator_Node($this);
            $currentNode.set_type('string');
            return $currentNode.concat($str);
        }
    
        $this.set_type = function ($type) {
            switch (String($type)) {
                case 'string':
                    $this.$_type = 'string';
                    break;
                case 'synonyms':
                    $this.$_type = 'synonyms';
                    break;
                case 'series':
                    $this.$_type = 'series';
                    break;
                default:
                    $this.$_type = 'mixing';
            }
        }
    
        $this.get = function($var) {
            $var = $var.toLowerCase();
            switch (String($var)) {
                case 'isseparator':
                    return $this.$_isSeparator;
                    break;
                case 'parent':
                    return $this.$_parent;
                    break;
                case 'type':
                    return $this.$_type;
                    break;
                default:
                    return null;
            }
        }
    
        $this.set = function($var, $value) {
            $var = $var.toLowerCase();
            switch (String($var)) {
                case 'isseparator':
                    $this.$_isSeparator = $value;
            }
        }
    }
    
    function TextRandomizator($text) {
    	$text = (typeof $text !== 'undefined') ? $text : '';
    	var $text = String($text);
    	var $match = [];
    	var $this = this;
    	$this.$_tree = null;
    	$this.$_text = $text;
    	$this.$_tree = new TextRandomizator_Node();
    	var regexp_str ='\\\\\\\\|\\\\\[|\\\\\]|\\\\\\{|\\\\\\}|\\\\\\+|\\\\\\||\[\\+|\\+|\\{|\\}|\[|\]|\\||[^\\\\\\+\\{\\}[\]\\|]+';
    	var $regexp = new RegExp(regexp_str, '');
            $currentNode = $this.$_tree;
            $currentNode = new TextRandomizator_Node($currentNode);
            $currentNode.set_type('series');
            $currentNode = $currentNode.concat('');
    		//while(($match = /\\\\|\\[|\\]|\\\{|\\\}|\\\+|\\\||[\+|\+|\{|\}|[|]|\||[^\\\+\{\}[]\|]+/.exec($text)) != null) {
    		while(($match =  $regexp.exec($text)) != null) {
    			switch ($match[0]) {
    				case '\\\\':
    				case '\\':
    					$currentNode = $currentNode.concat('\\');
    					break;
    				case '\\+':
    					$currentNode = $currentNode.concat('+');
    					break;
    				case '\\{':
    					$currentNode = $currentNode.concat('{');
    					break;
    				case '\\}':
    					$currentNode = $currentNode.concat('}');
    					break;
    				case '\[':
    					$currentNode = $currentNode.concat('[');
    					break;
    				case '\]':
    					$currentNode = $currentNode.concat(']');
    					break;
    				case '\\|':
    					$currentNode = $currentNode.concat('|');
    					break;
    				case '[+':
    					if('string' == $currentNode.get('type')) {
    						$currentNode = new TextRandomizator_Node($currentNode.get('parent'));
    					} else {
    						$currentNode = new TextRandomizator_Node($currentNode);
    					}
    					$currentNode.set('isSeparator', true);
    					break;
    				case '+':
    					if ($currentNode.get('isSeparator') == true) {
    						$currentNode.set('isSeparator', false);
    						$currentNode = new TextRandomizator_Node($currentNode);
    						$currentNode.set_type('series');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat('+');
    					}
    					break;
    				case '{':
    					if ('string' == $currentNode.get('type')) {
    						$currentNode = new TextRandomizator_Node($currentNode.get('parent'));
    					} else {
    						$currentNode = new TextRandomizator_Node($currentNode);
    					}
    					$currentNode.set_type('synonyms');
    					$currentNode = new TextRandomizator_Node($currentNode);
    					$currentNode.set_type('series');
    					$currentNode = $currentNode.concat('');
    					break;
    				case '}':
    					var $is = $currentNode.get('parent').get('parent');
    					if ($is && 'synonyms' == $is.get('type')) {
    						$currentNode = $is.get('parent');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat('}');
    					}
    					break;
    				case '[':
    					if ('string' == $currentNode.get('type')) {
    						$currentNode = new TextRandomizator_Node($currentNode.get('parent'));
    					} else {
    						$currentNode = new TextRandomizator_Node($currentNode);
    					}
    					$currentNode = new TextRandomizator_Node($currentNode);
    					$currentNode.set_type('series');
    					$currentNode = $currentNode.concat('');
    					break;
    				case ']':
    					var $is = $currentNode.get('parent').get('parent');
    					if ($is && 'mixing' == $is.get('type') && $is.get('parent')) {
    						$currentNode = $is.get('parent');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat(']');
    					}
    					break;
    				case '|':
    					var $is = $currentNode.get('parent');
    					if ($is && 'series' == $is.get('type')) {
    						$currentNode = $is.get('parent');
    						$currentNode = new TextRandomizator_Node($currentNode);
    						$currentNode.set_type('series');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat('|');
    					}
    					break;
    				default:
    					$currentNode = $currentNode.concat($match[0]);
    			}
    			$text = $text.substr($match[0].length);
    		}
    		
    	$this.get_text = function($rand) {
    		return $this.$_tree.get_text($rand);
    	}
    
    	$this.num_variant = function() {
    		return $this.$_tree.num_variant();
    	}
    }
    
    var text_data = [[SPINTAX_TEXT]];   // Ваш текст
    var rm_text = new TextRandomizator(text_data);
    var rm_text_random = true;
    VAR_SPINTAX_TEXT = (rm_text.get_text(rm_text_random));
    

    За наводку спасибо @Fox


  • administrators

    @bms-java said in Лайфхаки BAS:

    Расширенный spintax.

    Кроме стандартного БАСовского перебора {1|2|3} может менять текст местами, поддерживает любую вложеность.
    Вставить в экшн "Выполнить код"

    Твой код не работает, а искать почему, мне лень :D.
    Скопировал библиотеку по новой (библиотека взята с сайта http://xbb.uz/randomizator/) и немного подправил код, чтобы не поймать баг в объявлении именованой функции.


    /* Библиотека для обработки текста рандомизатором http://gsgen.ru/ */
    /* Поддерживаемые шаблоны и директивы */
    /*
    {текст 1|текст 2|текст 3} - перебор вариантов
    [текст 1|текст 2|текст 3] - перестановки
    [+разделитель+текст 1|текст 2|текст 3] - перестановки с разделителем
    \{ \} \| [ ] \+ \\ - экранизация спецсимволов
    */
    TextRandomizator_Node = function($parent) {
    	$parent = (typeof $parent !== 'undefined') ? $parent : null;
    	var $this = this;
    	//$this.$_parent = null;
    	$this.$_str = '';
    	$this.$_type = 'mixing';
    	$this.$_subNodes = [];
    	$this.$_usedKeys_s = [];
    	$this.$_usedKeys_m = [];
    	$this.var_num_m = 0;
    	$this.$pset_arr = [];
    	$this.$_separator = '';
    	$this.$_isSeparator = false;
    	$this.$_parent = $parent;
    	if($parent) {
    		$this.$_parent.$_subNodes.push($this);
    	}
    // Перемешать элементы массива в случайном порядке
    	function shuffle($arr) {
    		function compareRandom(a, b) {
    			return Math.random() - 0.5;
    		}
    		return $arr.sort(compareRandom);
    	}
    // Сортировка элементов массива по заданному массиву ключей
    	function sort_arr_arr($arr, $key_arr) {
    		var output = [];
    		for(var $i=0; $i<$key_arr.length; $i++) {
    			output.push($arr[$key_arr[$i]]);
    		}
    		return output;
    	}
    // Получение списка ключей массива	
    	function array_keys(myObject) {
    		var output = [];
    		for(var key in myObject) {
    			output.push(key);
    		}
    		return output;
    	}
    // Поменять местами элементы массива
    	function swap($i, $j, $arr) {
    		if($i != $j) {
    			var $temp = $arr[$i];
    			$arr[$i] = $arr[$j];
    			$arr[$j] = $temp;
    		}
    		return $arr;
    	}
    // Расстановка элементов в обратном порядке от заданной позиции
    	function reverse_arr($k, $arr) {
    		var $i = 0;
    		var $j = $k;
    		while($i < $j) {
    			$arr = swap($i, $j, $arr);
    			$i++;
    			$j--;
    		}
    		return $arr;
    	}
    // Генерация массива с перестановками
    	function gen_mset($arr, $k) {	
    		if ($k == 0) {
    			$this.$pset_arr.push($arr.slice());
    		} else {
    			for(var $i = 0; $i <= $k; $i++) {
    				gen_pvar($k-1, $arr);
    				if($i < $k) {
    					$arr = swap($i, $k, $arr);
    					$arr = reverse_arr($k - 1, $arr);
    				}
    			}
    		}
    	}
    // Генерация следующей перестановки
    	function next_mset($arr, $n) {
    		var $j = $n - 2;
    		while($j != -1 && $arr[$j] >= $arr[$j + 1]) $j--;
    		if ($j == -1)
    			return false; // больше перестановок нет
    		var $k = $n - 1;
    		while ($arr[$j] >= $arr[$k]) $k--;
    		$arr = swap($j, $k, $arr);
    		var $l = $j + 1, $r = $n - 1; // сортируем оставшуюся часть последовательности
    		while ($l<$r)
    			$arr = swap($l++, $r--, $arr);
    		return $arr;
    	}
    	
        $this.get_text = function($rand) {
    		$rand = (typeof $rand !== 'undefined') ? $rand : false;
            var $result = '';
            switch ($this.$_type) {
                case 'synonyms':
    				if ($this.$_usedKeys_s.length == 0) {
                        $this.$_usedKeys_s = array_keys($this.$_subNodes);
    				}
    				if($rand == true) {
    					var $random_key = Math.floor(Math.random() * ($this.$_usedKeys_s.length));
    					var $key = $this.$_usedKeys_s[$random_key];
    					$result = $this.$_subNodes[$key].get_text($rand);
    					$this.$_usedKeys_s.splice($random_key, 1);				
    				} else {
    					var $key_s = $this.$_usedKeys_s[0];
    					$result = $this.$_subNodes[$key_s].get_text($rand);
    					$this.$_usedKeys_s.splice(0, 1);
    				}
    				break;
                case 'mixing':
    				var $_subNodes_m = $this.$_subNodes;
    				if($this.$_usedKeys_m.length == 0 && $this.$_subNodes.length > 1) {
    					if($rand == true) {
    						$this.$_subNodes = shuffle($this.$_subNodes);
    					}
    					$_subNodes_m = $this.$_subNodes;
    					$this.$_usedKeys_m = array_keys($this.$_subNodes);
    				}
    				if($this.$_usedKeys_m.length > 1) {
    					$this.$_usedKeys_m = next_mset($this.$_usedKeys_m, $this.$_usedKeys_m.length);
    					if($this.$_usedKeys_m == false) {
    						$this.$_usedKeys_m = array_keys($this.$_subNodes);
    					}
    					$_subNodes_m = sort_arr_arr($this.$_subNodes, $this.$_usedKeys_m);
    				}
                    $_subNodes_m.forEach(function($item, $i, $arr) {
                        if($result) {
                            $result += '' + $this.$_separator;
                        }
                        $result += '' + $item.get_text($rand);
                    });
                    break;
                case 'series':
                    $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result += '' + $item.get_text($rand);
                    });
                    break;
                default:
                    $result = $this.$_str;
    		}
    		//$result = $result.trim();
            $result = $result.replace(new RegExp('\\s+', 'g'), ' ');
            $result = $result.replace(' ,', ',');
            $result = $result.replace(' .', '.');
            $result = $result.replace(' !', '!');
            $result = $result.replace(' ?', '?');
            return $result;
        }
    
        $this.num_variant = function() {
            var $result = 1;
            switch ($this.$_type) {
                case 'synonyms':
                    $result = 0;
                    $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result += $item.num_variant();
                    });
                    break;
                case 'mixing':
                    for (var $i=2, $kol=$this.$_subNodes.length; $i<=$kol; ++$i) {
                        $result *= $i;
                    }
                    $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result *= $item.num_variant();
                    });
                    break;
                case 'series':
                   $this.$_subNodes.forEach(function($item, $i, $arr) {
                        $result *= $item.num_variant();
                    });
                    break;
            }
            return $result;
        }
    
        $this.concat = function($str) {
            $str = String($str);
            if ($this.$_isSeparator) {
                $this.$_separator += $str;
                return $this;
            }
            if ('string' == $this.$_type) {
                $this.$_str += $str;
                return $this;
            }
            $currentNode = new TextRandomizator_Node($this);
            $currentNode.set_type('string');
            return $currentNode.concat($str);
        }
    
        $this.set_type = function ($type) {
            switch (String($type)) {
                case 'string':
                    $this.$_type = 'string';
                    break;
                case 'synonyms':
                    $this.$_type = 'synonyms';
                    break;
                case 'series':
                    $this.$_type = 'series';
                    break;
                default:
                    $this.$_type = 'mixing';
            }
        }
    
        $this.get = function($var) {
            $var = $var.toLowerCase();
            switch (String($var)) {
                case 'isseparator':
                    return $this.$_isSeparator;
                    break;
                case 'parent':
                    return $this.$_parent;
                    break;
                case 'type':
                    return $this.$_type;
                    break;
                default:
                    return null;
            }
        }
    
        $this.set = function($var, $value) {
            $var = $var.toLowerCase();
            switch (String($var)) {
                case 'isseparator':
                    $this.$_isSeparator = $value;
            }
        }
    }
    
    TextRandomizator = function($text) {
    	$text = (typeof $text !== 'undefined') ? $text : '';
    	var $text = String($text);
    	var $match = [];
    	var $this = this;
    	$this.$_tree = null;
    	$this.$_text = $text;
    	$this.$_tree = new TextRandomizator_Node();
    	var regexp_str ='\\\\\\\\|\\\\\[|\\\\\]|\\\\\\{|\\\\\\}|\\\\\\+|\\\\\\||\[\\+|\\+|\\{|\\}|\[|\]|\\||[^\\\\\\+\\{\\}[\]\\|]+';
    	var $regexp = new RegExp(regexp_str, '');
            $currentNode = $this.$_tree;
            $currentNode = new TextRandomizator_Node($currentNode);
            $currentNode.set_type('series');
            $currentNode = $currentNode.concat('');
    		//while(($match = /\\\\|\\[|\\]|\\\{|\\\}|\\\+|\\\||[\+|\+|\{|\}|[|]|\||[^\\\+\{\}[]\|]+/.exec($text)) != null) {
    		while(($match =  $regexp.exec($text)) != null) {
    			switch ($match[0]) {
    				case '\\\\':
    				case '\\':
    					$currentNode = $currentNode.concat('\\');
    					break;
    				case '\\+':
    					$currentNode = $currentNode.concat('+');
    					break;
    				case '\\{':
    					$currentNode = $currentNode.concat('{');
    					break;
    				case '\\}':
    					$currentNode = $currentNode.concat('}');
    					break;
    				case '\[':
    					$currentNode = $currentNode.concat('[');
    					break;
    				case '\]':
    					$currentNode = $currentNode.concat(']');
    					break;
    				case '\\|':
    					$currentNode = $currentNode.concat('|');
    					break;
    				case '[+':
    					if('string' == $currentNode.get('type')) {
    						$currentNode = new TextRandomizator_Node($currentNode.get('parent'));
    					} else {
    						$currentNode = new TextRandomizator_Node($currentNode);
    					}
    					$currentNode.set('isSeparator', true);
    					break;
    				case '+':
    					if ($currentNode.get('isSeparator') == true) {
    						$currentNode.set('isSeparator', false);
    						$currentNode = new TextRandomizator_Node($currentNode);
    						$currentNode.set_type('series');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat('+');
    					}
    					break;
    				case '{':
    					if ('string' == $currentNode.get('type')) {
    						$currentNode = new TextRandomizator_Node($currentNode.get('parent'));
    					} else {
    						$currentNode = new TextRandomizator_Node($currentNode);
    					}
    					$currentNode.set_type('synonyms');
    					$currentNode = new TextRandomizator_Node($currentNode);
    					$currentNode.set_type('series');
    					$currentNode = $currentNode.concat('');
    					break;
    				case '}':
    					var $is = $currentNode.get('parent').get('parent');
    					if ($is && 'synonyms' == $is.get('type')) {
    						$currentNode = $is.get('parent');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat('}');
    					}
    					break;
    				case '[':
    					if ('string' == $currentNode.get('type')) {
    						$currentNode = new TextRandomizator_Node($currentNode.get('parent'));
    					} else {
    						$currentNode = new TextRandomizator_Node($currentNode);
    					}
    					$currentNode = new TextRandomizator_Node($currentNode);
    					$currentNode.set_type('series');
    					$currentNode = $currentNode.concat('');
    					break;
    				case ']':
    					var $is = $currentNode.get('parent').get('parent');
    					if ($is && 'mixing' == $is.get('type') && $is.get('parent')) {
    						$currentNode = $is.get('parent');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat(']');
    					}
    					break;
    				case '|':
    					var $is = $currentNode.get('parent');
    					if ($is && 'series' == $is.get('type')) {
    						$currentNode = $is.get('parent');
    						$currentNode = new TextRandomizator_Node($currentNode);
    						$currentNode.set_type('series');
    						$currentNode = $currentNode.concat('');
    					} else {
    						$currentNode = $currentNode.concat('|');
    					}
    					break;
    				default:
    					$currentNode = $currentNode.concat($match[0]);
    			}
    			$text = $text.substr($match[0].length);
    		}
    		
    	$this.get_text = function($rand) {
    		return $this.$_tree.get_text($rand);
    	}
    
    	$this.num_variant = function() {
    		return $this.$_tree.num_variant();
    	}
    }
    
    var rm_text = new TextRandomizator([[TEXT]])
    var rm_text_random = true
    [[SPINTAX_TEXT]] = rm_text.get_text(rm_text_random)
    

    Вот тестовый скрипт для наглядности.


  • administrators

    Давненько сюда ни кто ни чего новевнького не скидывал. Не помню, кто на форуме спрашивал, можно ли видоизменить лог, чтобы убрать вывод id действия например:
    0_1547309292653_6b06f535-97ea-4463-80d6-9e0244581ec7-изображение.png
    Для этого нужно переопределить функцию log, к сожалению сама функция лога находится в C++ коде и немного изменить её не получится, но можно воспользоваться функцией log_html()


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


    Лог без id действия 0_1547310031022_50372e75-1923-450a-a269-227f6d8cabd7-изображение.png

    //здесь могла быть ваша реклама :D
    function log(text) {
        var tm = new Date();
        var h = tm.getHours();
        var m = tm.getMinutes();
        var s = tm.getSeconds();
        if (h < 10) h = "0" + h;
        if (m < 10) m = "0" + m;
        if (s < 10) s = "0" + s;
        var time_ = "[" + h + ":" + m + ":" + s + "]"
        Logger.WriteHtml("<span style='color:#FFFFFF'>" + time_ + " Поток№ " + thread_number() + ": " + text + "</span>", time_ + " Поток№ " + thread_number() + ": " + text);
    }
    

    Лог без времени 0_1547310211630_d5a16a74-acee-4cf4-8f11-3d52707d4832-изображение.png

    //здесь могла быть ваша реклама :)
    function log(text) {
        Logger.WriteHtml("<span style='color:#FFFFFF'>Поток №" + thread_number() + " : " + text + "</span>", "Поток №" + thread_number() + " : " + text);
    }
    

    Лог без номера потока 0_1547310328436_1ab2e055-5aae-44e7-9911-757bac1ea752-изображение.png

    //здесь могла быть ваша реклама :)
    function log(text) {
        Logger.WriteHtml("<span style='color:#FFFFFF'>" + text + "</span>", text);
    }
    

    Лог без текста 0_1547310407603_3f7fe19a-d487-4297-b2ad-02a34d7f3733-изображение.png
    На случай если нужно программно отключить вывод сообщений в лог.

    //здесь могла быть ваша реклама :)
    function log(text) {}
    

    Вот тестовый скрипт для примера.



  • Для читабельности созданной в BAS конструкции разработчик рекомендует использовать функции. И отделять таким образом логические разделы скрипта.
    Однако у этого метода есть свои недостатки (пусть кому-то они и покажутся мелочными):

    1. Если следовать рекомендациям разраба, многие функции будут использованы лишь один раз, что противоречит общей идеологии функций в программировании. Они просто будут захламлять список функций и усложнят поиск тех, которые используются в скрипте по нескольку раз.
    2. При копировании функций из одного скрипта в другой, необходимо предварительно объявить функцию. А лучше - объявить, вызвать и скопировать все действия. Встречал ошибки при несоблюдении подобной последовательности (возможно из-за кривизны рук).

    Для решения задачи из п.2 применил простой и доступный всем метод:
    Разделение логических разделов скрипта через условный оператор IF и единичку в условиии с описанием раздела. Увидев скриншот сразу станет понятнее:
    0_1547448550531_d7eefa61-6657-4f0f-a244-3005b4cbdac4-image.png
    После добавления функционала сворачивания вложенных конструкций стало совсем удобно. При необходимости каждый раздел разворачивается и нужные данные редактируются. Для пущей красоты можно раскрасить "разделы".
    С таким разделением можно не боясь проблем копировать готовые конструкции из одного скрипта в другой. В приведенном скриншоте каждый из разделов создавался отдельно, каждый в автономном скрипте.

    Конечно же у этого метода есть недостатки связанные исключительно с отсутствием у них возможностей функций, а именно:

    1. Удалив конструкцию, она пропадет из скрипта навсегда, тогда как при использовании функций вложенные действия остаются объявленными и их можно снова вызвать.
    2. Не получится использовать рекурсию. Частично заменил метками. Использовать их рекомендую только в самых простых конструкциях.
    3. Если очень хочется запустить часть скрипта в несколько потоков, всё-таки придется использовать функции =)

    Можно использовать такой метод для многократного повторения однотипных действий в скрипте. Аргументов у функций в BAS по прежнему нет. Так что можно как при использовании функций, объявить или присвоить значение какой-либо переменной, которая будет использоваться уже внутри конструкции. Однако следует помнить, что вновь добавленные в конструкцию экшны не будут добавлены в скопированные. Так что тут удобство сомнительно. Тут уж на вкус, цвет и внимательность.

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

    Может уже было. Может кому-то бесполезно. Жду факелы =)


  • administrators

    Есть ещё одна вещь, ради которой я не хочу создавать отдельную тему. Но вряд ли её кто-нибудь заметил.

    Это появление плагина Spoiler на форуме. Для создания спойлера можно воспользоваться кнопочкой на панели:
    0_1547467062558_fb8ed0dd-f7ab-47f4-8cb3-2ca7567e1b56-изображение.png

    После нажатия появится код

    
    
    
    

    Который на форуме будет выглядить вот так:
    0_1547467243595_06a63b02-49f5-49fb-bc22-7247bafd11e7-изображение.png
    0_1547467275803_2828136c-fcc5-4391-801a-4d85131e3a8b-изображение.png



    Важные момент в переопределении функций BAS, выполнять код нужно для каждого потока.

    0_1547467511179_4fff101c-69dc-483a-9eec-9a158b35ff9a-изображение.png

    Вот тестовый скрипт




  • @fox Как получить ID действия?



  • @yumilen как вариант придумай свои для лога