1 (изменено: Krot66, 2017-03-26 21:19:06)

Тема: AHK: Копирование выделенного текста в скрипт или текстовый файл

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

  • Для каждого типа и соответствующей клавиши задаются папка сохранения и кодировка.

  • В начало текста добавляется адрес страницы, при необходимости закомментированный.

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

  • Секундное зажатие горячей клавиши позволяет открыть файл в дефолтном приложении или заданном редакторе .

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

  • В текстовых файлах возможно так же автоматическое удаление переносов и OCR-чистка текста (исправление интервалов вокруг знаков препинания и скобок, удаление парных знаков и пр.). Вообще же для постобработки возможно подключение любой последовательности функций обработки текста, находящихся в скрипте или библиотеках.

  • Для каждого типа файлов ведется отдельный лог. Записи содержат имя файла, заголовок активного окна, адрес и начальный фрагмент текста.


#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance, force
Menu Tray, Icon, shell32.dll, 27
SetTitleMatchMode 2
SetTitleMatchMode Slow

/*
http://forum.script-coding.com/viewtopic.php?pid=114223#p114223
Скрипт для копирования выделенного текста в скрипт или текстовый файл
*/

key:="LAlt" ; кнопка, зажатие которой заставляет текст открыться в редакторе (иначе выводится сообщение подтверждения)
max_length:=120 ; ограничение длины имени файла
max_emptystr:=2 ; ограничение числа последовательных пустых строк по умолчанию
def_editor:="notepad.exe" ; путь к редактору по умолчанию
def_manager:="explorer.exe" ; путь к файловому менеджеру для открытия папки сохранения
logpath:="Logs" ; папка логов
fr:=20 ; число слов в начальных фрагментах логов
no_add:="SciTE4AutoHotkey|SumatraPDF|AkelPad|SynWrite|TextMaker|WinDjView|PDF-XChange Viewer" ; фрагменты заголовков окон, в которых не производится копирование адреса, разделенные "|" (в основном следует добавлять приложения, в которых сочетание Ctrl+L может произвести нежелательные изменения в интерфейсе или выделенном тексте)
return

!+F1::Run "%def_editor%" "%f_path%" ; Alt+Shift+F1 - открытие последнего файла	
!+F2::Run "%def_manager%" "%f_folder%" ; Alt+Shift+F2 - открытие последней папки

!+1::SaveText("_Textfiles",,,,1) ; Alt+Shift+1 - текстовый файл с названием из заголовка окна
!+2::SaveText("_Textfiles",1,,,1) ; Alt+Shift+2 - текстовый файл с названием из двух первых непустых строк
!+3::SaveText("_Textfiles",,,,2) ; Alt+Shift+3 - текстовый файл с названием из заголовка окна и удалением жестких переносов
!+4::SaveText("_Print",,,,"DropCap,OCR",1) ; Alt+Shift+4 - текстовый файл для печати

!+vk41::SaveText("_AHK",,"ahk",,,,";",1) ; Alt+Shift+A - юникодный ahk-скрипт с названием из заголовка окна
!+vk42::SaveText("_BAT",,"bat","cp866",,,"rem",2) ; Alt+Shift+B - батник
!+vk52::SaveText("_REG",,"reg","utf-16",,,";",2) ; Alt+Shift+R - регфайл

