Skip to content

Instantly share code, notes, and snippets.

@hippietrail
Created March 17, 2024 18:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hippietrail/9d860553d63224badbab03d6a09ee0f2 to your computer and use it in GitHub Desktop.
Save hippietrail/9d860553d63224badbab03d6a09ee0f2 to your computer and use it in GitHub Desktop.
Swift code to fetch one or more English Wikipedia articles as plain text without most of the interface text
import Foundation
/// Executes two commands in a pipeline.
///
/// - Parameters:
/// - firstCommand: The first command to execute. This should be a valid
/// command that you would type into the terminal.
/// - secondCommand: The second command to execute. This should be a valid
/// command that you would type into the terminal.
/// - args: The command line arguments passed to the script.
/// - Returns: The output of the second command, which is the result of the piped commands.
func executePipedCommands(firstCommand: String, secondCommand: String, args: [String]) -> String {
// Create two Process objects, one for each command.
let firstTask = Process()
let secondTask = Process()
// Create a Pipe object. This will be used as the input for the second command.
let pipe = Pipe()
// Set the standard output of the first command to be the pipe.
firstTask.standardOutput = pipe
// Set the arguments for the first command. The "-c" flag tells it to
// execute the command passed in as a string.
firstTask.arguments = ["-c", firstCommand]
// Set the launch path to the zsh shell. This is where the command will be executed.
firstTask.launchPath = "/bin/zsh"
// Set the standard input for the second command to be the read end of the pipe.
secondTask.standardInput = pipe
// Set the arguments for the second command. The "-c" flag tells it to
// execute the command passed in as a string.
secondTask.arguments = ["-c", secondCommand]
// Set the launch path to the zsh shell. This is where the command will be executed.
secondTask.launchPath = "/bin/zsh"
// Create a new Pipe object for the second command's standard output. This
// will be used to capture the output of the second command.
let outputPipe = Pipe()
// Set the standard output of the second command to be the new pipe.
secondTask.standardOutput = outputPipe
// Launch the first command.
firstTask.launch()
// Launch the second command.
secondTask.launch()
// Read the data from the new pipe that was created for the second command's standard output.
let data = outputPipe.fileHandleForReading.readDataToEndOfFile()
// Convert the data to a string using UTF8 encoding.
guard let output = String(data: data, encoding: .utf8) else {
// If the data could not be converted to a string, return an empty string.
return ""
}
// Return the output of the second command.
return output
}
// we'll need to convert spaces in the title to underscores
let urls = CommandLine
.arguments[1...]
.map { "https://en.wikipedia.org/w/index.php?title=\($0.replacingOccurrences(of: " ", with: "_"))&action=render" }
print(urls)
let pipedCommandOutput = executePipedCommands(
firstCommand: """
curl -Z \
-vs \
\(urls
.map { "\"\($0)\"" }
.joined(separator: " "))
""",
secondCommand: """
textutil \
-format html \
-convert txt \
-stdin \
-stdout \
-inputencoding UTF-8
""",
args: urls)
print(pipedCommandOutput)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment