Script Library: 1238 scripts
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Archive version of: parse-aid.r ... version: 7 ... luce80 6-May-2012

Amendment note: added undo (Ctrl+Z) and redo (Ctrl+R) || Publicly available? Yes

REBOL [
	title: "Parse Aid"
	file: %parse-aid.r
	author: "Marco Antoniazzi"
	Copyright: "(C) 2011 Marco Antoniazzi. All Rights reserved"
	email: [luce80 AT libero DOT it]
	date: 05-05-2012
	version: 0.5.8
	Purpose: "Help make and test parse rules"
	History: [
		0.5.1 [03-09-2011 "First version"]
		0.5.2 [04-09-2011 "modified resizing"]
		0.5.3 [17-09-2011 "Added balancing, changed save format (using strings to preserve comments)"]
		0.5.4 [18-09-2011 "Modified infinite loop exit mode,fixed scrollers"]
		0.5.5 [24-09-2011 "added shift-selecting"]
		0.5.6 [05-01-2012 "added results auto-scrolling"]
		0.5.7 [22-01-2012 "little bug fix in error handling"]
		0.5.8 [05-05-2012 "added undo (Ctrl+Z) and redo (Ctrl+R)"]
	]
	comment: "28-Aug-2011 GUI automatically generated by VID_build. Author: Marco Antoniazzi"
	library: [
		level: 'intermediate
		platform: 'all
		type: 'tool
		domain: 'parse
		tested-under: [View 2.7.8.3.1]
		support: none
		license: 'BSD
		see-also: none
	]
	todo: {
		- parse blocks
		- undo
		- ask to save before exit if something modified
		- scroll-wheel
	}
]
			
; file , undo
	change_title: func [/modified] [
		clear find/tail main-window/text "- "
		if modified [append main-window/text "*"]
		append main-window/text to-string last split-path any [job-name %Untitled]
		main-window/changes: [text] show main-window
	]
	open_file: func [/local file-name temp-list job] [
		until [
			file-name: request-file/title/keep/only/filter "Load a rules file" "Load" "*.r"
			if none? file-name [exit]
			exists? file-name
		]

		job-name: file-name
		temp-list: load file-name
		if not-equal? first temp-list 'Parse_Aid-block [exit]
		job: temp-list

		set-face check-clear-res get job/clear-res
		set-face check-spaces get job/spaces
		set-face field-main-rule job/main-rule
		set-face area-charsets job/charsets
		set-face area-rules job/rules
		set-face area-test job/test

		named: yes
		change_title
		saved?: yes
	]
	save_file: func [/as /local file-name filt ext response job] [
		;if empty? job [return false]
		if not named [as: true]

		if as [
			filt: "*.r"
			ext: %.r
			file-name: request-file/title/keep/only/filter "Save as Rebol file" "Save" filt
			if none? file-name [return false]
			if not-equal? suffix? file-name ext [append file-name ext]
			response: true
			if exists? file-name [response: request rejoin [{File "} last split-path file-name {" already exists, overwrite it?}]]
			if response <> true [return false]
			job-name: file-name
			named: yes
		]
		flash/with join "Saving to: " job-name main-window

		job: reduce [
			'Parse_Aid-block 1
			'clear-res get-face check-clear-res
			'spaces get-face check-spaces
			'main-rule get-face field-main-rule
			'charsets get-face area-charsets
			'rules get-face area-rules
			'test get-face area-test
		]
		save job-name job

		wait 1.3
		unview
		change_title
		saved?: yes
	]
	undo: does [
		if system/view/focal-face/parent-face/style = 'area-scroll [system/view/focal-face/parent-face/undo]
	]
	redo: does [
		if system/view/focal-face/parent-face/style = 'area-scroll [system/view/focal-face/parent-face/redo]
	]
