Render items with react

This commit is contained in:
Florian Schroedl
2022-05-04 17:00:00 +02:00
parent 2e57ff5129
commit 643ced98ab
16 changed files with 6238 additions and 40 deletions

2
.gitignore vendored
View File

@@ -4,3 +4,5 @@ result
/dst/
/tests/nimcache/
/tests/testresults/
node_modules
sandbox.js

View File

@@ -0,0 +1,2 @@
import react16/react_hooks
import react16/react_dom, react16/react_types, react16/react_styles

View File

@@ -0,0 +1,187 @@
import macros, dom, jsffi
import react_types
from react_globals import React
{.experimental: "callOperator".}
when not defined(js):
{.error: "React.nim is only available for the JS target".}
type NodeOrString = ReactNode or seq[ReactNode] or cstring or string
macro idString(x: untyped): auto = newStrLitNode($x)
template tocstring(x: typed): auto =
when x is string: cstring(x)
else: x
{.push importcpp.}
proc createElement*(react: ReactGlobal, tag: cstring, props: Attrs): ReactNode
proc createElement*(react: ReactGlobal, tag: cstring, props: Attrs,
n1: auto): ReactNode
{.pop.}
template makeDomElement(x: untyped, name: string = "") =
const tag {.gensym.} = if name == "": cstring(idString(x)) else: name
const NIL: Attrs = nil
proc x*(a: Attrs): ReactNode =
React.createElement(tag, a)
proc x*(a: Attrs, n1: NodeOrString): ReactNode =
let m1 = n1.tocstring
React.createElement(tag, a, m1)
proc x*(a: Attrs, n1, n2: NodeOrString): ReactNode =
let
m1 = n1.tocstring
m2 = n2.tocstring
React.createElement(tag, a, m1, m2)
proc x*(a: Attrs, n1, n2, n3: NodeOrString): ReactNode =
let
m1 = n1.tocstring
m2 = n2.tocstring
m3 = n3.tocstring
React.createElement(tag, a, m1, m2, m3)
proc x*(a: Attrs, n1, n2, n3, n4: NodeOrString): ReactNode =
let
m1 = n1.tocstring
m2 = n2.tocstring
m3 = n3.tocstring
m4 = n4.tocstring
React.createElement(tag, a, m1, m2, m3, m4)
proc x*(n1: NodeOrString): ReactNode =
let m1 = n1.tocstring
React.createElement(tag, NIL, m1)
proc x*(n1, n2: NodeOrString): ReactNode =
let
m1 = n1.tocstring
m2 = n2.tocstring
React.createElement(tag, NIL, m1, m2)
proc x*(n1, n2, n3: NodeOrString): ReactNode =
let
m1 = n1.tocstring
m2 = n2.tocstring
m3 = n3.tocstring
React.createElement(tag, NIL, m1, m2, m3)
proc x*(n1, n2, n3, n4: NodeOrString): ReactNode =
let
m1 = n1.tocstring
m2 = n2.tocstring
m3 = n3.tocstring
m4 = n4.tocstring
React.createElement(tag, NIL, m1, m2, m3, m4)
makeDomElement(a)
makeDomElement(abbr)
makeDomElement(address)
makeDomElement(area)
makeDomElement(article)
makeDomElement(aside)
makeDomElement(audio)
makeDomElement(b)
makeDomElement(base)
makeDomElement(bdi)
makeDomElement(bdo)
makeDomElement(big)
makeDomElement(blockquote)
makeDomElement(body)
makeDomElement(br)
makeDomElement(button)
makeDomElement(canvas)
makeDomElement(caption)
makeDomElement(cite)
makeDomElement(code)
makeDomElement(col)
makeDomElement(colgroup)
makeDomElement(data)
makeDomElement(datalist)
makeDomElement(dd)
makeDomElement(del)
makeDomElement(details)
makeDomElement(dfn)
makeDomElement(dialog)
makeDomElement(`div`, "div")
makeDomElement(dl)
makeDomElement(dt)
makeDomElement(em)
makeDomElement(embed)
makeDomElement(fieldset)
makeDomElement(figcaption)
makeDomElement(figure)
makeDomElement(footer)
makeDomElement(form)
makeDomElement(h1)
makeDomElement(h2)
makeDomElement(h3)
makeDomElement(h4)
makeDomElement(h5)
makeDomElement(h6)
makeDomElement(head)
makeDomElement(header)
makeDomElement(hgroup)
makeDomElement(hr)
makeDomElement(html)
makeDomElement(i)
makeDomElement(iframe)
makeDomElement(img)
makeDomElement(input)
makeDomElement(ins)
makeDomElement(kbd)
makeDomElement(keygen)
makeDomElement(label)
makeDomElement(legend)
makeDomElement(li)
makeDomElement(link)
makeDomElement(main)
makeDomElement(map)
makeDomElement(mark)
makeDomElement(menu)
makeDomElement(menuitem)
makeDomElement(meta)
makeDomElement(meter)
makeDomElement(nav)
makeDomElement(noscript)
makeDomElement(`object`)
makeDomElement(ol)
makeDomElement(optgroup)
makeDomElement(option)
makeDomElement(output)
makeDomElement(p)
makeDomElement(param)
makeDomElement(picture)
makeDomElement(pre)
makeDomElement(progress)
makeDomElement(q)
makeDomElement(rp)
makeDomElement(rt)
makeDomElement(ruby)
makeDomElement(s)
makeDomElement(samp)
makeDomElement(script)
makeDomElement(section)
makeDomElement(select)
makeDomElement(small)
makeDomElement(source)
makeDomElement(span)
makeDomElement(strong)
makeDomElement(style)
makeDomElement(sub)
makeDomElement(summary)
makeDomElement(sup)
makeDomElement(svg)
makeDomElement(table)
makeDomElement(tbody)
makeDomElement(td)
makeDomElement(textarea)
makeDomElement(tfoot)
makeDomElement(th)
makeDomElement(thead)
makeDomElement(time)
makeDomElement(title)
makeDomElement(tr)
makeDomElement(track)
makeDomElement(u)
makeDomElement(ul)
makeDomElement(`var`)
makeDomElement(video)
makeDomElement(wbr)

