Merge branch 'master' of git://factorcode.org/git/factor
commit
583673afa8
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2008 Doug Coleman.
|
! Copyright (C) 2008 Doug Coleman.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: classes kernel help.markup help.syntax sequences
|
USING: classes kernel help.markup help.syntax sequences
|
||||||
alien assocs strings math multiline ;
|
alien assocs strings math multiline quotations ;
|
||||||
IN: db
|
IN: db
|
||||||
|
|
||||||
HELP: db
|
HELP: db
|
||||||
|
@ -45,7 +45,22 @@ HELP: prepared-statement
|
||||||
{ $description } ;
|
{ $description } ;
|
||||||
|
|
||||||
HELP: result-set
|
HELP: result-set
|
||||||
{ $description } ;
|
{ $description "An object encapsulating a raw SQL result object. There are two ways in which a result set can be accessed, but they are specific to the database backend in use."
|
||||||
|
{ $subsection "db-random-access-result-set" }
|
||||||
|
{ $subsection "db-sequential-result-set" }
|
||||||
|
} ;
|
||||||
|
|
||||||
|
HELP: init-result-set
|
||||||
|
{ $values
|
||||||
|
{ "result-set" result-set } }
|
||||||
|
{ $description "" } ;
|
||||||
|
|
||||||
|
HELP: new-result-set
|
||||||
|
{ $values
|
||||||
|
{ "query" "a query" } { "handle" alien } { "class" class }
|
||||||
|
{ "result-set" result-set } }
|
||||||
|
{ $description "Creates a new " { $link result-set } " object of type " { $snippet "class" } "." } ;
|
||||||
|
|
||||||
|
|
||||||
HELP: new-statement
|
HELP: new-statement
|
||||||
{ $values { "sql" string } { "in" sequence } { "out" sequence } { "class" class } { "statement" statement } }
|
{ $values { "sql" string } { "in" sequence } { "out" sequence } { "class" class } { "statement" statement } }
|
||||||
|
@ -81,7 +96,7 @@ HELP: query-results
|
||||||
{ $values { "query" object }
|
{ $values { "query" object }
|
||||||
{ "result-set" result-set }
|
{ "result-set" result-set }
|
||||||
}
|
}
|
||||||
{ $description "" } ;
|
{ $description "Returns a " { $link result-set } " object representing the reults of a SQL query." } ;
|
||||||
|
|
||||||
HELP: #rows
|
HELP: #rows
|
||||||
{ $values { "result-set" result-set } { "n" integer } }
|
{ $values { "result-set" result-set } { "n" integer } }
|
||||||
|
@ -95,32 +110,119 @@ HELP: row-column
|
||||||
{ $values { "result-set" result-set } { "column" integer }
|
{ $values { "result-set" result-set } { "column" integer }
|
||||||
{ "obj" object }
|
{ "obj" object }
|
||||||
}
|
}
|
||||||
{ $description "" } ;
|
{ $description "Returns the value indexed by " { $snippet "column" } " in the current row of a " { $link result-set } "." } ;
|
||||||
|
|
||||||
HELP: row-column-typed
|
HELP: row-column-typed
|
||||||
{ $values { "result-set" result-set } { "column" integer }
|
{ $values { "result-set" result-set } { "column" integer }
|
||||||
{ "sql" "sql" } }
|
{ "sql" "sql" } }
|
||||||
{ $description "" } ;
|
{ $description "Returns the value indexed by " { $snippet "column" } " in the current row of a " { $link result-set } " and converts the result based on a type stored in the " { $link result-set } "'s " { $slot "out-params" } "." } ;
|
||||||
|
|
||||||
HELP: advance-row
|
HELP: advance-row
|
||||||
{ $values { "result-set" result-set } }
|
{ $values { "result-set" result-set } }
|
||||||
;
|
{ $description "Advanced the pointer to an underlying SQL result set stored in a " { $link result-set } " object." } ;
|
||||||
|
|
||||||
HELP: more-rows?
|
HELP: more-rows?
|
||||||
{ $values { "result-set" result-set } { "?" "a boolean" } }
|
{ $values { "result-set" result-set } { "?" "a boolean" } }
|
||||||
;
|
{ $description "Returns true if the " { $link result-set } " has more rows to traverse." } ;
|
||||||
|
|
||||||
HELP: execute-statement*
|
HELP: execute-statement*
|
||||||
{ $values { "statement" statement } { "type" object } }
|
{ $values { "statement" statement } { "type" object } }
|
||||||
{ $description } ;
|
{ $description } ;
|
||||||
|
|
||||||
|
HELP: execute-one-statement
|
||||||
|
{ $values
|
||||||
|
{ "statement" null } }
|
||||||
|
{ $description "" } ;
|
||||||
|
|
||||||
HELP: execute-statement
|
HELP: execute-statement
|
||||||
{ $values { "statement" statement } }
|
{ $values { "statement" statement } }
|
||||||
{ $description } ;
|
{ $description "" } ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
HELP: begin-transaction
|
||||||
|
{ $description "Begins a new transaction. User code should make use of the " { $link with-transaction } " combinator." } ;
|
||||||
|
|
||||||
|
HELP: bind-statement
|
||||||
|
{ $values
|
||||||
|
{ "obj" object } { "statement" null } }
|
||||||
|
{ $description "" } ;
|
||||||
|
|
||||||
|
HELP: commit-transaction
|
||||||
|
{ $description "Commits a transaction. User code should make use of the " { $link with-transaction } " combinator." } ;
|
||||||
|
|
||||||
|
HELP: default-query
|
||||||
|
{ $values
|
||||||
|
{ "query" null }
|
||||||
|
{ "result-set" null } }
|
||||||
|
{ $description "" } ;
|
||||||
|
|
||||||
|
HELP: in-transaction
|
||||||
|
{ $description "A variable that is set true when a transaction is in progress." } ;
|
||||||
|
|
||||||
|
HELP: in-transaction?
|
||||||
|
{ $values
|
||||||
|
{ "?" "a boolean" } }
|
||||||
|
{ $description "Returns true if there is currently a transaction in progress in this scope." } ;
|
||||||
|
|
||||||
|
HELP: query-each
|
||||||
|
{ $values
|
||||||
|
{ "statement" null } { "quot" quotation } }
|
||||||
|
{ $description "" } ;
|
||||||
|
|
||||||
|
HELP: query-map
|
||||||
|
{ $values
|
||||||
|
{ "statement" null } { "quot" quotation }
|
||||||
|
{ "seq" sequence } }
|
||||||
|
{ $description "" } ;
|
||||||
|
|
||||||
|
HELP: rollback-transaction
|
||||||
|
{ $description "Rolls back a transaction; no data is committed to the database. User code should make use of the " { $link with-transaction } " combinator." } ;
|
||||||
|
|
||||||
|
HELP: sql-command
|
||||||
|
{ $values
|
||||||
|
{ "sql" string } }
|
||||||
|
{ $description "Executes a SQL string using the databse in the " { $link db } " symbol." } ;
|
||||||
|
|
||||||
|
HELP: sql-query
|
||||||
|
{ $values
|
||||||
|
{ "sql" string }
|
||||||
|
{ "rows" "an array of arrays of strings" } }
|
||||||
|
{ $description "Runs a SQL query of raw text in the database in the " { $link db } " symbol. Each row is returned as an array of strings; no type-conversions are done on the resulting data." } ;
|
||||||
|
|
||||||
|
{ sql-command sql-query } related-words
|
||||||
|
|
||||||
|
HELP: sql-row
|
||||||
|
{ $values
|
||||||
|
{ "result-set" result-set }
|
||||||
|
{ "seq" sequence } }
|
||||||
|
{ $description "Returns the current row in a " { $link result-set } " as an array of strings." } ;
|
||||||
|
|
||||||
|
HELP: sql-row-typed
|
||||||
|
{ $values
|
||||||
|
{ "result-set" result-set }
|
||||||
|
{ "seq" sequence } }
|
||||||
|
{ $description "Returns the current row in a " { $link result-set } " as an array of typed Factor objects." } ;
|
||||||
|
|
||||||
|
{ sql-row sql-row-typed } related-words
|
||||||
|
|
||||||
|
HELP: with-db
|
||||||
|
{ $values
|
||||||
|
{ "seq" sequence } { "class" class } { "quot" quotation } }
|
||||||
|
{ $description "Calls the quotation with a database bound to the " { $link db } " symbol. The database called is based on the " { $snippet "class" } " with the " } ;
|
||||||
|
|
||||||
|
HELP: with-transaction
|
||||||
|
{ $values
|
||||||
|
{ "quot" quotation } }
|
||||||
|
{ $description "" } ;
|
||||||
|
|
||||||
ARTICLE: "db" "Database library"
|
ARTICLE: "db" "Database library"
|
||||||
{ $subsection "db-custom-database-combinators" }
|
{ $subsection "db-custom-database-combinators" }
|
||||||
{ $subsection "db-protocol" }
|
{ $subsection "db-protocol" }
|
||||||
|
{ $subsection "db-result-sets" }
|
||||||
{ $subsection "db-lowlevel-tutorial" }
|
{ $subsection "db-lowlevel-tutorial" }
|
||||||
"Higher-level database:"
|
"Higher-level database:"
|
||||||
{ $vocab-subsection "Database types" "db.types" }
|
{ $vocab-subsection "Database types" "db.types" }
|
||||||
|
@ -135,6 +237,40 @@ ARTICLE: "db" "Database library"
|
||||||
{ $subsection "db-porting-the-library" }
|
{ $subsection "db-porting-the-library" }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
ARTICLE: "db-random-access-result-set" "Random access result sets"
|
||||||
|
"Random-access result sets do not have to be traversed in order. For instance, PostgreSQL's result set object can be accessed as a matrix with i,j coordinates."
|
||||||
|
$nl
|
||||||
|
"Databases which work in this way must provide methods for the following traversal words:"
|
||||||
|
{ $subsection #rows }
|
||||||
|
{ $subsection #columns }
|
||||||
|
{ $subsection row-column }
|
||||||
|
{ $subsection row-column-typed } ;
|
||||||
|
|
||||||
|
ARTICLE: "db-sequential-result-set" "Sequential result sets"
|
||||||
|
"Sequential result sets can be iterated one element after the next. SQLite's result sets offer this method of traversal."
|
||||||
|
$nl
|
||||||
|
"Databases which work in this way must provide methods for the following traversal words:"
|
||||||
|
{ $subsection more-rows? }
|
||||||
|
{ $subsection advance-row }
|
||||||
|
{ $subsection row-column }
|
||||||
|
{ $subsection row-column-typed } ;
|
||||||
|
|
||||||
|
ARTICLE: "db-result-sets" "Result sets"
|
||||||
|
"Result sets are the encapsulated, database-specific results from a SQL query."
|
||||||
|
$nl
|
||||||
|
"Two possible protocols for iterating over result sets exist:"
|
||||||
|
{ $subsection "db-random-access-result-set" }
|
||||||
|
{ $subsection "db-sequential-result-set" }
|
||||||
|
"Query the number of rows or columns:"
|
||||||
|
{ $subsection #rows }
|
||||||
|
{ $subsection #columns }
|
||||||
|
"Traversing a result set:"
|
||||||
|
{ $subsection advance-row }
|
||||||
|
{ $subsection more-rows? }
|
||||||
|
"Pulling out a single row of results:"
|
||||||
|
{ $subsection row-column }
|
||||||
|
{ $subsection row-column-typed } ;
|
||||||
|
|
||||||
ARTICLE: "db-protocol" "Low-level database protocol"
|
ARTICLE: "db-protocol" "Low-level database protocol"
|
||||||
"The high-level protocol (see " { $vocab-link "db.tuples" } ") uses this low-level protocol for executing statements and queries."
|
"The high-level protocol (see " { $vocab-link "db.tuples" } ") uses this low-level protocol for executing statements and queries."
|
||||||
;
|
;
|
||||||
|
@ -157,7 +293,6 @@ USING: db.sqlite db io.files ;
|
||||||
{ "my-database.db" temp-file } sqlite-db rot with-db ;
|
{ "my-database.db" temp-file } sqlite-db rot with-db ;
|
||||||
"> }
|
"> }
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
ABOUT: "db"
|
ABOUT: "db"
|
||||||
|
|
|
@ -80,11 +80,14 @@ GENERIC: execute-statement* ( statement type -- )
|
||||||
M: object execute-statement* ( statement type -- )
|
M: object execute-statement* ( statement type -- )
|
||||||
drop query-results dispose ;
|
drop query-results dispose ;
|
||||||
|
|
||||||
|
: execute-one-statement ( statement -- )
|
||||||
|
dup type>> execute-statement* ;
|
||||||
|
|
||||||
: execute-statement ( statement -- )
|
: execute-statement ( statement -- )
|
||||||
dup sequence? [
|
dup sequence? [
|
||||||
[ execute-statement ] each
|
[ execute-one-statement ] each
|
||||||
] [
|
] [
|
||||||
dup type>> execute-statement*
|
execute-one-statement
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
: bind-statement ( obj statement -- )
|
: bind-statement ( obj statement -- )
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2008 Doug Coleman.
|
! Copyright (C) 2008 Doug Coleman.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: classes help.markup help.syntax io.streams.string kernel
|
USING: classes help.markup help.syntax io.streams.string kernel
|
||||||
quotations sequences strings multiline math ;
|
quotations sequences strings multiline math db.types ;
|
||||||
IN: db.tuples
|
IN: db.tuples
|
||||||
|
|
||||||
HELP: define-persistent
|
HELP: define-persistent
|
||||||
|
|
|
@ -518,6 +518,7 @@ string-encoding-test "STRING_ENCODING_TEST" {
|
||||||
! [ ] [ T{ exam f f "Kenny" 60 } insert-tuple ] unit-test
|
! [ ] [ T{ exam f f "Kenny" 60 } insert-tuple ] unit-test
|
||||||
! [ ] [ T{ exam f f "Cartman" 41 } insert-tuple ] unit-test
|
! [ ] [ T{ exam f f "Cartman" 41 } insert-tuple ] unit-test
|
||||||
[ ] [ 10 [ random-exam insert-tuple ] times ] unit-test
|
[ ] [ 10 [ random-exam insert-tuple ] times ] unit-test
|
||||||
|
[ 5 ] [ <query> T{ exam { score T{ interval { from { 0 t } } { to { 100 t } } } } } >>tuple 5 >>limit select-tuples length ] unit-test
|
||||||
! [ ] [ T{ exam { name "Kenny" } } >query ] unit-test
|
! [ ] [ T{ exam { name "Kenny" } } >query ] unit-test
|
||||||
! [ ] [ query ] unit-test
|
! [ ] [ query ] unit-test
|
||||||
;
|
;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
USING: arrays assocs classes db kernel namespaces
|
USING: arrays assocs classes db kernel namespaces
|
||||||
classes.tuple words sequences slots math accessors
|
classes.tuple words sequences slots math accessors
|
||||||
math.parser io prettyprint db.types continuations
|
math.parser io prettyprint db.types continuations
|
||||||
destructors mirrors sets ;
|
destructors mirrors sets db.types ;
|
||||||
IN: db.tuples
|
IN: db.tuples
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
! Copyright (C) 2008 Doug Coleman.
|
! Copyright (C) 2008 Doug Coleman.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: classes hashtables help.markup help.syntax io.streams.string kernel sequences strings ;
|
USING: classes hashtables help.markup help.syntax io.streams.string
|
||||||
|
kernel sequences strings math ;
|
||||||
IN: db.types
|
IN: db.types
|
||||||
|
|
||||||
HELP: (lookup-type)
|
|
||||||
{ $values
|
|
||||||
{ "obj" object }
|
|
||||||
{ "string" string } }
|
|
||||||
{ $description "" } ;
|
|
||||||
|
|
||||||
HELP: +autoincrement+
|
HELP: +autoincrement+
|
||||||
{ $description "" } ;
|
{ $description "" } ;
|
||||||
|
|
||||||
|
@ -55,7 +50,7 @@ HELP: <low-level-binding>
|
||||||
{ $description "" } ;
|
{ $description "" } ;
|
||||||
|
|
||||||
HELP: BIG-INTEGER
|
HELP: BIG-INTEGER
|
||||||
{ $description "A 64-bit integer." } ;
|
{ $description "A 64-bit integer. Whether this number is signed or unsigned depends on the database backend." } ;
|
||||||
|
|
||||||
HELP: BLOB
|
HELP: BLOB
|
||||||
{ $description "A serialized Factor object. The database library automatically serializes the object for a SQL insert or update and deserializes it on a tuple query." } ;
|
{ $description "A serialized Factor object. The database library automatically serializes the object for a SQL insert or update and deserializes it on a tuple query." } ;
|
||||||
|
@ -73,13 +68,13 @@ HELP: DOUBLE
|
||||||
{ $description "Corresponds to Factor's 64bit floating-point numbers." } ;
|
{ $description "Corresponds to Factor's 64bit floating-point numbers." } ;
|
||||||
|
|
||||||
HELP: FACTOR-BLOB
|
HELP: FACTOR-BLOB
|
||||||
{ $description "" } ;
|
{ $description "A serialized Factor object." } ;
|
||||||
|
|
||||||
HELP: INTEGER
|
HELP: INTEGER
|
||||||
{ $description "" } ;
|
{ $description "A small integer, at least 32 bits in length. Whether this number is signed or unsigned depends on the database backend." } ;
|
||||||
|
|
||||||
HELP: NULL
|
HELP: NULL
|
||||||
{ $description "" } ;
|
{ $description "The SQL null type." } ;
|
||||||
|
|
||||||
HELP: REAL
|
HELP: REAL
|
||||||
{ $description "" } ;
|
{ $description "" } ;
|
||||||
|
@ -94,16 +89,18 @@ HELP: TIME
|
||||||
{ $description "" } ;
|
{ $description "" } ;
|
||||||
|
|
||||||
HELP: TIMESTAMP
|
HELP: TIMESTAMP
|
||||||
{ $description "" } ;
|
{ $description "A Factor timestamp." } ;
|
||||||
|
|
||||||
HELP: UNSIGNED-BIG-INTEGER
|
HELP: UNSIGNED-BIG-INTEGER
|
||||||
{ $description "" } ;
|
{ $description "For portability, if a number is known to be 64bit, then this datatype may be used. Some databases, like SQLite, cannot store arbitrary bignums as BIGINT types. If storing arbitrary bignums, use " { $link FACTOR-BLOB } "." } ;
|
||||||
|
|
||||||
|
{ INTEGER SIGNED-BIG-INTEGER UNSIGNED-BIG-INTEGER } related-words
|
||||||
|
|
||||||
HELP: URL
|
HELP: URL
|
||||||
{ $description "" } ;
|
{ $description "A Factor " { $link "urls" } " object." } ;
|
||||||
|
|
||||||
HELP: VARCHAR
|
HELP: VARCHAR
|
||||||
{ $description "" } ;
|
{ $description "The SQL varchar type. This type can take an integer as an argument." } ;
|
||||||
|
|
||||||
HELP: assigned-id-spec?
|
HELP: assigned-id-spec?
|
||||||
{ $values
|
{ $values
|
||||||
|
@ -135,18 +132,19 @@ HELP: db-assigned-id-spec?
|
||||||
|
|
||||||
HELP: find-primary-key
|
HELP: find-primary-key
|
||||||
{ $values
|
{ $values
|
||||||
{ "specs" null }
|
{ "specs" "an array of sql-specs" }
|
||||||
{ "obj" object } }
|
{ "obj" object } }
|
||||||
{ $description "" } ;
|
{ $description "Returns the row from the sql-specs array." }
|
||||||
|
{ $notes "This is a low-level word." } ;
|
||||||
|
|
||||||
HELP: generator-bind
|
HELP: generator-bind
|
||||||
{ $description "" } ;
|
{ $description "" } ;
|
||||||
|
|
||||||
HELP: get-slot-named
|
HELP: get-slot-named
|
||||||
{ $values
|
{ $values
|
||||||
{ "name" null } { "obj" object }
|
{ "name" "a slot name" } { "tuple" tuple }
|
||||||
{ "value" null } }
|
{ "value" "the value stored in the slot" } }
|
||||||
{ $description "" } ;
|
{ $description "Returns the value stored in a tuple slot, where the tuple slot is a string." } ;
|
||||||
|
|
||||||
HELP: join-space
|
HELP: join-space
|
||||||
{ $values
|
{ $values
|
||||||
|
@ -192,23 +190,11 @@ HELP: normalize-spec
|
||||||
{ "spec" null } }
|
{ "spec" null } }
|
||||||
{ $description "" } ;
|
{ $description "" } ;
|
||||||
|
|
||||||
HELP: number>string*
|
|
||||||
{ $values
|
|
||||||
{ "n/string" null }
|
|
||||||
{ "string" string } }
|
|
||||||
{ $description "" } ;
|
|
||||||
|
|
||||||
HELP: offset-of-slot
|
HELP: offset-of-slot
|
||||||
{ $values
|
{ $values
|
||||||
{ "string" string } { "obj" object }
|
{ "string" string } { "tuple" tuple }
|
||||||
{ "n" null } }
|
{ "n" integer } }
|
||||||
{ $description "" } ;
|
{ $description "Returns the offset of a tuple slot accessed by name." } ;
|
||||||
|
|
||||||
HELP: paren
|
|
||||||
{ $values
|
|
||||||
{ "string" string }
|
|
||||||
{ "new-string" null } }
|
|
||||||
{ $description "" } ;
|
|
||||||
|
|
||||||
HELP: persistent-table
|
HELP: persistent-table
|
||||||
{ $values
|
{ $values
|
||||||
|
@ -294,7 +280,6 @@ ARTICLE: "db.types" "Database types"
|
||||||
{ $subsection BLOB }
|
{ $subsection BLOB }
|
||||||
{ $subsection FACTOR-BLOB }
|
{ $subsection FACTOR-BLOB }
|
||||||
"Factor URLs:"
|
"Factor URLs:"
|
||||||
{ $subsection URL }
|
{ $subsection URL } ;
|
||||||
;
|
|
||||||
|
|
||||||
ABOUT: "db.types"
|
ABOUT: "db.types"
|
||||||
|
|
|
@ -126,11 +126,11 @@ ERROR: no-sql-type ;
|
||||||
HOOK: bind% db ( spec -- )
|
HOOK: bind% db ( spec -- )
|
||||||
HOOK: bind# db ( spec obj -- )
|
HOOK: bind# db ( spec obj -- )
|
||||||
|
|
||||||
: offset-of-slot ( string obj -- n )
|
: offset-of-slot ( string tuple -- n )
|
||||||
class superclasses [ "slots" word-prop ] map concat
|
class superclasses [ "slots" word-prop ] map concat
|
||||||
slot-named offset>> ;
|
slot-named offset>> ;
|
||||||
|
|
||||||
: get-slot-named ( name obj -- value )
|
: get-slot-named ( name tuple -- value )
|
||||||
tuck offset-of-slot slot ;
|
tuck offset-of-slot slot ;
|
||||||
|
|
||||||
: set-slot-named ( value name obj -- )
|
: set-slot-named ( value name obj -- )
|
||||||
|
|
|
@ -141,3 +141,12 @@ link-no-follow? off
|
||||||
|
|
||||||
[ "<p><a href='Factor'>Factor</a>-rific!</p>" ]
|
[ "<p><a href='Factor'>Factor</a>-rific!</p>" ]
|
||||||
[ "[[Factor]]-rific!" convert-farkup ] unit-test
|
[ "[[Factor]]-rific!" convert-farkup ] unit-test
|
||||||
|
|
||||||
|
[ "<p>[ factor { 1 2 3 }]</p>" ]
|
||||||
|
[ "[ factor { 1 2 3 }]" convert-farkup ] unit-test
|
||||||
|
|
||||||
|
[ "<p>paragraph\n<hr/></p>" ]
|
||||||
|
[ "paragraph\n___" convert-farkup ] unit-test
|
||||||
|
|
||||||
|
[ "<p>paragraph\n a ___ b</p>" ]
|
||||||
|
[ "paragraph\n a ___ b" convert-farkup ] unit-test
|
||||||
|
|
|
@ -38,6 +38,7 @@ TUPLE: line ;
|
||||||
|
|
||||||
EBNF: parse-farkup
|
EBNF: parse-farkup
|
||||||
nl = ("\r\n" | "\r" | "\n") => [[ drop "\n" ]]
|
nl = ("\r\n" | "\r" | "\n") => [[ drop "\n" ]]
|
||||||
|
whitespace = " " | "\t" | nl
|
||||||
|
|
||||||
heading1 = "=" (!("=" | nl).)+ "="
|
heading1 = "=" (!("=" | nl).)+ "="
|
||||||
=> [[ second >string heading1 boa ]]
|
=> [[ second >string heading1 boa ]]
|
||||||
|
@ -107,7 +108,7 @@ table = ((table-row nl => [[ first ]] )+ table-row? | table-row)
|
||||||
text = (!(nl | code | heading | inline-delimiter | table ).)+
|
text = (!(nl | code | heading | inline-delimiter | table ).)+
|
||||||
=> [[ >string ]]
|
=> [[ >string ]]
|
||||||
|
|
||||||
paragraph-item = (table | nl list | code | text | inline-tag | inline-delimiter)+
|
paragraph-item = (table | nl list | nl line | code | text | inline-tag | inline-delimiter)+
|
||||||
paragraph = ((paragraph-item nl => [[ first ]])+ nl+ => [[ first ]]
|
paragraph = ((paragraph-item nl => [[ first ]])+ nl+ => [[ first ]]
|
||||||
| (paragraph-item nl)+ paragraph-item?
|
| (paragraph-item nl)+ paragraph-item?
|
||||||
| paragraph-item)
|
| paragraph-item)
|
||||||
|
@ -133,7 +134,7 @@ line = '___'
|
||||||
=> [[ drop line new ]]
|
=> [[ drop line new ]]
|
||||||
|
|
||||||
|
|
||||||
named-code = '[' (!('{' | nl | '[').)+ '{' (!("}]").)+ "}]"
|
named-code = '[' (!('{' | whitespace | '[').)+ '{' (!("}]").)+ "}]"
|
||||||
=> [[ [ second >string ] [ fourth >string ] bi code boa ]]
|
=> [[ [ second >string ] [ fourth >string ] bi code boa ]]
|
||||||
|
|
||||||
simple-code
|
simple-code
|
||||||
|
|
|
@ -28,6 +28,10 @@ Ordered lists:
|
||||||
# with three
|
# with three
|
||||||
# numbered items
|
# numbered items
|
||||||
|
|
||||||
|
Horizontal lines:
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
Tables:
|
Tables:
|
||||||
|
|
||||||
|a table|with|four|columns|
|
|a table|with|four|columns|
|
||||||
|
|
Loading…
Reference in New Issue