; rules
	charsets-block: copy [
		digit: charset [#"0" - #"9"]
		upper: charset [#"A" - #"Z"]
		lower: charset [#"a" - #"z"]
		alpha: union upper lower
		alpha_: union alpha charset "_"
		alpha_digit: union alpha_ digit
		hexdigit: union digit charset "abcdefABCDEF"
		bindigit: charset "01"
		space: charset " ^-^/"
	]
	rules-block: copy [
		digits: [some digit]
		sp*: [any space]
		sp+: [some space]
		
		area-code: ["(" 3 digit ")"]
		local-code: [3 digit "-" 4 digit]
		phone-num: [opt area-code copy var local-code (print ["number:" var])]
	]

	err?: func [blk /local arg1 arg2 arg3 message err][;11-Feb-2007 Guest2
		if not error? err: try blk [return :err]
		err: disarm err
		set [arg1 arg2 arg3] reduce [err/arg1 err/arg2 err/arg3]
		message: get err/id
		if block? message [bind message 'arg1]
		print ["**ERROR: " form reduce message]
		none
	]
	prin: func [value] [
		either 100000 > length? get-face area-results [ ; avoid fill mem
			set-face area-results append get-face area-results form reduce value
			system/view/vid/vid-feel/move-drag area-results/vscroll/pane/3 1 ; autoscroll down
		][
			alert "ERROR. Probable infinite loop."
			reset-face area-results
			throw
		]
	]
	print: func [value] [prin value prin newline]
	parse_test: func [/local result] [
		if get-face check-clear-res [reset-face area-results]
		result: err? [
			do get-face area-charsets
			do get-face area-rules
			do pick [parse/all parse] get-face check-spaces copy get-face area-test get load get-face field-main-rule
		]
		text-parsed/color: white
		show text-parsed
		wait .1 ; to see the activity
		either logic? result [
			text-parsed/color: 80 + either result [green] [red]
			text-parsed/text: uppercase form result
		] [
			text-parsed/text: "ERROR"
		]
		show text-parsed
	]
; gui
	;do %../area-scroll-style.r ;Copyright: {GNU Less General Public License (LGPL) - Copyright (C) Didier Cadieu 2004} 
	do decompress ; %area-scroll-style.r Copyright: {GNU Less General Public License (LGPL) - Copyright (C) Didier Cadieu 2004} 
		64#{
		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
		UJgjAAA=
		}
	rezize-faces: func [siz [pair!] /move] [
		area-charsets/ar/line-list: none ; to reactivate auto-wrapping
		resize-face/no-show area-charsets area-charsets/size + (siz * 1x0)

		area-rules/ar/line-list: none ; to reactivate auto-wrapping
		resize-face/no-show area-rules area-rules/size + (siz * 1x2)

		text-test/offset/x: text-test/offset/x + siz/x
		area-test/offset/x: area-test/offset/x + siz/x

		text-results/offset: text-results/offset + siz
		area-results/offset: area-results/offset + siz
		if move [siz: - siz]
		resize-face/no-show area-test area-test/size + siz
		resize-face/no-show area-results area-results/size + siz
	]
	feel-move: [
		engage-super: :engage
		engage: func [face action event /local prev-offset] [
			engage-super face action event
			;if (action = 'down) [
			;	face/user-data: event/offset
			;]
			if find [over away] action [
				prev-offset: face/offset
				face/offset/x: face/old-offset/x + event/offset/x ;- face/user-data/x ; We cannot modify face/old-offset but why not use it?
				face/offset/x: first confine face/offset face/size area-charsets/offset + 100x0 area-test/offset + area-test/size - 100x0

				if prev-offset <> face/offset [
					rezize-faces/move (face/offset - prev-offset * 1x0)
					show main-window
				]
			]
			;show face
		]
	]
	;append system/view/VID/vid-styles area-style ; add to master style-sheet
	main-window: center-face layout [
		styles area-style
		do [sp: 4x4] origin sp space sp
		Across
		btn "(O)pen..." #"^O" [open_file]
		btn "(S)ave" #"^S" [save_file]
		pad (sp * -1x0)
		btn "as..." [save_file/as]
		;check-line "save also test" on
		pad 350
		btn "Clear (T)est" #"^T" [reset-face area-test]
		btn "Clear R(e)sults" #"^e" [reset-face area-results]
		check-clear-res: check-line "before every parse"
		return
		btn "(P)arse" #"^P" yellow [parse_test]
		check-spaces: check-line "also spaces" on
		;check-line "on rules update" on
		text "with this rule:" bold
		field-main-rule: field "phone-num" 300x22
		text bold "Result:"
		text-parsed: text bold as-is "  NONE  " black white center
		return
		Below
		guide
		style area-scroll area-scroll 400x200 hscroll vscroll font-name font-fixed para [origin: 2x0 Tabs: 10]
		text bold "Charsets"
		area-charsets: area-scroll wrap
		text-rules: text bold "Rules"
		area-rules: area-scroll wrap
		return
		button-balance: button "|" 6x450 gray feel feel-move edge [size: 1x1]
		return
		text-test: text bold "Test"
		area-test: area-scroll "(707)467-8000"
		text-results: text bold "Results"
		area-results: area-scroll silver read-only
		key escape (sp * 0x-1) [ask_close]
		key #"^Z" (sp * 0x-1) [undo]
		key #"^R" (sp * 0x-1) [redo]
	]
	main-window/user-data: reduce ['size main-window/size]
	insert-event-func func [face event /local siz] [
		switch event/type [
			close [
				ask_close
				return none
			]
			resize [
				face: main-window
				siz: face/size - face/user-data/size / 2     ; compute size difference / 2
				face/user-data/size: face/size          ; store new size

				rezize-faces siz
				button-balance/offset: button-balance/offset + (siz * 1x0)
				button-balance/size: button-balance/size + (siz * 0x2)
				show main-window
			]
		]
		event
	]
	ask_close: does [
		either not saved? [
			switch request ["Exit without saving?" "Yes" "Save" "No"] reduce [
				yes [quit]
				no [if save_file [quit]]
			]
		][
			if confirm "Exit now?" [quit]
			;quit
		]
	]
; main
	
	set-face area-charsets trim mold/only charsets-block
	set-face area-rules trim mold/only rules-block

	job-name: none
	named: no
	saved?: yes
	main-title: join copy System/script/header/title " - Untitled"
	view/title/options main-window main-title reduce ['resize 'min-size main-window/size + system/view/title-size + 8x10 + system/view/resize-border]