View File

@@ -0,0 +1,15 @@
import react_types
when not defined(js):
{.error: "React.nim is only available for the JS target".}
var
React*{.importc, nodecl.}: ReactGlobal
ReactDOM*{.importc, nodecl.}: ReactDOMGlobal
type
Component*[P, S] = ref object of RootObj
props*: P
state*: S
setState*{.importcpp.}: proc(s: S)
StatelessComponent*[P] = Component[P, void]

View File

@@ -0,0 +1,33 @@
import jsffi
import sugar
type
Context* = JsObject
Reference* = ref object of JsObject
current*: auto
UseState*[S] = ref object of JsObject
getter*: S
setter*: S -> S
proc myUseState*[S](initialState: S): UseState[S] {.importjs: "myUseState(#)".}
# proc useState*(react: ReactGlobal, initialState: State): seq[string] {.importjs: "#.useState(#)".}
# proc useState*(react: ReactGlobal, initialState: State): tuple[state: string, setterFn: proc(newState: JsObject)] {.importjs: "#.useState(#)".}
# proc useEffect*(react: ReactGlobal, didUpdate: proc(), triggerDependencies: seq[auto]) {.importjs: "#.useEffect(#)".}
# proc useContext*(react: ReactGlobal, context: JsObject): Context
# proc useReducer*(react: ReactGlobal, reducer: proc(): auto, initialArg: auto, init: proc())
# proc useCallback*(react: ReactGlobal, callback: proc(), triggerDependencies: auto)
# proc useMemo*(react: ReactGlobal, createFn: proc(), recomputeDependencies: auto)
# proc useRef*(react: ReactGlobal, react2: ReactGlobal): Reference
# proc useImperativeHandle*(react: ReactGlobal, reference: Reference, createHandle: proc(),
# dependencies: sea[auto])
# proc useLayoutEffect*(react: ReactGlobal, didUpdate: proc(), triggerDependencies: seq[auto])
# proc useDebugValue*(react: ReactGlobal, initialState: auto): auto
# concurrent mode hooks (experimental) - see https://reactjs.org/docs/concurrent-mode-reference.html
# proc useTransition*(react: ReactGlobal, suspenseConfig: JsObject): auto
# proc useDeferredValue*(react: ReactGlobal, value: auto, suspenseConfig: JsObject): auto

View File

