Skip to content

Commit 72ac68c

Browse files
committed
Merge pull request microsoft#749 from Microsoft/specInMarkdown
Language Specification in Markdown format
2 parents 5fb50d8 + a8514da commit 72ac68c

8 files changed

+5790
-0
lines changed
Binary file not shown.
Binary file not shown.
12.5 KB
Binary file not shown.
-3 KB
Binary file not shown.

doc/header.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# TypeScript Language Specification
2+

doc/spec.md

+5,274
Large diffs are not rendered by default.

scripts/word2md.js

+188
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
// word2md - Word to Markdown conversion tool
2+
//
3+
// word2md converts a Microsoft Word document to Markdown formatted text. The tool uses the
4+
// Word Automation APIs to start an instance of Word and access the contents of the document
5+
// being converted. The tool must be run using the cscript.exe script host and requires Word
6+
// to be installed on the target machine. The name of the document to convert must be specified
7+
// as a command line argument and the resulting Markdown is written to standard output. The
8+
// tool recognizes the specific Word styles used in the TypeScript Language Specification.
9+
var sys = (function () {
10+
var args = [];
11+
for (var i = 0; i < WScript.Arguments.length; i++) {
12+
args[i] = WScript.Arguments.Item(i);
13+
}
14+
return {
15+
args: args,
16+
createObject: function (typeName) { return new ActiveXObject(typeName); },
17+
write: function (s) { return WScript.StdOut.Write(s); }
18+
};
19+
})();
20+
function convertDocumentToMarkdown(doc) {
21+
var result = "";
22+
var lastStyle;
23+
var lastInTable;
24+
var tableColumnCount;
25+
var tableCellIndex;
26+
var columnAlignment = [];
27+
function setProperties(target, properties) {
28+
for (var name in properties) {
29+
if (properties.hasOwnProperty(name)) {
30+
var value = properties[name];
31+
if (typeof value === "object") {
32+
setProperties(target[name], value);
33+
}
34+
else {
35+
target[name] = value;
36+
}
37+
}
38+
}
39+
}
40+
function findReplace(findText, findProps, replaceText, replaceProps) {
41+
var find = doc.range().find;
42+
find.clearFormatting();
43+
setProperties(find, findProps);
44+
var replace = find.replacement;
45+
replace.clearFormatting();
46+
setProperties(replace, replaceProps);
47+
find.execute(findText, false, false, false, false, false, true, 0, true, replaceText, 2);
48+
}
49+
function write(s) {
50+
result += s;
51+
}
52+
function writeTableHeader() {
53+
for (var i = 0; i < tableColumnCount - 1; i++) {
54+
switch (columnAlignment[i]) {
55+
case 1:
56+
write("|:---:");
57+
break;
58+
case 2:
59+
write("|---:");
60+
break;
61+
default:
62+
write("|---");
63+
}
64+
}
65+
write("|\n");
66+
}
67+
function trimEndFormattingMarks(text) {
68+
var i = text.length;
69+
while (i > 0 && text.charCodeAt(i - 1) < 0x20)
70+
i--;
71+
return text.substr(0, i);
72+
}
73+
function writeBlockEnd() {
74+
switch (lastStyle) {
75+
case "Code":
76+
write("```\n\n");
77+
break;
78+
case "List Paragraph":
79+
case "Table":
80+
case "TOC":
81+
write("\n");
82+
break;
83+
}
84+
}
85+
function writeParagraph(p) {
86+
var text = p.range.text;
87+
var style = p.style.nameLocal;
88+
var inTable = p.range.tables.count > 0;
89+
var level = 1;
90+
var sectionBreak = text.indexOf("\x0C") >= 0;
91+
text = trimEndFormattingMarks(text);
92+
if (inTable) {
93+
style = "Table";
94+
}
95+
else if (style.match(/\s\d$/)) {
96+
level = +style.substr(style.length - 1);
97+
style = style.substr(0, style.length - 2);
98+
}
99+
if (lastStyle && style !== lastStyle) {
100+
writeBlockEnd();
101+
}
102+
switch (style) {
103+
case "Heading":
104+
case "Appendix":
105+
var section = p.range.listFormat.listString;
106+
write("####".substr(0, level) + ' <a name="' + section + '"/>' + section + " " + text + "\n\n");
107+
break;
108+
case "Normal":
109+
if (text.length) {
110+
write(text + "\n\n");
111+
}
112+
break;
113+
case "List Paragraph":
114+
write(" ".substr(0, p.range.listFormat.listLevelNumber * 2 - 2) + "* " + text + "\n");
115+
break;
116+
case "Grammar":
117+
write("&emsp;&emsp;" + text.replace(/\s\s\s/g, "&emsp;").replace(/\x0B/g, " \n&emsp;&emsp;&emsp;") + "\n\n");
118+
break;
119+
case "Code":
120+
if (lastStyle !== "Code") {
121+
write("```TypeScript\n");
122+
}
123+
else {
124+
write("\n");
125+
}
126+
write(text.replace(/\x0B/g, " \n") + "\n");
127+
break;
128+
case "Table":
129+
if (!lastInTable) {
130+
tableColumnCount = p.range.tables.item(1).columns.count + 1;
131+
tableCellIndex = 0;
132+
}
133+
if (tableCellIndex < tableColumnCount) {
134+
columnAlignment[tableCellIndex] = p.alignment;
135+
}
136+
write("|" + text);
137+
tableCellIndex++;
138+
if (tableCellIndex % tableColumnCount === 0) {
139+
write("\n");
140+
if (tableCellIndex === tableColumnCount) {
141+
writeTableHeader();
142+
}
143+
}
144+
break;
145+
case "TOC Heading":
146+
write("## " + text + "\n\n");
147+
break;
148+
case "TOC":
149+
var strings = text.split("\t");
150+
write(" ".substr(0, level * 2 - 2) + "* [" + strings[0] + " " + strings[1] + "](#" + strings[0] + ")\n");
151+
break;
152+
}
153+
if (sectionBreak) {
154+
write("<br/>\n\n");
155+
}
156+
lastStyle = style;
157+
lastInTable = inTable;
158+
}
159+
function writeDocument() {
160+
for (var p = doc.paragraphs.first; p; p = p.next()) {
161+
writeParagraph(p);
162+
}
163+
writeBlockEnd();
164+
}
165+
findReplace("", { font: { subscript: true } }, "<sub>^&</sub>", { font: { subscript: false } });
166+
findReplace("", { style: "Code Fragment" }, "`^&`", { style: -66 /* default font */ });
167+
findReplace("", { style: "Production" }, "*^&*", { style: -66 /* default font */ });
168+
findReplace("", { style: "Terminal" }, "`^&`", { style: -66 /* default font */ });
169+
findReplace("", { font: { bold: true, italic: true } }, "***^&***", { font: { bold: false, italic: false } });
170+
findReplace("", { font: { italic: true } }, "*^&*", { font: { italic: false } });
171+
doc.fields.toggleShowCodes();
172+
findReplace("^19 REF", {}, "[^&](#^&)", {});
173+
doc.fields.toggleShowCodes();
174+
writeDocument();
175+
return result;
176+
}
177+
function main(args) {
178+
if (args.length !== 1) {
179+
sys.write("Syntax: word2md <filename>\n");
180+
return;
181+
}
182+
var app = sys.createObject("Word.Application");
183+
var doc = app.documents.open(args[0]);
184+
sys.write(convertDocumentToMarkdown(doc));
185+
doc.close(false);
186+
app.quit();
187+
}
188+
main(sys.args);

0 commit comments

Comments
 (0)