kevboh / longform

A plugin for Obsidian that helps you write and edit novels, screenplays, and other long projects.
Other
610 stars 30 forks source link

Feature Request: support for templating, formatting inside compile step text arguments #137

Open ReaderGuy42 opened 1 year ago

ReaderGuy42 commented 1 year ago

Like $1 outputs the project's title in the compiled note title, would it be possible to add something like that for the current date and/or date-time, so e.g. you include $2 in the compiled note title, and it would output the date?

Sorry if this has been discussed, I'm not sure how to search for it.

Thanks :)

kevboh commented 1 year ago

It's a good idea. What I should really do is allow some very light templating language inside text arguments to compile steps so that you could format the datetime.

ReaderGuy42 commented 1 year ago

Apologies, didn't get notified you replied, yes that would work! I would appreciate that, thanks :)

tumblebone commented 3 months ago

Greetings!

The following script compiles the current projects scenes as a manuscript with the following file name syntax:

{project title}{date}{time}.md

Happy sunday! 🌻

module.exports = {
  description: {
      name: "Save Manuscript with Date and Time",
      description: "Saves the manuscript with the current date and time in the filename.",
      availableKinds: ["Manuscript"],
      options: [
          {
              id: "output-folder",
              name: "Output Folder",
              description: "Folder path where the compiled manuscript will be saved, relative to the Longform project folder.",
              type: "Text",
              default: "output/",
          },
          {
              id: "open-after",
              name: "Open Compiled Manuscript",
              description: "If checked, open the compiled manuscript in a new pane.",
              type: "Boolean",
              default: true,
          },
      ],
  },

  compile(input, context) {
      return __awaiter(this, void 0, void 0, function* () {
          if (context.kind !== "Manuscript") {
              throw new Error("Cannot write non-manuscript as note.");
          }
          else {
              const now = new Date();
              const formattedDate = now.toISOString().slice(0, 10).replace(/-/g, '_');
              const formattedTime = now.toISOString().slice(11, 19).replace(/:/g, '-');

              const projectName = context.draft.title.replace(/ /g, "_");
              const fileName = `${projectName}_${formattedDate}_${formattedTime}.md`;

              let outputFolder = context.optionValues["output-folder"];
              const openAfter = context.optionValues["open-after"];
              if (!outputFolder || outputFolder.length === 0) {
                  throw new Error("Invalid output folder.");
              }
              // Concatenate the Longform project path with the specified output folder
              const projectPath = context.projectPath.endsWith("/") ? context.projectPath : context.projectPath + "/";
              outputFolder = projectPath + outputFolder;
              outputFolder = outputFolder.endsWith("/") ? outputFolder : outputFolder + "/";
              const filePath = outputFolder + fileName;

              // Write the manuscript content to the file
              yield writeToFile(context.app, filePath, input.contents);

              // Open the compiled manuscript in a new pane if the option is checked
              if (openAfter) {
                  console.log("[Longform] Attempting to open:", filePath);
                  context.app.workspace.openLinkText(filePath, "/", true).catch((err) => {
                      console.error("[Longform] Could not open", filePath, err);
                  });
              }

              return input;
          }
      });
  },
};

async function writeToFile(app, filePath, contents) {
  await ensureContainingFolderExists(app, filePath);
  console.log("[Longform] Writing to:", filePath);
  await app.vault.adapter.write(filePath, contents);
}

async function ensureContainingFolderExists(app, filePath) {
  const containingFolderPath = filePath.substring(0, filePath.lastIndexOf("/"));
  try {
      await app.vault.createFolder(containingFolderPath);
  }
  catch (e) {
      // Folder already exists
  }
}