@@ -0,0 +1,188 @@
type
Style* = ref object of RootObj
alignContent*, # Sets or returns the alignment between the lines inside a flexible container when the items do not use all available space 3
alignItems*, # Sets or returns the alignment for items inside a flexible container 3
alignSelf*, # Sets or returns the alignment for selected items inside a flexible container 3
animation*, # A shorthand property for all the animation properties below, except the animationPlayState property 3
animationDelay*, # Sets or returns when the animation will start 3
animationDirection*, # Sets or returns whether or not the animation should play in reverse on alternate cycles 3
animationDuration*, # Sets or returns how many seconds or milliseconds an animation takes to complete one cycle 3
animationFillMode*, # Sets or returns what values are applied by the animation outside the time it is executing 3
animationIterationCount*, # Sets or returns the number of times an animation should be played 3
animationName*, # Sets or returns a name for the @keyframes animation 3
animationTimingFunction*, # Sets or returns the speed curve of the animation 3
animationPlayState*, # Sets or returns whether the animation is running or paused 3
background*, # Sets or returns all the background properties in one declaration 1
backgroundAttachment*, # Sets or returns whether a background-image is fixed or scrolls with the page 1
backgroundColor*, # Sets or returns the background-color of an element 1
backgroundImage*, # Sets or returns the background-image for an element 1
backgroundPosition*, # Sets or returns the starting position of a background-image 1
backgroundRepeat*, # Sets or returns how to repeat (tile) a background-image 1
backgroundClip*, # Sets or returns the painting area of the background 3
backgroundOrigin*, # Sets or returns the positioning area of the background images 3
backgroundSize*, # Sets or returns the size of the background image 3
backfaceVisibility*, # Sets or returns whether or not an element should be visible when not facing the screen 3
border*, # Sets or returns borderWidth, borderStyle, and borderColor in one declaration 1
borderBottom*, # Sets or returns all the borderBottom properties in one declaration 1
borderBottomColor*, # Sets or returns the color of the bottom border 1
borderBottomLeftRadius*, # Sets or returns the shape of the border of the bottom-left corner 3
borderBottomRightRadius*, # Sets or returns the shape of the border of the bottom-right corner 3
borderBottomStyle*, # Sets or returns the style of the bottom border 1
borderBottomWidth*, # Sets or returns the width of the bottom border 1
borderCollapse*, # Sets or returns whether the table border should be collapsed into a single border, or not 2
borderColor*, # Sets or returns the color of an element's border (can have up to four values) 1
borderImage*, # A shorthand property for setting or returning all the borderImage properties 3
borderImageOutset*, # Sets or returns the amount by which the border image area extends beyond the border box 3
borderImageRepeat*, # Sets or returns whether the image-border should be repeated, rounded or stretched 3
borderImageSlice*, # Sets or returns the inward offsets of the image-border 3
borderImageSource*, # Sets or returns the image to be used as a border 3
borderImageWidth*, # Sets or returns the widths of the image-border 3
borderLeft*, # Sets or returns all the borderLeft properties in one declaration 1
borderLeftColor*, # Sets or returns the color of the left border 1
borderLeftStyle*, # Sets or returns the style of the left border 1
borderLeftWidth*, # Sets or returns the width of the left border 1
borderRadius*, # A shorthand property for setting or returning all the four borderRadius properties 3
borderRight*, # Sets or returns all the borderRight properties in one declaration 1
borderRightColor*, # Sets or returns the color of the right border 1
borderRightStyle*, # Sets or returns the style of the right border 1
borderRightWidth*, # Sets or returns the width of the right border 1
borderSpacing*, # Sets or returns the space between cells in a table 2
borderStyle*, # Sets or returns the style of an element's border (can have up to four values) 1
borderTop*, # Sets or returns all the borderTop properties in one declaration 1
borderTopColor*, # Sets or returns the color of the top border 1
borderTopLeftRadius*, # Sets or returns the shape of the border of the top-left corner 3
borderTopRightRadius*, # Sets or returns the shape of the border of the top-right corner 3
borderTopStyle*, # Sets or returns the style of the top border 1
borderTopWidth*, # Sets or returns the width of the top border 1
borderWidth*, # Sets or returns the width of an element's border (can have up to four values) 1
bottom*, # Sets or returns the bottom position of a positioned element 2
boxDecorationBreak*, # Sets or returns the behaviour of the background and border of an element at page-break, or, for in-line elements, at line-break. 3
boxShadow*, # Attaches one or more drop-shadows to the box 3
boxSizing*, # Allows you to define certain elements to fit an area in a certain way 3
captionSide*, # Sets or returns the position of the table caption 2
clear*, # Sets or returns the position of the element relative to floating objects 1
clip*, # Sets or returns which part of a positioned element is visible 2
color*, # Sets or returns the color of the text 1
columnCount*, # Sets or returns the number of columns an element should be divided into 3
columnFill*, # Sets or returns how to fill columns 3
columnGap*, # Sets or returns the gap between the columns 3
columnRule*, # A shorthand property for setting or returning all the columnRule properties 3
columnRuleColor*, # Sets or returns the color of the rule between columns 3
columnRuleStyle*, # Sets or returns the style of the rule between columns 3
columnRuleWidth*, # Sets or returns the width of the rule between columns 3
columns*, # A shorthand property for setting or returning columnWidth and columnCount 3
columnSpan*, # Sets or returns how many columns an element should span across 3
columnWidth*, # Sets or returns the width of the columns 3
content*, # Used with the :before and :after pseudo-elements, to insert generated content 2
counterIncrement*, # Increments one or more counters 2
counterReset*, # Creates or resets one or more counters 2
cursor*, # Sets or returns the type of cursor to display for the mouse pointer 2
direction*, # Sets or returns the text direction 2
display*, # Sets or returns an element's display type 1
emptyCells*, # Setsor returns whether to show the border and background of empty cells, or not 2
filter*, # Setsor returns image filters (visual effects, like blur and saturation) 3
flex*, # Setsor returns the length of the item, relative to the rest 3
flexBasis*, # Setsor returns the initial length of a flexible item 3
flexDirection*, # Setsor returns the direction of the flexible items 3
flexFlow*, # A shorthand property for the flexDirection and the flexWrap properties 3
flexGrow*, # Setsor returns how much the item will grow relative to the rest 3
flexShrink*, # Setsor returns how the item will shrink relative to the rest 3
flexWrap*, # Setsor returns whether the flexible items should wrap or not 3
cssFloat*, # Setsor returns the horizontal alignment of an element 1
font*, # Setsor returns fontStyle, fontVariant, fontWeight, fontSize, lineHeight, and fontFamily in one declaration 1
fontFamily*, # Setsor returns the font family for text 1
fontSize*, # Setsor returns the font size of the text 1
fontStyle*, # Setsor returns whether the style of the font is normal, italic or oblique 1
fontVariant*, # Setsor returns whether the font should be displayed in small capital letters 1
fontWeight*, # Setsor returns the boldness of the font 1
fontSizeAdjust*, # Preserves the readability of text when font fallback occurs 3
fontStretch*, # Selects a normal, condensed, or expanded face from a font family 3
hangingPunctuation*, # Specifies whether a punctuation character may be placed outside the line box 3
height*, # Setsor returns the height of an element 1
hyphens*, # Setshow to split words to improve the layout of paragraphs 3
icon*, # Provides the author the ability to style an element with an iconic equivalent 3
imageOrientation*, # Specifies a rotation in the right or clockwise direction that a user agent applies to an image 3
isolation*, # Defines whether an element must create a new stacking content 3
justifyContent*, # Setsor returns the alignment between the items inside a flexible container when the items do not use all available space. 3
left*, # Setsor returns the left position of a positioned element 2
letterSpacing*, # Setsor returns the space between characters in a text 1
lineHeight*, # Setsor returns the distance between lines in a text 1
listStyle*, # Setsor returns listStyleImage, listStylePosition, and listStyleType in one declaration 1
listStyleImage*, # Setsor returns an image as the list-item marker 1
listStylePosition*, # Setsor returns the position of the list-item marker 1
listStyleType*: cstring # Setsor returns the list-item marker type 1
margin*, # Setsor returns the margins of an element (can have up to four values) 1
marginBottom*, # Setsor returns the bottom margin of an element 1
marginLeft*, # Setsor returns the left margin of an element 1
marginRight*, # Setsor returns the right margin of an element 1
marginTop*, # Setsor returns the top margin of an element 1
maxHeight*, # Setsor returns the maximum height of an element 2
maxWidth*, # Setsor returns the maximum width of an element 2
minHeight*, # Setsor returns the minimum height of an element 2
minWidth*: cint # Setsor returns the minimum width of an element 2
# navDown*, # Setsor returns where to navigate when using the arrow-down navigation key 3
# navIndex*, # Setsor returns the tabbing order for an element 3
# navLeft*, # Setsor returns where to navigate when using the arrow-left navigation key 3
# navRight*, # Setsor returns where to navigate when using the arrow-right navigation key 3
# navUp*, # Setsor returns where to navigate when using the arrow-up navigation key 3
# objectFit*, # Specifies how the contents of a replaced element should be fitted to the box established by its used height and width 3
# objectPosition*, # Specifies the alignment of the replaced element inside its box 3
# opacity*, # Setsor returns the opacity level for an element 3
# order*, # Setsor returns the order of the flexible item, relative to the rest 3
# orphans*, # Setsor returns the minimum number of lines for an element that must be left at the bottom of a page when a page break occurs inside an element 2
# outline*, # Setsor returns all the outline properties in one declaration 2
# outlineColor*, # Setsor returns the color of the outline around a element 2
# outlineOffset*, # Setsan outline, and draws it beyond the border edge 3
# outlineStyle*, # Setsor returns the style of the outline around an element 2
# outlineWidth*, # Setsor returns the width of the outline around an element 2
# overflow*, # Setsor returns what to do with content that renders outside the element box 2
# overflowX*, # Specifies what to do with the left/right edges of the content, if it overflows the element's content area 3
# overflowY*, # Specifies what to do with the top/bottom edges of the content, if it overflows the element's content area 3
# padding*, # Setsor returns the padding of an element (can have up to four values) 1
# paddingBottom*, # Setsor returns the bottom padding of an element 1
# paddingLeft*, # Setsor returns the left padding of an element 1
# paddingRight*, # Setsor returns the right padding of an element 1
# paddingTop*, # Setsor returns the top padding of an element 1
# pageBreakAfter*, # Setsor returns the page-break behavior after an element 2
# pageBreakBefore*, # Setsor returns the page-break behavior before an element 2
# pageBreakInside*, # Setsor returns the page-break behavior inside an element 2
# perspective*, # Setsor returns the perspective on how 3D elements are viewed 3
# perspectiveOrigin*, # Setsor returns the bottom position of 3D elements 3
# position*, # Setsor returns the type of positioning method used for an element (static, relative, absolute or fixed) 2
# quotes*, # Setsor returns the type of quotation marks for embedded quotations 2
# resize*, # Setsor returns whether or not an element is resizable by the user 3
# right*, # Setsor returns the right position of a positioned element 2
# tableLayout*, # Setsor returns the way to lay out table cells, rows, and columns 2
# tabSize*, # Setsor returns the length of the tab-character 3
# textAlign*, # Setsor returns the horizontal alignment of text 1
# textAlignLast*, # Setsor returns how the last line of a block or a line right before a forced line break is aligned when text-align is "justify" 3
# textDecoration*, # Setsor returns the decoration of a text 1
# textDecorationColor*, # Setsor returns the color of the text-decoration 3
# textDecorationLine*, # Setsor returns the type of line in a text-decoration 3
# textDecorationStyle*, # Setsor returns the style of the line in a text decoration 3
# textIndent*, # Setsor returns the indentation of the first line of text 1
# textJustify*, # Setsor returns the justification method used when text-align is "justify" 3
# textOverflow*, # Setsor returns what should happen when text overflows the containing element 3
# textShadow*, # Setsor returns the shadow effect of a text 3
# textTransform*, # Setsor returns the capitalization of a text 1
# top*, # Setsor returns the top position of a positioned element 2
# transform*, # Applies a 2D or 3D transformation to an element 3
# transformOrigin*, # Setsor returns the position of transformed elements 3
# transformStyle*, # Setsor returns how nested elements are rendered in 3D space 3
# transition*, # A shorthand property for setting or returning the four transition properties 3
# transitionProperty*, # Setsor returns the CSS property that the transition effect is for 3
# transitionDuration*, # Setsor returns how many seconds or milliseconds a transition effect takes to complete 3
# transitionTimingFunction*, # Setsor returns the speed curve of the transition effect 3
# transitionDelay*, # Setsor returns when the transition effect will start 3
# unicodeBidi*, # Setsor returns whether the text should be overridden to support multiple languages in the same document 2
# userSelect*, # Setsor returns whether the text of an element can be selected or not 2
# verticalAlign*, # Setsor returns the vertical alignment of the content in an element 1
# visibility*, # Setsor returns whether an element should be visible 2
# whiteSpace*, # Setsor returns how to handle tabs, line breaks and whitespace in a text 1
# width*, # Setsor returns the width of an element 1
# wordBreak*, # Setsor returns line breaking rules for non-CJK scripts 3
# wordSpacing*, # Setsor returns the spacing between words in a text 1
# wordWrap*, # Allows long, unbreakable words to be broken and wrap to the next line 3
# widows*, # Setsor returns the minimum number of lines for an element that must be visible at the top of a page 2
# zIndex*: cstring # Setsor returns the stack order of a positioned element 2

