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

Archive version of: rebol-dom.r ... version: 18 ... inetw3dm 13-Feb

Amendment note: removed (mold join node-name) from with-this-data. caused invalid keys or nested string formating characters. || Publicly available? Yes

REBOL [
    	File: %rebol-dom.r
    	Date: 02-11-2020
    	Title: "Dialect Object Model"
        Emai: inetw3.dm@gmail.com
        author: daniel murrill
    	Purpose: {
             Use a recodable rebol function to create easy to follow blocks/series as 
             a Dialect Object Model  that allow different program languages to work together
             and viewed as HTML and VID. A parse alternative}
    	]

library: [
        author: daniel murrill
    	level: 'intermediate
        platform: 'all
        type: Dialect
        domain: [html vid css json js array]
        tested-under: 'windows
        support: none
        license: none
        see-also: %HTML-view.r
    ]

my-dialect: [body: [{background-color="blue" text "white"} ]
p: [
	{ "color":"#0000ff", "bgcolor":"yellow", "width" : "399", "height" : "100" "font-styles": "big" } 
 This is an example of an Dialect Oject Model
b: [
	{color = "Chocolate" bgcolor = "yellow"} 
	
 that can be written to look like json' html' javascript arrays' css'  
i: [
	{color = "green"} 
	
 VID' or plain old rebol ] 
  ] 
 if you like.
  ]

var anObj = { 100: 'a', 2: 'b', 7: 'c', };

hr: [{color="red" bgcolor="yellow"}]

div: [
	{width="399" bgcolor="orange"}  
b: [
	{color: "purple" bgcolor: "orange"} 
	
 Maybe it would be easier to write  
i: [
	{color: "green"}
	
 MakeDoc.r code but the purpose of this rebol DOM is']  
   ]
]

lua-tbl = {[first] = "fred", [last] = "cougar"} 
    
#this-issue [{color: "purple" bgcolor: "orange"}]

p: [
	{width "399" height= 200 
	style="color: red;	bgcolor: brown;	border: 2x2;" 
	} 
b: [	 
	{color="red"}
 to read or load as many well known dialects of coding styles as possible
 and write all of it as a single or seperate legible rebol series that's
 quickly manipulated' transcoded as html' and viewed as a VID. ]
	]
]


document.: func [request-as][
		attempt [
		DOM: head DOM
		if block! != type? data-node [this: copy data-node insert data-node: [] this]
		if data-node/1 [
		data: type? data-node/1 
		either equal? data tag!
					[node-element: data-node/1 use*=*to-set-values
					 var style: .style: = node-element style: .style: :array-obj!
					]
					[node-element: data-node/1: build-tag to-block first parent-node: data-node]
					]
					 
					
					return node-element
				]use*=*to-set-values styles: ""
]
	
return-tag-node: does [=: :equal? 
				if block! != type? data-node [this: copy data-node insert data-node: [] this]
				if type? block! = node-element: data-node/1 [
				replace/all node-element [=] [] 
			    node-element: data-node/1: build-tag to-block node-element
			]
]
			
.style: []
equal?: :=
DOM: DSL: html: window: end-tag: ""
data-node: parent-node: node: none

.body: .hr: .p: .b: .i: .tr: .ul: .li: .table: .td: .button: .input: .div: .font: .span: 0
node-obj: node-element: node-name: *name: use-methods: attr-name: attr-value: none

check: func [select-this][node-name: select-this =: :equal?
	any [
		if block! = type? select-this [ select-this: first parse/all node-name " "]
		if string! = type? select-this [select-this: first parse/all node-name " "]
		if tag! = type? select-this [select-this: first parse/all node-name " "]
		]
]
			

		 
strip-chars-from: func [node-name][
			foreach char elemt-chars: ["{" "}" {"} "(" ")" "/" "." "[" "]" "," ":" ";" "," "="
			][
			replace/all node-name char " "
			]	
]

strip-obj-chars-from: func [node-name][
			trim node-name if #"^"" = node-name/1 [remove node-name]
			foreach [-char +char] obj-chars: [#"^/" " " 
			"," "" {" : "} {: "} {":"} {: "} {":} {:} {" "} {" } { " } "" 
			"[" "" "]" "" {""} {"} {  "} "" ":" "" { =} {=} {=} " " "'" ""
			][
			replace/all node-name -char +char
			]
]

getnodename: func [node-name][count: [] DOM: head DOM
		=: :equal?
		either block! = type? node-name [data-node: :node-name if error? try [
		node-element: data-node/1: build-tag data-node/1][
		node-element: data-node]
		][
		node-name: to block! strip-chars-from form node-name
		if error? try [count: pick find node-name integer! 1][count: 1]
		if error? try [nodename: to-word join  "." array-obj!: node-name/1 
		repeat ? count [data-node: first DOM: next node: find DOM nodename]
		][print reduce ["node-name:" mold form node-name/1 "not found"]
		] 
		return either tag! = type? data-node/1 [node-element: data-node/1][node-element: data-node] 
		slf: join node-name/1 count
		] 
]

setnodename: func [old-name new-name][
		this-name: check strip-chars-from old-name node-element-name: check node-element
		same: this-name = node-element-name
		if false = same [getnodename old-name]
		if not find node-element new-name [	
		replace node-element to string! this-name new-name 
		replace data-node to-tag join "/" this-name  to-tag join "/" new-name 
		]		
]
 
getattribute: func [attr-name][use*=*to-set-values
			attr-value: mold array-obj! reduce attr-name
			either attr-value [print reduce [attr-name attr-value]
			][print reduce ["node-attribute:" mold form attr-name "not found"]
			]
						
] 

setattribute: func [attr-name new-attr][return-tag-node
			either find/any node-element any [to-string reduce [attr-name "="] form attr-name][ 
			replace node-element attr-name new-attr
			;get-attributes node-element attempt [set-attributes]
		][
			either node-element [insert tail node-element reduce [" " new-attr {="null"}]
		][
			print reduce ["Must get a parent-node with this attribute: " attr-name]
            ]
	   ]		
]			

setattributevalue: func [attr-name attr-value][return-tag-node
			either find/any node-element any [to-string reduce [attr-name "="] form attr-name] [ 
			document.(window) any [attempt [.style/:attr-name: = attr-value] attempt [.style/(to-word join "." :attr-name): attr-value]]  
			return-tag-node ;get-attributes node-element attempt [set-attributes]
		][
			either node-element [insert tail node-element reduce [" " attr-name {="} attr-value {"}]
			;get-attributes node-element attempt [set-attributes]
		][	
			print reduce ["Must get a parent-node with this attribute: " attr-name]
            ]
	   ]		
]

getElementByTagName: func [array-obj! selection [block!]][
			dom: head dom 
			repeat this first selection [
			node-element: first data-node: first dom: next find dom to-word join "." array-obj! 
			]
			if [use-methods and not find node-element " ." ][use-attr-as-methods yes]
			use-methods: off		
]
		 	
use*=*to-set-values: does [=: func [value][any [value]]]

use-attr-as-methods: func [maybe [logic!]][
			if maybe [foreach [-char +char][{" } {" .}][replace/all node-element -char +char]
			]
			replace node-element " " " ."
			use-methods: yes
]
	
var: func [var-data [string! tag!]][
			variable: first parse node-element: var-data "=:, "
			use*=*to-set-values
			node-element
			do reform ["array-obj!: " join variable ":" 
			{func [key [block! word! string!]][any [
			attempt [*value: first next find parse form parse node-element {=} {:;,} *key: form key] } 
			join variable ": {" node-element: var-data "}]]"
			]
			variable: none
			use-methods: off
]

arr=: `=: func[value][
			equal: '= 
			either equal? *value/1 #"'" [
			replace node-element *value to-string reduce ["'" value "'"]
			]
			[
			either find node-element mold form *value [
			replace node-element mold *value mold value
			][			
			replace node-element *value value
			]
			 replace/all node-element {""} {"}
			]
			
 ]

node-element: array-obj!: key: *key: *value: ""


markup-DOM: func [DSL][DOM: DSL
		either block! = type? DSL [
			either find DSL <rebol-DOM type="text/html"> []
			[insert DSL <rebol-DOM type="text/html">
			DOM: DSL: load replace/all mold DSL "__" " "
			
get-data: func [data][	
		find-end-tag: find data get-word!
			either find-end-tag [
			replace data first find-end-tag  to-tag mold to-refinement first find-end-tag][insert tail data to-tag join "/" any [*name *node-name]
			]
repeat in-data data [cnt: 0
		if set-word! = type? in-data [*node-name: copy form in-data
			replace data in-data node-name: to-word join "." *node-name
			]
		if string! = type? in-data [
			strip-obj-chars-from in-data 
			insert in-data next reform [node-name " "]
			child: build-tag to-block in-data 
			;foreach [a b][" " " ."][replace/all child a b]
			replace data in-data child
			]
		if block! = type? in-data [
			set to-word join *node-name cnt: cnt + 1 in-data
			get-next in-data
			]
		]	 
]

get-next: func [in-data][
	repeat data in-data [
		if set-word! = type? data [*name: copy form data
			replace in-data data node-name: to-word join "." *name
			]
		if string! = type? data [
			strip-chars-from data  
			insert data next reform [node-name " "]
			child: build-tag to-block data 
			;foreach [a b][" " " ."][replace/all child a b]
			replace in-data data child
			]
		if block! = type? data [get-data data
			set to-word *node-name data]
		] find-end-tag: find in-data get-word!
			either find-end-tag[
			replace in-data first find-end-tag  to-tag mold to-refinement first find-end-tag][insert tail in-data to-tag join "/" any [*node-name *name]
			clear *node-name]
		

]

repeat with-this-data DSL [
		
		if issue! = type? with-this-data [
			node-name: to-word join "." *name: copy form with-this-data
			]
		if set-word! = type? with-this-data [
			replace DSL with-this-data node-name: to-word join "." *name: copy form with-this-data
			]
		if word! = type? with-this-data [
			either '= = with-this-data [string-is-data: yes replace DSL with-this-data ""
			][
			*name: copy form with-this-data
			replace DSL with-this-data node-name: to-word join "." with-this-data] 
			replace DSL reduce [node-name node-name] node-name
			]
		if string! = type? with-this-data [
			either string-is-data [replace DSL with-this-data join node-name with-this-data][
			created-data: copy with-this-data
			strip-obj-chars-from created-data  
			insert created-data reduce [node-name " "]
			child: build-tag to-block remove created-data 
			;foreach [a b][" " " ."][replace/all child a b]
			replace DSL with-this-data child
			]
			string-is-data: no
			]
		if block! = type? with-this-data [ 
			get-data with-this-data
			]
			
		if get-word! = type? with-this-data [
			replace DSL with-this-data to-tag mold to-refinement *name
			]
]	
	       ]
		   ][
		   alert "Need a Dialect Object Model as type! block"
		   ]
		replace/all dsl "" [] DOM: copy DSL
 ]

return-html-dsl: does [
		html: copy form any [find head DOM "<body" head DOM]	
		replace/all replace/all html "<." "<" "' " ", "
		;replace/all replace/all html "{" "<" "}" ">" 
		foreach n-name [
						".body " ".hr " ".p " ".b " ".i " ".? " 
						".tr " ".table " ".td " ".button " ".input "
						".div " ".ul " ".li " ".font " ".span "
						".img " ".a " ".strong " " ." ".hr " ".lua-tbl "
						][replace/all html n-name " "
						]
		append replace/all html </body> "" </body>
		html: any [find html "<body" html]
]

{
**************************************************************************************************
An example of how to use the DOM functions follows. The syntax hopefully should be easy to follow being that it
resembles how you would use javascript with the HTML,XML DOM. 

It's just a little bit different, why not just make it the same?

Were not scripting against a DOM, (a Documents  Object Modle) but a DOM, (a Dialect Object Modle) because 
you may not actually know the syntax of the loaded document or data before it's transcode to a DOM from a DSL.

Plus Rebol wont let you too far off the hook in writing code any way you like. Some *op Words and  code/data 
has set types that follow a strict syntax. I think the best way around this is to load as type? string!, reformat 
and parse as type? block!. Maybe.....

These DOM functions should work very close to the HTML DOM functions:

getElementsByTagName .getAttribute .setAttribute 
}


markup-DOM my-dialect
        
document. getnodename {"div"[1]}getattribute "bgcolor"	
	
document. getnodename{("p")[2]} .style[width] `= "block-build"

setattributevalue('height)"1000"
	
	node-element

    getattribute "height"

setnodename {hr[1]} "listview"
	node-element	
		
document. getnodename{("p")[1]}.style[font-styles] `= "block-build"
	
	setattribute('font-styles)"whithouse"
	
	setattributevalue('boogies)"green-color"
	 
data-node: do to-path [DOM .p .b] 

document.(data-node).style[color] `= "bluberry" 

	setattribute('i-style) "silly" 
	

; some examples of selecting keys and values set to variables as an array object.
; good to use with anything that's structured with {} or " ". 
;IE (javascript, json objects/arrays.. lua table/arrays.. associative arrays etc.) 
;even DOM's and rebol data.

{you must use use*=*to-set-values before setting the first variable.
it will use = to set any value to a variable (a set-word)} 
;`= this literal equal is used to set values to keys 

use*=*to-set-values

var anObj: = {anObj 100:"a" 2 : "b" 7="c"}

anObj[2]
anObj[2] `= "zz"

node-element

use-methods: yes

var app: = document.(getElementByTagName('p)[2]) 

;call/associate the array-obj! with this variable name

app: :array-obj!

;the style.obj! is auto created by using the document. function

.style[bgcolor]
;is the same as calling 
app[bgcolor]

app[.width] `= "curly quew"
app('bgcolor) `= {'purple'}


;when you need to create a variable to use with an array-obj!

var join {poppy } {100:"a" street : "backside" 7="c"}

poppy[street]`="old rover rd."
poppy[7] `= "cities"

;when calling a nodename and use that name as the variable.

var anObj: = getnodename "anobj"

;call/associate the array-obj! with this variable name
anObj: :array-obj!

anobj[7] 

;after calling some variable[key]/array-obj![key], you can replace the key and value.

replace replace node-element *key 'this-key *value {'some-value'}

data-node

probe return-html-dsl