SaveText(folder,title=0,ext="txt",enc="utf-8",format=0,max_empty="",comment="url: ",editor=0)
/*
	folder - папка сохранения (абсолютный или относительный пути)
	title - название файла
		0 - из заголовка окна
		1 - из первых двух непустых строк
	ext - расширение
	enc - кодировка
	format - обработка текста
		0 - отсутствует
		1 - чистка OCR
		2 - чистка OCR плюс удаление жестких переносов (как на старых страницах Lib.ru)
	Вместо цифр сюда может быть вписана последовательность имен функций обработки текста, разделенных запятыми. Значение "RDel,OCR" приводит к тому же результату, что и равное 2.
	max_empty - максимальное число последовательных пустых строк в сохраненном тексте
	comment - коментарий для добавления адреса страницы
		0 - адрес не копируется и не добавляется
	editor - редактор для открытия текста
		0 - ассоциированный
		1 - редактор по умолчанию (как для ahk-файлов)
		2 - прописанный в настройках
*/
{
	global
	KeyWait	% key, T0.9
	e:=Errorlevel
	KeyWait	Shift, T1
	сlipboard_old:=Clipboard, add:=add2:=""
	WinGetActiveTitle t
	ClipBoard:=""
	Send ^{vk43}
	ClipWait 2
	If !clip:=Trim(Clipboard)
	{
		MsgBox, 262160, , Ничего не скопировано!, 1.5
		Clipboard:=сlip_old
		return
	}	
	If (clip~="^https?://\S+$")
	{
		MsgBox, 262160, , Фокус на адресной строке!, 1.5
		return
	}
	If (!(t~="(" no_add ")") && comment!=0)
			add:=CopyAddress()
	If add
		add2:=add "`r`n", add:=comment " " add "`r`n"		
	If !title
		f_name:=Trim(RegExReplace(t," - [^-]+$"))
	else
	{
		n:=0, f_name:=""
		Loop parse, clip, `n, `r
		{
			RegExMatch(A_LoopField,"m)^( |-|_|\*|#)+$",sep)
			If (!A_LoopField || sep)
				continue
			f_name.=A_LoopField " ", n+=1
			If (n=2)
				break
		}
		StringTrimRight f_name, f_name, 1
	}
	If StrLen(f_name)>max_length
	{
		f_name:=SubStr(f_name,1,max_length)
		StringGetPos sp, f_name,% " ", 1
		f_name:=SubStr(f_name,1,sp)
	}
	f_name:=FirstUppercase(ValidName(f_name))
	If format=2
		clip:=RDel(clip)
	If format in 1,2
		clip:=OCR(clip)
	else If format
		Loop Parse, format, CSV
			clip:=%A_LoopField%(clip)
	If !max_empty
		max_empty:=max_emptystr
	clip:=MaxEmptyString(clip,max_empty)
	mes:="Введите имя файла без расширения:"
	Input:
	InputBox f_name, % "Папка: " folder ", расширение: " ext ", кодировка: " enc ", формат " format, % mes, , 800, 120 , , , , ,% f_name
	If Errorlevel
	{
		Clipboard:=сlip_old
		return
	}
	f_path:=folder "\" f_name "." ext
	If FileExist(f_path)
	{
		mes:="Имя файла существует!"
		goto Input
	}
	FileCreateDir % folder
	FileAppend % add . clip,% f_path,% enc
	If Errorlevel
	{
		MsgBox, 262160, , Ошибка сохранения!, 1.5
		Clipboard:=сlip_old
		return
	}
	FileGetSize size, % f_path
	clip:=RegExReplace(clip,"\R"," ")
	StringGetPos pos, clip, % " ", L%fr%
	StringLeft clip2, clip, % pos
	FileCreateDir % logpath
	SplitPath f_path, name
	FileAppend % "`r`n`r`n`r`n" A_DD "." A_MM "." A_YYYY "  " A_Hour ":" A_Min "  " name "`r`n" t "`r`n" add2 . clip2 "(...)", % logpath "\" ext ".log"
	If e
	{
		If !editor
			Run "%f_path%"
		else If editor=1
			Run edit "%f_path%"
		else
			Run "%def_editor%" "%f_path%"
	}
	else
		MsgBox 262208, , % "Сохранено в:`n" f_path "`nРазмер " size " B", 1.5
	SplitPath f_path, , f_folder
	Clipboard:=сlip_old
	return
}

CopyAddress(e=0)
{
	Clipboard:=""
	Send ^{vk4C}
	Sleep 300
	Send ^{Ins}
	ClipWait 0.5
	If !Clipboard~="^htt(p|s)://\S+$"
		Clipboard:=""
	If (!Clipboard && e)
		MsgBox, 262160, , Адрес недоступен!, 1
	return Trim(Clipboard)
}

FirstUppercase(t)
{
	StringLeft n, t, 1
	StringTrimLeft k, t, 1
	StringUpper n, n
	return n . k
}

MaxEmptyString(text,max)
{
	text:=RegExReplace(text,"m)[ \t]+$")
	Loop % max+1
		n.="`r`n"
	return RegExReplace(text,"\R{" max+2 ",}",n)
}

ValidName(n,r="") ; r - замена пробелов
{
	n:=RegExReplace(n,"(:|;|,|\.|\*|\?|\\|/|<|>|"")"," ")
	n:=RegExReplace(n,"\s+"," ")
	StringReplace n, n, |, -, All
	If r
		StringReplace n, n, % " ", % r, All
	return Trim(n)
}