View File

@@ -0,0 +1,58 @@
import jsffi, react_styles
type
Context*{.importc.} = JsObject
Consumer*{.importc.} = JsObject
Producer*{.importc.} = JsObject
ReactGlobal* {.importc.} = ref object of RootObj
version*: cstring
ReactDOMGlobal* {.importc.} = ref object of RootObj
version*: cstring
ReactDescriptor* [P, S] {.importcpp.} = ref object of RootObj
render*: proc(): ReactNode
componentWillMount*: proc(): void
componentWillUnmount*: proc(): void
componentDidMount*: proc(): void
componentWillReceiveProps*: proc(nextProps: P): void
shouldComponentUpdate*: proc(nextProps: P, nextState: S): bool
componentWillUpdate*: proc(nextProps: P, nextState: S): bool
componentDidUpdate*: proc(prevProps: P, prevState: S): bool
getInitialState*: proc(): S
ReactComponent* {.importc.} = ref object of RootObj
ReactNode* {.importc.} = ref object of RootObj
EventTarget* = ref object
value*: cstring
Event* = ref object
target*: EventTarget
`type`*: cstring
Attrs* = ref object of RootObj
onClick*, onChange*: proc(e: Event)
key*, `ref`*, dangerouslySetInnerHTML*: cstring
accept*, acceptCharset*, accessKey*, action*, alt*, capture*,
cellPadding*, cellSpacing*, challenge*, charSet*, cite*, classID*,
className*, content*, contextMenu*, coords*, crossOrigin*,
data*, dateTime*, default*, dir*, download*, encType*, form*,
formAction*, formEncType*, formMethod*, formTarget*, frameBorder*,
headers*, href*, hrefLang*, htmlFor*, httpEquiv*, icon*, id*, inputMode*,
integrity*, keyParams*, keyType*, kind*, label*, lang*, list*,
manifest*, media*, mediaGroup*, `method`*, name*, nonce*, pattern*,
placeholder*, poster*, profile*, radioGroup*, rel*, role*, sandbox*,
scope*, scrolling*, seamless*, shape*, sizes*, span*, src*, srcDoc*,
srcLang*, srcSet*, summary*, tabIndex*, target*, title*, `type`*,
useMap*, value*, wmode*, wrap*: cstring
allowFullScreen*, allowTransparency*, async*, autoComplete*, autoFocus*,
autoPlay*, checked*, contentEditable*, controls*, `defer`*, disabled*,
draggable*, formNoValidate*, hidden*, loop*, multiple*, muted*,
noValidate*, open*, preload*, readOnly*, required*, reversed*,
scoped*, selected*, spellCheck*: bool
colSpan*, cols*, height*, high*, low*, marginHeight*, marginWidth*, max*,
maxLength*, min*, minLength*, optimum*, rowSpan*, rows*, size*, start*,
step*, width*: cint
style*: react_styles.Style
# Style* = ref object
# color*, backgroundColor*: cstring
# marginTop*, marginBottom*, marginLeft*, marginRight*: int

