mypatchDVI <- function (f, newname = f) { specials <- DVIspecials(f) concordind <- grep("^concordance:", specials) concords <- specials[concordind] if(length(concords) == 1) ## 処理するSweaveファイルが1つなら concords <- sub("c:", "", concords) ## ドライブレターを削除する parseConcord <- function(split) { oldname <- split[2] newname <- split[3] if (length(split) == 4) { ofs <- 0 vi <- 4 } else { ofs <- as.integer(sub("^ofs ([0-9]+)", "\\1", split[4])) vi <- 5 } values <- as.integer(strsplit(split[vi], " ")[[1]]) firstline <- values[1] rledata <- matrix(values[-1], nrow = 2) rle <- structure(list(lengths = rledata[1, ], values = rledata[2, ]), class = "rle") diffs <- inverse.rle(rle) concord <- c(firstline, firstline + cumsum(diffs)) list(oldname = oldname, newname = newname, concord = concord, ofs = ofs) } concords <- strsplit(concords, ":") concords <- lapply(concords, parseConcord) ## 処理するSweaveファイルが1つなら,ドライブレターを元に戻す if(length(concords) == 1) concords[[1]]$newname <- paste("c:", concords[[1]]$newname, sep = "") names(concords) <- sapply(concords, function(x) x$oldname) srcrefind <- grep("^src:", specials) srcrefs <- specials[srcrefind] linenums <- sub("^src:([0-9]+).*$", "\\1", srcrefs) ## 下行は substr(srcrefs, 5 + ...)だったの6に変更 ##(ファイル名の先頭に空白が入るのを除くため) filenames <- substr(srcrefs, 6 + nchar(linenums), 10000) noext <- !grepl("\\.", filenames) filenames[noext] <- paste(filenames[noext], ".tex", sep = "") filenames <- normalizePath(filenames) linenums <- as.integer(linenums) changed <- rep(FALSE, length(filenames)) for (i in seq_along(concords)) { n <- names(concords)[i] ofs <- concords[[i]]$ofs concord <- concords[[i]]$concord subset <- (filenames == normalizePath(n)) & (linenums > ofs) & (linenums <= ofs + length(concord)) linenums[subset] <- concord[linenums[subset] - ofs] filenames[subset] <- concords[[i]]$newname changed[subset] <- TRUE } ## 上記修正で 5→6にしたことの調整をここで行う(" "を追記) newrefs <- ifelse(changed, paste("src:", linenums, " ", filenames, sep = ""), srcrefs) specials[srcrefind] <- newrefs specials[concordind] <- NA if (any(changed) || length(concordind)) setDVIspecials(f, specials, newname) changes <- sum(changed) + length(concordind) msg <- paste(changes, "patches made.") if (!changes) msg <- paste(msg, "Did you set \\SweaveOpts{concordance=TRUE}?") msg } mypatchSynctex <- function (f, newname = f, uncompress = "pdftk %s output %s uncompress") { DVIfile <- sub(".synctex", ".dvi", f) ## dviファイル名を付値 compressed <- FALSE if (!file.exists(f)) { f <- paste(f, ".gz", sep = "") if (file.exists(f)) { compressed <- TRUE force(newname) f <- gzfile(f) } } lines <- try(readLines(f, warn = FALSE), silent = TRUE) if (inherits(lines, "try-error")) return(paste(f, "cannot be read, no patching done.")) ## syncFiles()はpatchDVIパッケージ内の不可視関数なので:::が必要 files <- patchDVI:::syncFiles(lines) ## リストconcordsを作るまでの処理はmypatchDVI()の該当箇所を移植 specials <- DVIspecials(DVIfile) concordind <- grep("^concordance:", specials) concords <- specials[concordind] if(length(concords) == 1) ## 処理するSweaveファイルが1つなら concords <- sub("c:", "", concords) ## ドライブレターを削除する parseConcord <- function(split) { oldname <- split[2] newname <- split[3] if (length(split) == 4) { ofs <- 0 vi <- 4 } else { ofs <- as.integer(sub("^ofs ([0-9]+)", "\\1", split[4])) vi <- 5 } values <- as.integer(strsplit(split[vi], " ")[[1]]) firstline <- values[1] rledata <- matrix(values[-1], nrow = 2) rle <- structure(list(lengths = rledata[1, ], values = rledata[2, ]), class = "rle") diffs <- inverse.rle(rle) concord <- c(firstline, firstline + cumsum(diffs)) list(oldname = oldname, newname = newname, concord = concord, ofs = ofs) } concords <- strsplit(concords, ":") concords <- lapply(concords, parseConcord) ## 処理するSweaveファイルが1つなら,ドライブレターを元に戻す if(length(concords) == 1) concords[[1]]$newname <- paste("c:", concords[[1]]$newname, sep = "") names(concords) <- sapply(concords, function(x) x$oldname) re <- "^([vhxkgr$[(])([[:digit:]]+),([[:digit:]]+)([^[:digit:]].*)" srcrefind <- grep(re, lines) srcrefs <- lines[srcrefind] ops <- sub(re, "\\1", srcrefs) tags <- sub(re, "\\2", srcrefs) linenums <- sub(re, "\\3", srcrefs) rest <- sub(re, "\\4", srcrefs) linenums <- as.integer(linenums) changed <- rep(FALSE, length(tags)) newtags <- c() maxtag <- max(files$tag) for (i in seq_along(concords)) { n <- names(concords)[i] ofs <- concords[[i]]$ofs concord <- concords[[i]]$concord newsrc <- concords[[i]]$newname ## 元はconcords[[i]]$newsrc if (!(newsrc %in% names(newtags))) { maxtag <- maxtag + 1 newtags <- c(newtags, maxtag) names(newtags)[length(newtags)] <- newsrc } tag <- files$tag[files$name == n] if (length(tag) == 1) { subset <- (tags == tag) & (linenums > ofs) & (linenums <= ofs + length(concord)) linenums[subset] <- concord[linenums[subset] - ofs] tags[subset] <- newtags[newsrc] changed[subset] <- TRUE } } if (any(changed)) { newrefs <- ifelse(changed, paste(ops, tags, ",", linenums, rest, sep = ""), srcrefs) lines[srcrefind] <- newrefs firstInput <- grep("^Input:", lines)[1] lines <- c(lines[1:firstInput], paste("Input:", newtags, ":", names(newtags), sep = ""), lines[(firstInput + 1):length(lines)]) } con <- if (compressed) gzfile(newname, "wb") else file(newname, "wb") on.exit(close(con)) writeLines(lines, con, sep = "\n") changes <- sum(changed) + length(newtags) msg <- paste(changes, "patches made.") if (!changes) msg <- paste(msg, "Did you set \\SweaveOpts{concordance=TRUE}?") msg }