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