33
src/js/example/index.html Normal file
View File

@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Nim on JS</title>
</head>
<body onload="startApp()">
<div id="app" class="container"></div>
<!-- React -->
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<!-- React Wrapper Helpers for nim -->
<script>
function myUseState(state) {
const [getter, setter] = React.useState(state);
return { getter, setter };
}
</script>
<!-- Nim App -->
<script src="sandbox.js"></script>
<script>
function startApp() {
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(React.createElement(makeTopLevel))
}
</script>
</body>
</html>

1
src/js/example/nim.cfg Normal file
View File

@@ -0,0 +1 @@
path=".."

View File

@@ -0,0 +1,10 @@
{
"name": "org",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"react": "^18.1.0",
"react-dom": "^18.1.0"
}
}

View File

@@ -0,0 +1,48 @@
import jsconsole, jsffi, strutils, sequtils, sugar
import sugar
import ../bindings/react/react_dom,
../bindings/react/react_types,
../bindings/react/react_styles,
../bindings/react/react_hooks
import sequtils
import options
import strformat
import ../../org/org_block_heading
import ../../org/org_builder
import ../../org/org_types
proc renderItems(
onClick: proc(e: react_types.Event): void,
count: Option[int],
): ReactNode =
`div`(
Attrs{
onClick: onclick
},
&"Add button {count.get(0)}"
)
proc makeTopLevel(): ReactNode {.exportc.} =
let text = myUseState[cstring]("")
let val = text.getter
let orgItems: seq[string] = makeOrg($val)
.foldOrg()
console.log(orgItems)
`div`(
Attrs{style: Style{marginTop: 50}},
@[
textarea(
Attrs{
onchange: proc(e: react_types.Event): void = discard text.setter(e.target.value)
},
),
`div`(
Attrs{},
$orgItems
)
]
)

