diff --git a/DESCRIPTION b/DESCRIPTION
index 46b9aa4..652c777 100755
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,8 +1,10 @@
Package: textgRid
Title: Praat TextGrid Objects in R
Version: 1.0.1.9000
-Authors@R: person("Patrick", "Reidy", email = "patrick.francis.reidy@gmail.com",
- role = c("aut", "cre"))
+Authors@R: c(
+ person("Patrick", "Reidy", email = "patrick.francis.reidy@gmail.com",
+ role = c("aut", "cre")),
+ person("Tobias", "Busch", email = "teebusch@gmail.com", role = "ctb"))
Description: The software application Praat can be used to annotate
waveform data (e.g., to mark intervals of interest or to label events).
(See for more information about Praat.)
@@ -21,8 +23,8 @@ Suggests:
License: GPL-3
Encoding: UTF-8
LazyData: true
-RoxygenNote: 5.0.1
-Collate:
+RoxygenNote: 6.0.1
+Collate:
'Tier-class.R'
'IntervalTier-class.R'
'IntervalTier-accessors.R'
@@ -42,5 +44,6 @@ Collate:
'finders.R'
'length.R'
'textgRid.R'
+ 'writeTextGrid.R'
URL: www.praat.org, http://www.fon.hum.uva.nl/praat/manual/TextGrid.html
BugReports: https://github.com/patrickreidy/textgRid
diff --git a/NAMESPACE b/NAMESPACE
index e43200a..0119210 100755
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -17,6 +17,7 @@ export(textGridEndTime)
export(textGridStartTime)
export(tierName)
export(tierNumber)
+export(writeTextGrid)
exportClasses(IntervalTier)
exportClasses(PointTier)
exportClasses(TextGrid)
diff --git a/NEWS.md b/NEWS.md
index 9e896ef..1953751 100755
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,7 +1,11 @@
-# v1.0.1.9000
+# v1.0.1.9001
**_Current development version on Github_**
+* `writeTextGrid` function for `TextGrid`s.
+
+# v1.0.1.9000
+
* `length` methods for `IntervalTier`s and `PointTier`s.
* `Tier@number` slot changed from `numeric` to `integer`.
* `as.data.frame` methods for `IntervalTier`s, `PointTier`s, and `TextGrid`s.
diff --git a/R/IntervalTier-constructor.R b/R/IntervalTier-constructor.R
index be8a86d..47bf5f3 100755
--- a/R/IntervalTier-constructor.R
+++ b/R/IntervalTier-constructor.R
@@ -18,7 +18,7 @@ NULL
#' @importFrom methods setGeneric
setGeneric(
name = 'IntervalTier',
- def = function(praatText, ...) {
+ def = function(x, ...) {
standardGeneric('IntervalTier')
}
)
@@ -27,15 +27,56 @@ setGeneric(
#' @importFrom methods setMethod new
setMethod(
f = 'IntervalTier',
- sig = c(praatText = 'character'),
- def = function(praatText) {
+ sig = c(x = 'character'),
+ def = function(x) {
# Initialize the IntervalTier object.
new(Class = 'IntervalTier',
- name = .TierName(praatText),
- number = .TierNumber(praatText),
- startTimes = .IntervalStartTimes(praatText),
- endTimes = .IntervalEndTimes(praatText),
- labels = .IntervalLabels(praatText)
+ name = .TierName(x),
+ number = .TierNumber(x),
+ startTimes = .IntervalStartTimes(x),
+ endTimes = .IntervalEndTimes(x),
+ labels = .IntervalLabels(x)
+ )
+ }
+)
+
+
+#' @rdname IntervalTier-constructor
+#' @importFrom methods setMethod new
+setMethod(
+ f = 'IntervalTier',
+ sig = c(x = 'data.frame'),
+ def = function(x, startTime = 0, endTime = NULL) {
+ # TODO: Check if TierName column exists exists
+ .name <- x$TierName[1]
+ # TODO: Check if TierNumber col exists
+ .number <- x$TierNumber[1]
+ # TODO: Check if StartTime col exists
+ # TODO: Check if EndTime col exists
+ endTime = max(endTime, max(x$EndTime))
+ # TODO: Check if Label col exists
+ x <- x[, c('StartTime', 'EndTime', 'Label')]
+ x <- x[order(x$StartTime), ]
+ .endPrevious <- c(startTime, x$EndTime)
+ .startCurrent <- c(x$StartTime, endTime)
+ .gap <- .startCurrent - .endPrevious
+ # TODO: Check whether annotations are non-overlapping, with any(.gap < 0)
+ # Fill Gaps in Annotations
+ .gaps <- data.frame(
+ StartTime = .endPrevious,
+ EndTime = .startCurrent,
+ Label = NA
+ )
+ .gaps <- .gaps[.gap > 0, ]
+ x <- rbind(x, .gaps)
+ x <- x[order(x$StartTime), ]
+ # Initialize the IntervalTier object.
+ new(Class = 'IntervalTier',
+ name = .name,
+ number = .number,
+ startTimes = x$StartTime,
+ endTimes = x$EndTime,
+ labels = x$Label
)
}
)
diff --git a/R/PointTier-constructor.R b/R/PointTier-constructor.R
index 7b260e5..bf4b5ec 100755
--- a/R/PointTier-constructor.R
+++ b/R/PointTier-constructor.R
@@ -7,7 +7,7 @@ NULL
#' An S4 generic and S4 methods for creating an \code{\link[=PointTier-class]{PointTier}}
#' object.
#'
-#' @param praatText A character vector, the lines of text from a
+#' @param x A character vector, the lines of text from a
#' \code{.TextGrid} file that define a PointTier.
#' @param ... optional arguments for multiple dispatch (in development).
#' @return A \code{\link[=PointTier-class]{PointTier}} object. Values for the
@@ -19,7 +19,7 @@ NULL
#' @importFrom methods setGeneric
setGeneric(
name = 'PointTier',
- def = function(praatText, ...)
+ def = function(x, ...)
standardGeneric('PointTier')
)
@@ -28,13 +28,33 @@ setGeneric(
#' @importFrom methods setMethod new
setMethod(
f = 'PointTier',
- sig = c(praatText = 'character'),
- def = function(praatText)
+ sig = c(x = 'character'),
+ def = function(x)
# Initialize the TextTier object.
new(Class = 'PointTier',
- name = .TierName(praatText),
- number = .TierNumber(praatText),
- times = .PointTimes(praatText),
- labels = .PointLabels(praatText)
+ name = .TierName(x),
+ number = .TierNumber(x),
+ times = .PointTimes(x),
+ labels = .PointLabels(x)
+ )
+)
+
+
+#' @rdname PointTier-constructor
+#' @importFrom methods setMethod new
+setMethod(
+ f = 'PointTier',
+ sig = c(x = 'data.frame'),
+ def = function(x)
+ # TODO: Check if TierName column exists exists
+ # TODO: Check if TierNumber col exists
+ # TODO: Check if StartTime col exists
+ # TODO: Check if Label col exists
+ # Initialize the TextTier object.
+ new(Class = 'PointTier',
+ name = x$TierName[1],
+ number = x$TierNumber[1],
+ times = x$StartTime,
+ labels = x$Label
)
)
diff --git a/R/TextGrid-constructor.R b/R/TextGrid-constructor.R
index 3e364dc..7a28860 100755
--- a/R/TextGrid-constructor.R
+++ b/R/TextGrid-constructor.R
@@ -16,6 +16,9 @@ NULL
#' argument is the path to a \code{.TextGrid} file. Otherwise, the
#' \code{textGrid} argument is assumed to be a character vector whose
#' elements are the lines of some \code{.TextGrid} file.
+#' @section Details for signature \code{c(textGrid = 'data.frame')}:
+#' If \code{textGrid} is a data.frame it is tried to create a TextGrid object
+#' from it.
#' @name TextGrid-constructor
#' @aliases TextGrid
#' @seealso \code{\link{TextGrid-class}}, \code{\link{TextGrid-accessors}}
@@ -45,3 +48,33 @@ setMethod(
endTime = .TextGridTime(.textgrid, pattern = '^xmax')
)
})
+
+#' @rdname TextGrid-constructor
+#' @export
+#' @importFrom methods setMethod new
+setMethod(
+ f = 'TextGrid',
+ sig = c(textGrid = 'data.frame'),
+ def = function(textGrid, startTime = 0, endTime = NULL) {
+ # TODO: Check if TierNumber column exists
+ # TODO: Check if TierType column exists
+ .tiers <- .DataFrame2TierObjects(textGrid)
+ .lastAnnotation <- max(
+ sapply(.tiers, function(x) {
+ if (inherits(x, 'PointTier')) {
+ return(max(pointTimes(x)))
+ } else if (inherits(x, 'IntervalTier')) {
+ return(max(intervalEndTimes(x)))
+ }
+ })
+ )
+ endTime <- max(endTime, .lastAnnotation)
+ new(Class = 'TextGrid',
+ .tiers,
+ startTime = startTime,
+ endTime = endTime
+ )
+ })
+
+
+
\ No newline at end of file
diff --git a/R/TextGrid-utilities.R b/R/TextGrid-utilities.R
index 0cfd593..04a8a2d 100755
--- a/R/TextGrid-utilities.R
+++ b/R/TextGrid-utilities.R
@@ -53,3 +53,32 @@ NULL
names(.tier_objects) <- .TierName(praatText)
return(.tier_objects)
}
+
+
+# convert a TextGrid data frame to a list of IntervalTier and PointTier objects
+.DataFrame2TierObjects <- function(x) {
+ # TODO: Check if TierType and TierNumber exist
+ lapply(split(x, x$TierNumber), function(t) {
+ .tierType <- t$TierType[1]
+ if (.tierType == "IntervalTier") {
+ return(IntervalTier(t))
+ } else if (.tierType == "PointTier") {
+ return(PointTier(t))
+ }
+ })
+}
+
+# Check a data frame for compatibility with TextGrid constructor, report
+# issues, make educated guesses to rename and clean columns where possible
+.CleanTextGridDataFrame <- function(x) {
+ # TODO: check if all necessary columns exist
+ # TODO: fill gaps between StarTime/EndTime with NA
+ y <- x %>%
+ group_by(TierType, TierNumber) %>%
+ mutate(StartTime = EndTime,
+ EndTime = lag(EndTime),
+ Label = NA)
+
+ return(y)
+}
+
diff --git a/R/writeTextGrid.R b/R/writeTextGrid.R
new file mode 100644
index 0000000..4872d5a
--- /dev/null
+++ b/R/writeTextGrid.R
@@ -0,0 +1,114 @@
+#' @include Tier-class.R IntervalTier-class.R PointTier-class.R TextGrid-class.R
+NULL
+
+
+#' Write Praat-compatible TextGrid.
+#'
+#' Convert a \code{TextGrid} object to a Praat-compatible character string and
+#' (optionally) write it to a file.
+#'
+#' @param x A \code{TextGrid} object to be written.
+#' @param path Either a character string naming a file to write to, a connection
+#' open for writing, or \code{NULL} (default) for no output. When writing to
+#' file or connection, \code{path} is passed on as the \code{con} argument to
+#' \code{\link{writeLines}}
+#' @param ... Additional arguments passed on to \code{\link{writeLines}}
+#' when writing to a file or connection.
+#' @return A character vector, Each element is one row of the TextGrid file.
+#'
+#' @seealso \code{\link{TextGrid-class}}
+#' @name writeTextGrid
+#' @export
+writeTextGrid <- function(x, path = NULL, ...) {
+ .tiers <- x@.Data
+ .nTiers <- length(.tiers)
+
+ .header <- c(
+ 'File type = "ooTextFile"',
+ 'Object class = "TextGrid"',
+ '',
+ sprintf('xmin = %g', textGridStartTime(x)),
+ sprintf('xmax = %g', textGridEndTime(x)),
+ 'tiers? ',
+ sprintf('size = %g', .nTiers),
+ 'item []:'
+ )
+ .tiers <- sapply(.tiers, function(t) {
+ if (inherits(t, "IntervalTier")) {
+ return(writeIntervalTier(t))
+ } else if (inherits(t, "PointTier")) {
+ return(writePointTier(t))
+ }
+ })
+
+ .out <- c(.header, unlist(.tiers))
+ if (!is.null(path)) {
+ writeLines(.out, con = path, ...)
+ return(invisible(.out))
+ } else {
+ return(.out)
+ }
+}
+
+
+# convert IntervalTier object into a Praat-compatible character vector and
+# (optionally) write it to a file.
+writeIntervalTier <- function(x, path = NULL, ...) {
+ .tierStart <- min(intervalStartTimes(x))
+ .tierEnd <- max(intervalEndTimes(x))
+ .labels <- replace(intervalLabels(x), is.na(intervalLabels(x)), "")
+ .tierLen <- length(.labels)
+
+ .header <- c(
+ sprintf(' item[%d]:', tierNumber(x)),
+ ' class = "IntervalTier"',
+ sprintf(' name = "%s"', tierName(x)),
+ sprintf(' xmin = %g', .tierStart),
+ sprintf(' xmax = %g', .tierEnd),
+ sprintf(' intervals: size = %d', .tierLen)
+ )
+ .annotations <- mapply(function(startTime, endTime, label) {
+ c(sprintf(' xmin = %g', startTime),
+ sprintf(' xmax = %g', endTime),
+ sprintf(' text = "%s"', label))
+ }, intervalStartTimes(x), intervalEndTimes(x), .labels, SIMPLIFY = T)
+
+ .out <- c(.header, .annotations)
+ if (!is.null(path)) {
+ writeLines(.out, con = path, ...)
+ return(invisible(.out))
+ } else {
+ return(.out)
+ }
+}
+
+
+# convert PointTier object into a Praat-compatible character vector and
+# (optionally) write it to a file.
+writePointTier <- function(x, path = NULL, ...) {
+ .tierStart <- min(pointTimes(x))
+ .tierEnd <- max(pointTimes(x))
+ .labels <- replace(pointLabels(x), is.na(pointLabels(x)), "")
+ .tierLen <- length(.labels)
+
+ .header <- c(
+ sprintf(' item[%d]:', tierNumber(x)),
+ ' class = "TextTier"',
+ sprintf(' name = "%s"', tierName(x)),
+ sprintf(' xmin = %g', .tierStart),
+ sprintf(' xmax = %g', .tierEnd),
+ sprintf(' points: size = %d', .tierLen)
+ )
+ .annotations <- mapply(function(time, label) {
+ c(sprintf(' number = %g', time),
+ sprintf(' mark = "%s"', label))
+ }, pointTimes(x), .labels, SIMPLIFY = T)
+
+ .out <- c(.header, .annotations)
+ if (!is.null(path)) {
+ writeLines(.out, con = path, ...)
+ return(invisible(.out))
+ } else {
+ return(.out)
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 8c57f4d..11a1b2b 100755
--- a/README.md
+++ b/README.md
@@ -98,6 +98,17 @@ as.data.frame(textgrid)
# 11 3 Events PointTier 2 8.25 8.25 voicingOff
```
+#### Convert a data.frame to a TextGrid object
+```r
+df <- as.data.frame(textgrid)
+TextGrid(df)
+```
+
+#### Write a TextGrid object to a Praat-compatible .TextGrid file.
+```r
+writeTextGrid(textgrid, path = 'test_out.TextGrid')
+```
+
## Details on S4 classes
The textgRid package defines four S4 classes, whose slots and accessors are
diff --git a/man/IntervalTier-accessors.Rd b/man/IntervalTier-accessors.Rd
index 0e4d2b4..c75f184 100755
--- a/man/IntervalTier-accessors.Rd
+++ b/man/IntervalTier-accessors.Rd
@@ -2,9 +2,9 @@
% Please edit documentation in R/IntervalTier-accessors.R
\name{IntervalTier-accessors}
\alias{IntervalTier-accessors}
+\alias{intervalStartTimes}
\alias{intervalEndTimes}
\alias{intervalLabels}
-\alias{intervalStartTimes}
\title{Access the slots of IntervalTier objects.}
\usage{
intervalStartTimes(tier)
@@ -24,4 +24,3 @@ object.
\code{\link{IntervalTier-class}},
\code{\link{IntervalTier-constructor}}, \code{\link{Tier-accessors}}
}
-
diff --git a/man/IntervalTier-class.Rd b/man/IntervalTier-class.Rd
index d7b4333..78a7358 100755
--- a/man/IntervalTier-class.Rd
+++ b/man/IntervalTier-class.Rd
@@ -26,9 +26,9 @@ IntervalTier.}
\item{\code{labels}}{A character vector, the labels of the intervals in the
IntervalTier.}
}}
+
\seealso{
\code{\link{IntervalTier-constructor}},
\code{\link{IntervalTier-accessors}}, \code{\link{TextGrid-class}},
\code{\link{Tier-class}}
}
-
diff --git a/man/IntervalTier-constructor.Rd b/man/IntervalTier-constructor.Rd
index cd06747..2e93633 100755
--- a/man/IntervalTier-constructor.Rd
+++ b/man/IntervalTier-constructor.Rd
@@ -2,20 +2,23 @@
% Please edit documentation in R/IntervalTier-constructor.R
\docType{methods}
\name{IntervalTier-constructor}
+\alias{IntervalTier-constructor}
\alias{IntervalTier}
\alias{IntervalTier,character-method}
-\alias{IntervalTier-constructor}
+\alias{IntervalTier,data.frame-method}
\title{Create an instance of the IntervalTier class.}
\usage{
-IntervalTier(praatText, ...)
+IntervalTier(x, ...)
-\S4method{IntervalTier}{character}(praatText)
+\S4method{IntervalTier}{character}(x)
+
+\S4method{IntervalTier}{data.frame}(x, startTime = 0, endTime = NULL)
}
\arguments{
+\item{...}{optional arguments for multiple dispatch (in development).}
+
\item{praatText}{A character vector, the lines of text from a
\code{.TextGrid} file that define an IntervalTier.}
-
-\item{...}{optional arguments for multiple dispatch (in development).}
}
\value{
A \code{\link[=IntervalTier-class]{IntervalTier}} object. Values for the
@@ -29,4 +32,3 @@ object.
\seealso{
\code{\link{IntervalTier-class}}, \code{\link{IntervalTier-accessors}}
}
-
diff --git a/man/PointTier-accessors.Rd b/man/PointTier-accessors.Rd
index 8a5e6c4..0c36ed8 100755
--- a/man/PointTier-accessors.Rd
+++ b/man/PointTier-accessors.Rd
@@ -2,8 +2,8 @@
% Please edit documentation in R/PointTier-accessors.R
\name{PointTier-accessors}
\alias{PointTier-accessors}
-\alias{pointLabels}
\alias{pointTimes}
+\alias{pointLabels}
\title{Access the slots of PointTier objects.}
\usage{
pointTimes(tier)
@@ -21,4 +21,3 @@ object.
\code{\link{PointTier-class}},
\code{\link{PointTier-constructor}}, \code{\link{Tier-accessors}}
}
-
diff --git a/man/PointTier-class.Rd b/man/PointTier-class.Rd
index 4c19506..1f3fdf0 100755
--- a/man/PointTier-class.Rd
+++ b/man/PointTier-class.Rd
@@ -21,9 +21,9 @@ A point's label is typically the annotation of some event in waveform data
\item{\code{labels}}{A character vector, the labels of the points in the PointTier.}
}}
+
\seealso{
\code{\link{PointTier-constructor}},
\code{\link{PointTier-accessors}}, \code{\link{TextGrid-class}},
\code{\link{Tier-class}}
}
-
diff --git a/man/PointTier-constructor.Rd b/man/PointTier-constructor.Rd
index 3c7e6fb..2f6c2c9 100755
--- a/man/PointTier-constructor.Rd
+++ b/man/PointTier-constructor.Rd
@@ -2,17 +2,20 @@
% Please edit documentation in R/PointTier-constructor.R
\docType{methods}
\name{PointTier-constructor}
+\alias{PointTier-constructor}
\alias{PointTier}
\alias{PointTier,character-method}
-\alias{PointTier-constructor}
+\alias{PointTier,data.frame-method}
\title{Create an instance of the PointTier class.}
\usage{
-PointTier(praatText, ...)
+PointTier(x, ...)
-\S4method{PointTier}{character}(praatText)
+\S4method{PointTier}{character}(x)
+
+\S4method{PointTier}{data.frame}(x)
}
\arguments{
-\item{praatText}{A character vector, the lines of text from a
+\item{x}{A character vector, the lines of text from a
\code{.TextGrid} file that define a PointTier.}
\item{...}{optional arguments for multiple dispatch (in development).}
@@ -29,4 +32,3 @@ object.
\seealso{
\code{\link{PointTier-class}}, \code{\link{PointTier-accessors}}
}
-
diff --git a/man/TextGrid-accessors.Rd b/man/TextGrid-accessors.Rd
index 3dcf711..9a0dfbb 100755
--- a/man/TextGrid-accessors.Rd
+++ b/man/TextGrid-accessors.Rd
@@ -2,8 +2,8 @@
% Please edit documentation in R/TextGrid-accessors.R
\name{TextGrid-accessors}
\alias{TextGrid-accessors}
-\alias{textGridEndTime}
\alias{textGridStartTime}
+\alias{textGridEndTime}
\title{Access the slots of TextGrid objects.}
\usage{
textGridStartTime(textGrid)
@@ -21,4 +21,3 @@ object.
\code{\link{TextGrid-class}},
\code{\link{TextGrid-constructor}}
}
-
diff --git a/man/TextGrid-class.Rd b/man/TextGrid-class.Rd
index 6340288..3d0e9cc 100755
--- a/man/TextGrid-class.Rd
+++ b/man/TextGrid-class.Rd
@@ -21,9 +21,9 @@ A \code{TextGrid} object is essentially a list of
\item{\code{endTime}}{A numeric, the end time of the TextGrid.}
}}
+
\seealso{
\code{\link{TextGrid-constructor}},
\code{\link{TextGrid-accessors}}, \code{\link{IntervalTier-class}},
\code{\link{PointTier-class}}
}
-
diff --git a/man/TextGrid-constructor.Rd b/man/TextGrid-constructor.Rd
index a80f3a8..a45daa3 100755
--- a/man/TextGrid-constructor.Rd
+++ b/man/TextGrid-constructor.Rd
@@ -2,14 +2,17 @@
% Please edit documentation in R/TextGrid-constructor.R
\docType{methods}
\name{TextGrid-constructor}
+\alias{TextGrid-constructor}
\alias{TextGrid}
\alias{TextGrid,character-method}
-\alias{TextGrid-constructor}
+\alias{TextGrid,data.frame-method}
\title{Create an instance of the TextGrid class.}
\usage{
TextGrid(textGrid, ...)
\S4method{TextGrid}{character}(textGrid)
+
+\S4method{TextGrid}{data.frame}(textGrid, startTime = 0, endTime = NULL)
}
\arguments{
\item{textGrid}{A character vector}
@@ -31,7 +34,13 @@ object.
\code{textGrid} argument is assumed to be a character vector whose
elements are the lines of some \code{.TextGrid} file.
}
+
+\section{Details for signature \code{c(textGrid = 'data.frame')}}{
+
+ If \code{textGrid} is a data.frame it is tried to create a TextGrid object
+ from it.
+}
+
\seealso{
\code{\link{TextGrid-class}}, \code{\link{TextGrid-accessors}}
}
-
diff --git a/man/Tier-accessors.Rd b/man/Tier-accessors.Rd
index d2ee169..a94ac24 100755
--- a/man/Tier-accessors.Rd
+++ b/man/Tier-accessors.Rd
@@ -19,4 +19,3 @@ Get the values of slots in a \code{\link[=Tier-class]{Tier}} object.
\seealso{
\code{\link{Tier-class}}
}
-
diff --git a/man/Tier-class.Rd b/man/Tier-class.Rd
index 771e0d7..cdd4574 100755
--- a/man/Tier-class.Rd
+++ b/man/Tier-class.Rd
@@ -2,8 +2,8 @@
% Please edit documentation in R/Tier-class.R
\docType{class}
\name{Tier-class}
-\alias{Tier}
\alias{Tier-class}
+\alias{Tier}
\title{Tier S4 class for Praat TextGrids.}
\description{
The \code{Tier} class is extended by the \code{\link[=PointTier-class]{PointTier}}
@@ -18,8 +18,8 @@ to both subtypes of tier-like object.
\item{\code{number}}{An integer, the number of the Tier within the TextGrid.}
}}
+
\seealso{
\code{\link{IntervalTier-class}}, \code{\link{PointTier-class}},
\code{\link{TextGrid-class}}, \code{\link{Tier-accessors}}
}
-
diff --git a/man/findIntervals.Rd b/man/findIntervals.Rd
index a9675d0..c692a38 100755
--- a/man/findIntervals.Rd
+++ b/man/findIntervals.Rd
@@ -45,4 +45,3 @@ only at the time given by \code{at}.
\seealso{
\code{\link{IntervalTier-class}}, \code{\link{grep}}
}
-
diff --git a/man/findPoints.Rd b/man/findPoints.Rd
index 1961387..c3efb34 100755
--- a/man/findPoints.Rd
+++ b/man/findPoints.Rd
@@ -36,4 +36,3 @@ time range, whose labels match a pattern.
\seealso{
\code{\link{PointTier-class}}, \code{\link{grep}}
}
-
diff --git a/man/textgRid-as.data.frame.Rd b/man/textgRid-as.data.frame.Rd
index de21c71..998e5ba 100755
--- a/man/textgRid-as.data.frame.Rd
+++ b/man/textgRid-as.data.frame.Rd
@@ -1,10 +1,13 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/as.data.frame.R
\name{textgRid-as.data.frame}
+\alias{textgRid-as.data.frame}
+\alias{as.data.frame.IntervalTier}
+\alias{as.data.frame.PointTier}
+\alias{as.data.frame.TextGrid}
\alias{as.data.frame.IntervalTier}
\alias{as.data.frame.PointTier}
\alias{as.data.frame.TextGrid}
-\alias{textgRid-as.data.frame}
\title{Coerce to a data.frame.}
\usage{
\method{as.data.frame}{IntervalTier}(x, row.names = NULL, optional = FALSE,
@@ -46,4 +49,3 @@ to a \code{data.frame}.
\code{findIntervals()} and \code{findPoints()}, respectively. Only intervals
and points that have contentful, non-empty labels are returned after coercion.
}
-
diff --git a/man/textgRid-length.Rd b/man/textgRid-length.Rd
index 700ea25..7d42e2a 100755
--- a/man/textgRid-length.Rd
+++ b/man/textgRid-length.Rd
@@ -1,9 +1,11 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/length.R
\name{textgRid-length}
+\alias{textgRid-length}
+\alias{length.IntervalTier}
+\alias{length.PointTier}
\alias{length.IntervalTier}
\alias{length.PointTier}
-\alias{textgRid-length}
\title{Length of an IntervalTier or PointTier}
\usage{
\method{length}{IntervalTier}(x)
@@ -31,4 +33,3 @@ of the \code{labels}-vector is returned; otherwise, \code{NULL} is returned.
have the same length. If so, the length of the \code{labels}-vector is
returned; otherwise, \code{NULL} is returned.
}
-
diff --git a/man/writeTextGrid.Rd b/man/writeTextGrid.Rd
new file mode 100644
index 0000000..99999ce
--- /dev/null
+++ b/man/writeTextGrid.Rd
@@ -0,0 +1,29 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/writeTextGrid.R
+\name{writeTextGrid}
+\alias{writeTextGrid}
+\title{Write Praat-compatible TextGrid.}
+\usage{
+writeTextGrid(x, path = NULL, ...)
+}
+\arguments{
+\item{x}{A \code{TextGrid} object to be written.}
+
+\item{path}{Either a character string naming a file to write to, a connection
+open for writing, or \code{NULL} (default) for no output. When writing to
+file or connection, \code{path} is passed on as the \code{con} argument to
+\code{\link{writeLines}}}
+
+\item{...}{Additional arguments passed on to \code{\link{writeLines}}
+when writing to a file or connection.}
+}
+\value{
+A character vector, Each element is one row of the TextGrid file.
+}
+\description{
+Convert a \code{TextGrid} object to a Praat-compatible character string and
+(optionally) write it to a file.
+}
+\seealso{
+\code{\link{TextGrid-class}}
+}
diff --git a/tests/testthat/test-TextGrid.R b/tests/testthat/test-TextGrid.R
index 261eb89..2b89e92 100755
--- a/tests/testthat/test-TextGrid.R
+++ b/tests/testthat/test-TextGrid.R
@@ -208,3 +208,35 @@ test_that('as.data.frame.TextGrid() can override default row names', {
expected = .labels
)
})
+
+
+test_that('TextGrid() of data.frame returns a TextGrid', {
+ .textgrid_in <- TextGrid('../test.TextGrid')
+ .textgrid_out <- TextGrid(as.data.frame(.textgrid_in))
+ expect_s4_class(.textgrid_out, 'TextGrid')
+})
+
+
+test_that('TextGrid() of data.frame returns a TextGrid', {
+ .textgrid_in <- TextGrid('../test.TextGrid')
+ .textgrid_out <- TextGrid(as.data.frame(.textgrid_in))
+ expect_s4_class(.textgrid_out, 'TextGrid')
+})
+
+
+test_that('as.data.frame(TextGrid(as.data.frame(x))) equals x', {
+ .df_in <- as.data.frame(TextGrid('../test.TextGrid'))
+ .df_out <- as.data.frame(TextGrid(.df_in))
+ expect_equal(.df_in, .df_out)
+})
+
+
+test_that('TextGrid(as.data.frame(x)) equals x', {
+ .textgrid_in <- TextGrid('../test.TextGrid')
+ .textgrid_out <- TextGrid(as.data.frame(.textgrid_in))
+ expect_equal(.textgrid_in@.Data, .textgrid_out@.Data)
+ expect_equal(textGridStartTime(.textgrid_in),
+ textGridStartTime(.textgrid_out))
+ expect_equal(textGridEndTime(.textgrid_in),
+ textGridEndTime(.textgrid_out))
+})
diff --git a/tests/testthat/test-writeTextGrid.R b/tests/testthat/test-writeTextGrid.R
new file mode 100644
index 0000000..a3da7d2
--- /dev/null
+++ b/tests/testthat/test-writeTextGrid.R
@@ -0,0 +1,66 @@
+library(textgRid)
+context('TextGrid')
+
+
+test_that('writeTextGrid() returns valid TextGrid character vector', {
+ .fin <- '../test.TextGrid'
+ .textgrid <- TextGrid(.fin)
+ .textgrid_lines <- writeTextGrid(.textgrid)
+
+ expect_s4_class(
+ object = TextGrid(.textgrid_lines),
+ class = 'TextGrid'
+ )
+})
+
+
+test_that('writeTextGrid() output is identical to input TextGrid', {
+ .fin <- '../test.TextGrid'
+ .textgrid_in <- TextGrid(.fin)
+ .textgrid_lines <- writeTextGrid(.textgrid_in)
+ .textgrid_out <- TextGrid(.textgrid_lines)
+
+ expect_identical(.textgrid_out, .textgrid_in)
+})
+
+
+test_that('writeTextGrid() can write to file', {
+ .fin <- '../test.TextGrid'
+ .fout <- '../test_out.TextGrid'
+ .textgrid_in <- TextGrid(.fin)
+ writeTextGrid(.textgrid_in, path = .fout)
+ .textgrid_out <- TextGrid(.fout)
+
+ expect_identical(.textgrid_out, .textgrid_in)
+ file.remove(.fout)
+})
+
+
+test_that('writeIntervalTier() can write to file', {
+ .fin <- '../test.TextGrid'
+ .fout <- '../test_out.TextGrid'
+ .textgrid_in <- TextGrid(.fin)
+ .tier <- .textgrid_in@.Data[[1]] # an ItervalTier
+
+ .tier_in <- writeIntervalTier(.tier)
+ writeIntervalTier(.tier, path = .fout)
+ .tier_out <- readLines(.fout)
+
+ expect_identical(.tier_in, .tier_out)
+ file.remove(.fout)
+})
+
+
+test_that('writePointTier() can write to file', {
+ .fin <- '../test.TextGrid'
+ .fout <- '../test_out.TextGrid'
+ .textgrid_in <- TextGrid(.fin)
+ .tier <- .textgrid_in@.Data[[3]] # a PointTier
+
+ .tier_in <- writePointTier(.tier)
+ writePointTier(.tier, path = .fout)
+ .tier_out <- readLines(.fout)
+
+ expect_identical(.tier_in, .tier_out)
+ file.remove(.fout)
+})
\ No newline at end of file