;---------------------------------------
OCR(t)
{
	t:=RegExReplace(t,"(\.|,|:|;)\K(,|:|;)") ; парные знаки
	t:=RegExReplace(t," {1,3}(?=(\.|,|:|;|!|\?|\)|]|}))") ; пробелы до знаков препинания
	t:=RegExReplace(t,"(\[|\{|\()\K\s{1,3}") ; пробелы после скобок
	t:=RegExReplace(t,"\.\K (?=\.)") ; пробелы меж точек
	t:=RegExReplace(t,"\.(?!(\d|\.| ))",". ") ; пробелы после точек
	t:=RegExReplace(t,",\.?(?!(\d| ))",", ") ; пробелы после запятых
	t:=RegExReplace(t,"m) {1,}$") ; пробелы в конце строк
	t:=RegExReplace(t,"\S\K {2,3}(?=\S)"," ") ; лишние пробелы
	t:=RegExReplace(t,"(:|;|!|\?)(?!(\d| |!|\?))","$1 ") ; пробелы после знаков
	t:=RegExReplace(t,"''","""")	; кавычки двойным апострофом
	return t
}

RDel(t) ; удаление жестких переносов
{
	return RegExReplace(t,"\R(?!( {4,10}|\t|\R))"," ")
}

DropCap(t) ; исправление буквиц, занимающих отдельную строку
{
return RegExReplace(t,"\R[A-ZЁЦУКЕНГШЩЗХФЫВАПРОЛДЖЭЯЧСМИТБЮ]\K\R")
}

2

Re: AHK: Копирование выделенного текста в скрипт или текстовый файл

Имелась ввиду шелуха, остающаяся после распознавания в невычитанном тексте: двойные запятые неправильные интервалы вокруг знаков, косяки с кавычками и пр.. В сети этого валом. Все это не исправляет, да и не может исправлять, но какой-то необходимый минимум - да.

3

Re: AHK: Копирование выделенного текста в скрипт или текстовый файл

Как понять "для получения по горячим клавишам готовых скриптов, батников, регфайлов или текстовых файлов из выделенного текста"? И нужно описание с примером использования.

4 (изменено: Krot66, 2017-03-26 21:41:14)

Re: AHK: Копирование выделенного текста в скрипт или текстовый файл

ypppu
Поправил описание. С примерами сложно: кажется, тут и так все ясно.
stealzy
Формально, оптическое распознавание текста.

5

Re: AHK: Копирование выделенного текста в скрипт или текстовый файл

Напишите хоть какие кнопки нажимать, что при этом должно происходить.

6

Re: AHK: Копирование выделенного текста в скрипт или текстовый файл

Как работает это сие чудо?

7 (изменено: stealzy, 2017-03-27 11:02:04)

Re: AHK: Копирование выделенного текста в скрипт или текстовый файл

Значит мы расшифровываем одинаково, но по разному понимаем смысл оптического распознавания .
Вспомнил, что The Gray Cardinal выкладывал скрипт для этой цели:
http://forum.script-coding.com/viewtopic.php?id=2577

8

Re: AHK: Копирование выделенного текста в скрипт или текстовый файл

Работает сие чудо так. Выделяем текст скрипта, нажимаем Alt+Shift+A. Выскакивает окно ввода со сгенерированным из заголовка окна текстом. В заголовке окна отображается папка сохранения и параметры сохранения. Если имя файла уже есть - окно вылазит снова. Такие же сочетания есть для батников, регфайлов и можно дописать для чего угодно.
Я в основном пользуюсь для простого текста. Есть скажем тест на старых страницах Lib.ru с фиксированной длиной строки и пробелами в начале абзаца. Вместо того, чтобы править регулярками в редакторе, нажали сочетание клавиш и получили готовый текст, который можно засунуть в читалку или куда еще. Копируете текст из pdf или djvu. Качество текстового слоя обычно очень посредственное (да и обычного невычитанного текста в сети очень много) - по сочетанию клавиш получили вполне сносный текст, в котором осталось руками удалить жесткие переносы. Имеете вы какой-нибудь часто используемый сайт, имеющий идиотские рекламные или контекстные вставки, или добавляемые при копировании хвосты "Читать далее на..." написали простую функцию обработки текста, вписали ее в функцию скрипта - не видите всех этих радостей и так оно вам хорошо.
Мне казалось, и тут уже говорили, таких прилад должно быть в сети множество. Это просто довольно универсальный вариант, который можно допиливать как угодно, приспосабливая к меняющимся обстоятельствам.