37
src/js/example/yarn.lock Normal file
View File

@@ -0,0 +1,37 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"js-tokens@^3.0.0 || ^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
loose-envify@^1.1.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
react-dom@^18.1.0:
version "18.1.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.1.0.tgz#7f6dd84b706408adde05e1df575b3a024d7e8a2f"
integrity sha512-fU1Txz7Budmvamp7bshe4Zi32d0ll7ect+ccxNu9FlObT605GOEB8BfO4tmRJ39R5Zj831VCpvQ05QPBW5yb+w==
dependencies:
loose-envify "^1.1.0"
scheduler "^0.22.0"
react@^18.1.0:
version "18.1.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.1.0.tgz#6f8620382decb17fdc5cc223a115e2adbf104890"
integrity sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ==
dependencies:
loose-envify "^1.1.0"
scheduler@^0.22.0:
version "0.22.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.22.0.tgz#83a5d63594edf074add9a7198b1bae76c3db01b8"
integrity sha512-6QAm1BgQI88NPYymgGQLCZgvep4FyePDWFpXVK+zNSUgHwlqpJy8VEh8Et0KxTACS4VWwMousBElAZOH9nkkoQ==
dependencies:
loose-envify "^1.1.0"

26
src/org/index.html Normal file
View File

@@ -0,0 +1,26 @@
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Untitled</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<!-- Place favicon.ico in the root directory -->
</head>
<body>
<!--[if lt IE 8]>
<p class="browserupgrade">
You are using an <strong>outdated</strong> browser. Please
<a href="http://browsehappy.com/">upgrade your browser</a> to improve
your experience.
</p>
<![endif]-->
<script type="text/javascript" src="./org_block_heading.js"></script>
</body>
</html>

