Skip to content

Commit

Permalink
Add experimental "convert to pretext" command
Browse files Browse the repository at this point in the history
  • Loading branch information
oscarlevin committed Nov 27, 2023

Unverified

This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
1 parent 72db595 commit 1975c2f
Showing 8 changed files with 186 additions and 93 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -21,10 +21,11 @@ jobs:
uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v2
with:
node-version: "16"


- name: Install Dependencies
run: |
npm install
@@ -55,7 +56,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@master
uses: actions/checkout@latest
- name: Create Release
id: create_release
uses: actions/create-release@latest
4 changes: 2 additions & 2 deletions .github/workflows/pull-request-tests.yml
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@ jobs:
format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@latest
- uses: actions/setup-node@latest
with:
node-version: 18

2 changes: 2 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.github
.vscode
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [UNRELEASED]

## [0.13.0] - 2023-11-27

### Added

- Experimental support for converting selected LaTeX to PreTeXt.

## [0.12.2] - 2023-09-12

### Fixed
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -162,7 +162,7 @@
"command": "pretext-tools.latexToPretext",
"title": "Convert Selected LaTeX to PreTeXt",
"category": "PreTeXt",
"description": "Converts and replaces a selection of LaTeX with PreTeXt formatted text."
"description": "Converts and replaces a selection of LaTeX with PreTeXt formatted text (experimental)."
}
],
"xmlLanguageParticipants": [
2 changes: 1 addition & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ import { execSync, spawn } from "child_process";
import { homedir } from "os";
import * as path from "path";
import * as vscode from "vscode";
import { convertToPretext } from "./convert";
import { convertToPretext } from "./pandocConvert";
import { latexToPretext } from "./latextopretext";

// Set up vscode elements
258 changes: 171 additions & 87 deletions src/latextopretext.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
//convertParagraph function using regex currently unused
// function convertParagraph(text: string) {
// //convert empty lines to paragraph
// let result = text.replace(
// /(\r|\n(?!\r|\n))(.*?)((\r|\n)\s*?(\r|\n))/gs,
// "<p>\n$2\n</p>\n\n"
// );
// return result;
// }
// module

const BLOCKS: {[key: string]: string } = {
"axiom": "axiom",
"theorem": "theorem",
"lemma": "lemma",
"corollary": "corollary",
"proposition": "proposition",
"definition": "definition",
"example": "example",
"remark": "remark",
"exercise": "exercise",
"question": "question",
"problem": "problem",
"solution": "solution",
"proof": "proof",
"note": "note",
"aside": "aside",
"figure": "figure",
"table": "table",
"algorithm": "algorithm",
"enumerate": "ol",
"itemize": "ul",
};

// Paragraph element conversions /////////////////////////////////

@@ -37,6 +52,7 @@ function convertTextMarkup(text: string) {

return result;
}

function convertQuotation(text: string) {
//convert double quote
let result = text.replace(/(``|")(.*?)(''|")/gs, "<q>$2</q>");
@@ -48,110 +64,178 @@ function convertQuotation(text: string) {

/////////////////////////////////////////////////////////////////

function converter(text: string) {
function convertP(text: string) {
let result = text;
//result = convertParagraph(result);
result = convertMath(result);
result = convertTextMarkup(result);
result = convertQuotation(result);

return result;
}

function getBlockList(text: string) {
// We parse the text input and return a list of strings, each a separate "block", which could be a paragraph or a \begin/\end environment.
let blockList: string[] = [];
let textArray = text.split(/\r\n|\r|\n/);
let loopCount = text.split(/\r\n|\r|\n/).length;
let convertCheck = true;
let block = "";

for (let i = 0; i < loopCount; i++) {
if (convertCheck) {
if (textArray[i].trim().length === 0) {
block += "\n";
blockList.push(block);
block = "";
continue;
}
if (textArray[i].trim().startsWith("\\begin")) {
block += textArray[i].trim() + "\n";
//////// Convert lines starting with a backslash //////////////////////

convertCheck = false;
} else {
if (i === 0) {
block += textArray[i].trim() + "\n";
if (textArray[i + 1].trim().length === 0) {
blockList.push(block);
block = "";
}
} else if (i + 1 === loopCount) {
block += textArray[i].trim() + "\n";
blockList.push(block);
block = "";
} else {
block += converter(textArray[i]).trim() + "\n";
if (textArray[i + 1].trim().length === 0) {
blockList.push(block);
block = "";
}
}
}
} else {
if (textArray[i].trim().startsWith("\\end")) {
block += textArray[i].trim();
function convertBS(text: string) {
let command = text.match(/(\\.*?)(\\| |$)/);
// console.log("LINE "+text);
if (command !== null) {
// console.log("COMMAND: "+command[1]);
text = text.replace(command[1], "");
// console.log("TEXT: "+text);
// Item:
if (command[1] === "\\item") {
return "<li>\n\t<p>\n\t\t" + convertP(text) + "\n<\p>\n</li>\n";
}
// \vspace or \vskip:
else if (["\\vskip", "\\vspace"].includes(command[1].trim())) {
// console.log("VSPACE");
return "<!-- " + command[1] + text + " -->\n";
}
// All other cases, just leave a comment:
else {
return "<!-- " + command[1] + " -->\n<p>\n\t" + convertP(text) + "\n</p>\n";
}
}
}

//////// Split text into array of lines //////////////////////

blockList.push(block);
block = "";
function makeLines(text: string) {
// Create an array of lines, with whitespace stripped from the beginning and end of each line.
let lines = text.split(/\r\n|\r|\n/);
lines = lines.map(line => line.trim());
// console.log("LINES: "+lines );
// console.log("LINES LENGTH: "+lines.length );

convertCheck = true;
// If lines contains multiple lines, we process it, otherwise just return the single line.
if (lines.length > 1) {
// Merge lines that start with regular characters into single lines.
let i = 0;
while (i < lines.length-1) {
if (lines[i].length > 0 && lines[i+1].length > 0 && !lines[i].startsWith("\\") && !lines[i+1].startsWith("\\")) {
lines[i] = lines[i] + " " + lines[i+1];
lines.splice(i+1,1);
} else {
if (textArray[i].trim().length === 0) {
block += "\n";
} else {
block += textArray[i].trim() + "\n";
}
if (i + 1 === loopCount) {
blockList.push(block);
}
i += 1;
}
}
// Then remove empty lines.
lines = lines.filter(line => line.length > 0);
}
// console.log("LINES: "+lines );
// console.log("LINES LENGTH: "+lines.length );
return lines;
// let loopCount = text.split(/\r\n|\r|\n/).length;
// let depth = 0;
// let block = "";
// console.log("TEXT ARRAY: " + lines);
// console.log("LOOP COUNT: " + lines.length);
// let i = 0;
// while (i < lines.length) {
// console.log("LINE: " + lines[i] + "; BLOCK: " + block);
// // If we are at depth 0 and we see regular text, assume we are at a start of a paragraph. Read until an empty line or a \begin is encountered.
// if (depth === 0) {
// if (lines[i].startsWith("\\begin")) {
// depth += 1;
// i += 1;
// } else if (lines[i].startsWith("\\end")) {
// lines[i-1] = lines[i-1]+"\n"+lines[i].
// depth -= 1;
// }

// }
// if (convertCheck) {
// if (lines[i].trim().length === 0) {
// block += "\n";
// blockList.push(block);
// block = "";
// continue;
// }
// if (lines[i].trim().startsWith("\\begin")) {
// block += lines[i].trim() + "\n";

// convertCheck = false;
// } else {
// if (i === 0) {
// block += lines[i].trim() + "\n";
// if (lines[i + 1].trim().length === 0) {
// blockList.push(block);
// block = "";
// }
// } else if (i + 1 === loopCount) {
// block += lines[i].trim() + "\n";
// blockList.push(block);
// block = "";
// } else {
// block += converter(lines[i]).trim() + "\n";
// if (lines[i + 1].trim().length === 0) {
// blockList.push(block);
// block = "";
// }
// }
// }
// } else {
// if (lines[i].trim().startsWith("\\end")) {
// block += lines[i].trim();

// blockList.push(block);
// block = "";

// convertCheck = true;
// } else {
// if (lines[i].trim().length === 0) {
// block += "\n";
// } else {
// block += lines[i].trim() + "\n";
// }
// if (i + 1 === loopCount) {
// blockList.push(block);
// }
// }
// }
// }

// //log each block in terminal to see how it is building as test
// for (var blockCheck of blockList) {
// console.log("BLOCK CHECK: " + blockCheck);
// }

return blockList;
// return blockList;
}

function convertBlockList(blockList: Array<string>) {
function convertLines(lines: string[]) {
// We put the lines back together into a single string, with each line converted into its proper PreTeXt form.
var result = "";
for (let block of blockList) {
if (block.trim().length === 0) {
for (let line of lines) {
if (line.length === 0) {
result += "\n";
}
//block is a \begin/\end block skip for now.
else if (block.trim().startsWith("\\begin")) {
const blockArray = block.split("\n");

const insideBlock = blockArray.slice(1, -1);
result +=
"<block>\n\t" +
convertBlockList(getBlockList(insideBlock.join("\n"))) +
"\n</block>";

//additional conditionals can be added within this section for /begin blocks to detemine convert|!convert
// result += block;
//line is a \begin/\end: convert to pretext block
else if (line.startsWith("\\begin")) {
let env = line.match(/\\begin{(.*?)}/);
if (env !== null){
if (env[1] in BLOCKS) {
result += "<" + BLOCKS[env[1]] + ">\n\t";
} else {
result += "<!-- START " + env[1] + " environment (not defined in PreTeXt) -->\n\t";
}
}
} else if (line.startsWith("\\end")) {
let env = line.match(/\\end{(.*?)}/);
if (env !== null){
if (env[1] in BLOCKS) {
result += "\n</" + BLOCKS[env[1]] + ">\n";
} else {
result += "<!-- END " + env[1] + " environment -->\n";
}
}
}
//Block likely a paragraph run a converter on the block.
//Line starts with a backslash command; could be something like \item
else if (line.startsWith("\\")){
result += convertBS(line);
}
// Otherwise we assume it is a paragraph.
else {
if (block.trim().startsWith("\\")) {
result += converter(block);
} else {
result += "<p>\n" + converter(block) + "</p>\n";
}
result += "<p>\n\t" + convertP(line) + "\n</p>\n";
}
}
return result;
@@ -169,7 +253,7 @@ function convertBlockList(blockList: Array<string>) {
// return result;
// }
export function latexToPretext(text: string) {
var result = convertBlockList(getBlockList(text));
var result = convertLines(makeLines(text));

return result;
}
File renamed without changes.

0 comments on commit 1975c2f

Please sign in to comment.