5539
src/org/org_block_heading.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -32,7 +32,7 @@ let parseTodoKeyword = todoKeywords.createTodoKeywordParser()
let parseDoneKeyword = doneKeywords.createTodoKeywordParser()
let parseContentText = @[
anyUntil(choice(@[endOfStream, str("\n*")])),
anyUntilPerformant(choice(@[endOfStream, str("\n*")])),
]
let parseHeadlineNewline = @[
@@ -40,7 +40,7 @@ let parseHeadlineNewline = @[
]
let parseHeadingText = @[
anyUntil(newline),
anyUntilPerformant(newline),
]
# func buildStars(token: seq[ParserToken]): seq[ParserToken] =
@@ -71,7 +71,7 @@ let buildHeadlineContent = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlo
let buildHeadlineChildren = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}=
# let headlineString = tokens.tokensToString()
org.headlineChildrenText = tokens.tokensToString()
# org.headlineChildrenText = tokens.tokensToString()
org
let buildHeadlineNewline = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}=
@@ -92,26 +92,20 @@ proc tryBuildHeading(builder: OrgBuilderResult): OrgBuilderResult =
(parseContentText, buildHeadlineChildren, true),
(parseHeadlineNewline, buildHeadlineContent, true),
(parseHeadlineNewline, buildHeadlineNewline, true),
(parseHeadlineNewline, buildHeadlineNewline, false),
]
)
when isMainModule:
var acc = initOrgBuilder("""* TODO Level 1
** TODO Level 2
""")
proc makeOrg*(x: string): OrgBuilderResult =
var acc = initOrgBuilder(x)
while acc.isOk() and acc.tryParser(endOfStream).isErr():
let unsafeAcc = acc.unsafeGet()
let item = acc
.tryBuildHeading()
.fold(
err => OrgBuilderResult.err((unsafeAcc, "Error")),
.flatMap(
(x: OrgBuilder) => OrgBuilderResult.ok(OrgBuilder((
parser: x.parser,
tree: unsafeAcc.tree & x.tree,
@@ -120,35 +114,34 @@ when isMainModule:
acc = item
echo acc
acc
# let sampleBuilder = StringBuilderResult
# .ok(StringBuilder((
# parser: initParser("""**** TODO Some stars
# :PROPERTIES:
# :PROP_NAME: Value
# :PROP_NAME: Value
# :PROP_NAME: Value
# :PROP_NAME: Value
# :PROPERTIES_END:
proc foldOrg*(x: OrgBuilderResult): seq[string] =
x
.fold(
(err) => @["Error"],
(builder: OrgBuilder) => builder.tree.map((x: OrgBlock) => $x.headlineContent),
)
# echo acc.unsafeGet().tree[^1]
# Foo
# """),
# tree: newSeq[StringBuilderT](),
# )))
# .applyParsersSeq(@[
# (parseHeadingStars, stringConcat("Stars: ")),
when isMainModule:
# import nimprof
# import timeit
let test1 = """* TODO Level 1
Some stuff inbetween
# (@[optional(parseTodoKeyword)], stringConcat("TODO: ")),
# (@[optional(parseDoneKeyword)], stringConcat("DONE: ")),
** DONE Level 2 """
# (parseHeadingText, stringConcat("Text: ")),
# (parseProperties, stringConcat("Properties: ", seperator = ", ")),
# # (@[optional(choice(parseProperties))], stringConcat("Properties: ")),
# ])
# .foldBuilder(
# err => &"Error Parsing: {err}",
# xs => "Parser Succesfull:\n" & xs.join("\n"),
# )
let test1_2 = """* TODO Failing
# echo sampleBuilder
*
** Level 2"""
# let test2 = readFile("/home/floscr/Documents/Org/Bookmarks/bookmarks.org")
# let test2 = readFile("/tmp/gtd.org")
var acc = makeOrg(test1)
echo acc .foldOrg()
# echo acc.unsafeGet().tree[^1]

View File

@@ -108,6 +108,32 @@ func ignore*(parserFn: Parser -> ParserResult): (Parser -> ParserResult) {.inlin
tokens: parser.tokens,
))
func manyUntilPerformant*(acceptFn: Parser -> ParserResult, stopFn: Parser -> ParserResult): (Parser -> ParserResult) {.inline.} =
## Parse characters but throw success tokens away
return proc(parser: Parser): ParserResult =
let startPosition = parser.state.position
var res: ParserResult = parser.ok()
while res.isOk() and res.flatMap(stopFn).isErr():
res = res.flatMap(acceptFn)
return res.map((p: Parser) => Parser(
state: ParserState(
stream: p.state.stream,
position: p.state.position,
lastPosition: p.state.lastPosition,
),
tokens: @[
ParserToken(
kind: parserTokenString,
stringValue: p.state.stream[(startPosition - 1)..p.state.position],
)
]
))
proc anyUntilPerformant*(stopFn: Parser -> ParserResult): (Parser -> ParserResult) {.inline.} =
manyUntilPerformant(anyCh, stopFn)
func manyUntil*(acceptFn: Parser -> ParserResult, stopFn: Parser -> ParserResult): (Parser -> ParserResult) {.inline.} =
## Parse characters but throw success tokens away
return proc(parser: Parser): ParserResult =