Ingen beskrivning
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

card.js 30KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. var RpgCards;
  2. (function (RpgCards) {
  3. function normalizeTag(tag) {
  4. return tag.trim().toLowerCase();
  5. }
  6. function splitParams(value) {
  7. return value.split("|").map(function (str) {
  8. return str.trim();
  9. });
  10. }
  11. var Options = (function () {
  12. function Options() {
  13. this.foreground_color = "white";
  14. this.background_color = "white";
  15. this.empty_color = "black";
  16. this.default_color = "black";
  17. this.default_icon = "";
  18. this.default_title_size = "13";
  19. this.page_size = "A4";
  20. this.page_rows = 3;
  21. this.page_columns = 3;
  22. this.card_arrangement = "doublesided";
  23. this.card_size = "25x35";
  24. this.card_count = null;
  25. this.icon_inline = true;
  26. }
  27. return Options;
  28. })();
  29. RpgCards.Options = Options;
  30. var Card = (function () {
  31. function Card() {
  32. this.count = 1;
  33. this.title = "New card";
  34. this.title_size = null;
  35. this.title_icon_text = null;
  36. this.color = null;
  37. this.color_front = null;
  38. this.color_back = null;
  39. this.icon = null;
  40. this.icon_front = null;
  41. this.icon_back = null;
  42. this.contents = [];
  43. this.tags = [];
  44. this.userData = null;
  45. }
  46. Card.fromJSON = function (json) {
  47. var result = new Card;
  48. result.count = json.count || 1;
  49. result.title = json.title || "";
  50. result.title_size = json.title_size || null;
  51. result.title_icon_text = json.title_icon_text || null;
  52. result.color = json.color || null;
  53. result.color_front = json.color_front || null;
  54. result.color_back = json.color_back || null;
  55. result.icon = json.icon || null;
  56. result.icon_front = json.icon_front || null;
  57. result.icon_back = json.icon_back || null;
  58. result.contents = json.contents || [];
  59. result.tags = json.tags || [];
  60. return result;
  61. };
  62. Card.prototype.toJSON = function () {
  63. return {
  64. count: this.count,
  65. title: this.title,
  66. title_size: this.title_size,
  67. title_icon_text: this.title_icon_text,
  68. color: this.color,
  69. color_front: this.color_front,
  70. color_back: this.color_back,
  71. icon: this.icon,
  72. icon_front: this.icon_front,
  73. icon_back: this.icon_back,
  74. contents: this.contents.slice(),
  75. tags: this.tags.slice()
  76. };
  77. };
  78. Card.prototype.duplicate = function () {
  79. var result = Card.fromJSON(this.toJSON());
  80. result.title += " (Copy)";
  81. return result;
  82. };
  83. Card.prototype.hasTag = function (tag) {
  84. var index = this.tags.indexOf(normalizeTag(tag));
  85. return index > -1;
  86. };
  87. Card.prototype.addTag = function (tag) {
  88. if (!this.hasTag(tag)) {
  89. this.tags.push(normalizeTag(tag));
  90. }
  91. };
  92. Card.prototype.removeTag = function (tag) {
  93. var ntag = normalizeTag(tag);
  94. this.tags = this.tags.filter(function (t) {
  95. return ntag != t;
  96. });
  97. };
  98. Card.prototype.findTag = function (pattern, flags) {
  99. var f = flags || "g";
  100. var regexp = new RegExp(pattern, f);
  101. var s = this.tags.join("\n");
  102. return regexp.exec(s);
  103. };
  104. Card.prototype.replaceTag = function (pattern, substitution, flags) {
  105. var f = flags || "g";
  106. var regexp = new RegExp(pattern, f);
  107. this.tags = this.tags.map(function (s) { return s.replace(regexp, substitution); });
  108. };
  109. Card.prototype.findContent = function (pattern, flags) {
  110. var f = flags || "g";
  111. var regexp = new RegExp(pattern, f);
  112. var s = this.contents.join("\n");
  113. return regexp.exec(s);
  114. };
  115. Card.prototype.replaceContent = function (pattern, substitution, flags) {
  116. var f = flags || "g";
  117. var regexp = new RegExp(pattern, f);
  118. this.contents = this.contents.map(function (s) { return s.replace(regexp, substitution); });
  119. };
  120. Card.prototype.findTitle = function (pattern, flags) {
  121. var f = flags || "g";
  122. var regexp = new RegExp(pattern, f);
  123. var s = this.title;
  124. return regexp.exec(s);
  125. };
  126. Card.prototype.findTitleAny = function (patterns, flags) {
  127. for (var i = 0; i < patterns.length; ++i) {
  128. var f = flags || "g";
  129. var regexp = new RegExp(patterns[i], f);
  130. var s = this.title;
  131. var result = regexp.exec(s);
  132. if (result) {
  133. return result;
  134. }
  135. }
  136. return null;
  137. };
  138. Card.prototype.getTitle = function (options) {
  139. return this.title || "";
  140. };
  141. Card.prototype.getTitleSize = function (options) {
  142. return this.title_size || options.default_title_size || "13";
  143. };
  144. Card.prototype.getTitleIconText = function (options) {
  145. return this.title_icon_text || "";
  146. };
  147. Card.prototype.getColorFront = function (options) {
  148. return this.color_front || this.color || options.default_color || "black";
  149. };
  150. Card.prototype.getColorBack = function (options) {
  151. return this.color_back || this.color || options.default_color || "black";
  152. };
  153. Card.prototype.getIconFront = function (options) {
  154. return this.icon_front || this.icon || options.default_icon || "";
  155. };
  156. Card.prototype.getIconBack = function (options) {
  157. return this.icon_back || this.icon || options.default_icon || "";
  158. };
  159. return Card;
  160. })();
  161. RpgCards.Card = Card;
  162. ;
  163. var CardDeck = (function () {
  164. function CardDeck() {
  165. this.cards = [];
  166. this._actions = [];
  167. }
  168. CardDeck.prototype.toJSON = function () {
  169. return this.cards.map(function (card) { return card.toJSON(); });
  170. };
  171. CardDeck.fromJSON = function (data) {
  172. if (Array.isArray(data)) {
  173. var result = new CardDeck;
  174. for (var i = 0; i < data.length; ++i) {
  175. result.cards.push(Card.fromJSON(data[i]));
  176. }
  177. return result;
  178. }
  179. else {
  180. throw new Error("Invalid data");
  181. }
  182. };
  183. CardDeck.prototype.addCards = function (cards) {
  184. var _this = this;
  185. cards.forEach(function (card) {
  186. _this._actions.push({ fn: "add", card: card, ref: null });
  187. });
  188. };
  189. CardDeck.prototype.addNewCard = function () {
  190. var newCard = new Card();
  191. this._actions.push({ fn: "add", card: newCard, ref: null });
  192. return newCard;
  193. };
  194. CardDeck.prototype.duplicateCard = function (card) {
  195. var newCard = card.duplicate();
  196. this._actions.push({ fn: "add", card: newCard, ref: card });
  197. return newCard;
  198. };
  199. CardDeck.prototype.deleteCard = function (card) {
  200. this._actions.push({ fn: "del", card: card, ref: null });
  201. };
  202. CardDeck.prototype.commit = function () {
  203. for (var i = 0; i < this._actions.length; ++i) {
  204. var action = this._actions[i];
  205. if (action.fn === "add") {
  206. var index = this.cards.indexOf(action.ref);
  207. if (index > -1) {
  208. this.cards.splice(index + 1, 0, action.card);
  209. }
  210. else {
  211. this.cards.push(action.card);
  212. }
  213. }
  214. else if (action.fn === "del") {
  215. var index = this.cards.indexOf(action.card);
  216. if (index > -1) {
  217. this.cards.splice(index, 1);
  218. }
  219. }
  220. }
  221. this._actions = [];
  222. };
  223. return CardDeck;
  224. })();
  225. RpgCards.CardDeck = CardDeck;
  226. var CardHtmlGenerator = (function () {
  227. function CardHtmlGenerator() {
  228. }
  229. CardHtmlGenerator.prototype._icon = function (src, ind, ind0) {
  230. if (src.length > 0) {
  231. return ind + '<card-icon src="./icons/' + src + '.svg"></card-icon>\n';
  232. }
  233. else {
  234. return "";
  235. }
  236. };
  237. CardHtmlGenerator.prototype._subtitle = function (params, card, options, ind, ind0) {
  238. var text = params[0] || "";
  239. return ind + '<card-subtitle>' + text + '</card-subtitle>\n';
  240. };
  241. CardHtmlGenerator.prototype._ruler = function (params, card, options, ind, ind0) {
  242. return ind + '<card-rule></card-rule>\n';
  243. };
  244. CardHtmlGenerator.prototype._boxes = function (params, card, options, ind, ind0) {
  245. var count = params[0] || 1;
  246. var size = params[1] || 3;
  247. return ind + '<card-boxes size="' + size + '" count="' + count + '"></card-boxes>\n';
  248. };
  249. CardHtmlGenerator.prototype._property = function (params, card, options, ind, ind0) {
  250. var header = params[0] || "";
  251. var text = params[1] || "";
  252. var result = "";
  253. result += ind + '<card-property>\n';
  254. result += ind + ind0 + '<h4>' + header + '</h4>\n';
  255. result += ind + ind0 + '<p>' + text + '</p>\n';
  256. result += ind + '</card-property>\n';
  257. return result;
  258. };
  259. CardHtmlGenerator.prototype._description = function (params, card, options, ind, ind0) {
  260. var header = params[0] || "";
  261. var text = params[1] || "";
  262. var result = "";
  263. result += ind + '<card-description>\n';
  264. result += ind + ind0 + '<h4>' + header + '</h4>\n';
  265. result += ind + ind0 + '<p>' + text + '</p>\n';
  266. result += ind + '</card-description>\n';
  267. return result;
  268. };
  269. CardHtmlGenerator.prototype._text = function (params, card, options, ind, ind0) {
  270. var text = params[0] || "";
  271. var result = "";
  272. result += ind + '<card-description>\n';
  273. result += ind + ind0 + '<p>' + text + '</p>\n';
  274. result += ind + '</card-description>\n';
  275. return result;
  276. };
  277. CardHtmlGenerator.prototype._dndstats = function (params, card, options, ind, ind0) {
  278. var stats = ["str", "dex", "con", "int", "wis", "cha"];
  279. var result = "";
  280. result += ind + '<card-dndstats';
  281. for (var i = 0; i < stats.length; ++i) {
  282. var value = params[i] || "";
  283. var stat = stats[i];
  284. result += ' ' + stat + '="' + value + '"';
  285. }
  286. result += '></card-dndstats>\n';
  287. return result;
  288. };
  289. CardHtmlGenerator.prototype._bullet = function (params, card, options, ind, ind0) {
  290. var text = params[0] || "";
  291. return ind + '<card-bullet>' + text + '</card-bullet>\n';
  292. };
  293. CardHtmlGenerator.prototype._section = function (params, card, options, ind, ind0) {
  294. var text = params[0] || "";
  295. return ind + '<card-section>' + text + '</card-section>\n';
  296. };
  297. CardHtmlGenerator.prototype._fill = function (params, card, options, ind, ind0) {
  298. var size = params[0] || "1";
  299. return ind + '<card-fill size="' + size + '"></card-fill>\n';
  300. };
  301. CardHtmlGenerator.prototype._vspace = function (params, card, options, ind, ind0) {
  302. var size = params[0] || "1em";
  303. return ind + '<card-vspace size="' + size + '"></card-vspace>\n';
  304. };
  305. CardHtmlGenerator.prototype._unknown = function (params, card, options, ind, ind0) {
  306. var text = params.join(' | ');
  307. return ind + '<card-description><p>' + text + '</p></card-description>\n';
  308. };
  309. CardHtmlGenerator.prototype._empty = function (params, card, options, ind, ind0) {
  310. return '';
  311. };
  312. CardHtmlGenerator.prototype._contents = function (contents, card, options, ind, ind0) {
  313. var _this = this;
  314. var result = "";
  315. result += ind + '<card-contents>\n';
  316. result += contents.map(function (value) {
  317. var parts = splitParams(value);
  318. var name = parts[0];
  319. var params = parts.splice(1);
  320. var generator = null;
  321. switch (name) {
  322. case "subtitle":
  323. generator = _this._subtitle;
  324. break;
  325. case "property":
  326. generator = _this._property;
  327. break;
  328. case "rule":
  329. generator = _this._ruler;
  330. break;
  331. case "ruler":
  332. generator = _this._ruler;
  333. break;
  334. case "boxes":
  335. generator = _this._boxes;
  336. break;
  337. case "description":
  338. generator = _this._description;
  339. break;
  340. case "dndstats":
  341. generator = _this._dndstats;
  342. break;
  343. case "text":
  344. generator = _this._text;
  345. break;
  346. case "bullet":
  347. generator = _this._bullet;
  348. break;
  349. case "fill":
  350. generator = _this._fill;
  351. break;
  352. case "vspace":
  353. generator = _this._vspace;
  354. break;
  355. case "section":
  356. generator = _this._section;
  357. break;
  358. case "disabled":
  359. generator = _this._empty;
  360. break;
  361. case "":
  362. generator = _this._empty;
  363. break;
  364. default: return _this._unknown(parts, card, options, ind, ind0);
  365. }
  366. return generator(params, card, options, ind + ind0, ind);
  367. }).join("\n");
  368. result += ind + '</card-contents>\n';
  369. return result;
  370. };
  371. CardHtmlGenerator.prototype._title = function (card, options, ind, ind0) {
  372. var title = card.getTitle(options);
  373. var title_size = card.getTitleSize(options);
  374. var title_icon_text = card.getTitleIconText(options);
  375. var icon = card.getIconFront(options);
  376. var result = "";
  377. result += ind + '<card-title size="' + title_size + '">\n';
  378. result += ind + ind0 + '<h1>' + title + '</h1>\n';
  379. result += ind + ind0 + '<h2>' + title_icon_text + '</h2>\n';
  380. result += this._icon(icon, ind + ind0, ind0);
  381. result += ind + '</card-title>\n';
  382. return result;
  383. };
  384. CardHtmlGenerator.prototype._card_front = function (card, options, ind, ind0) {
  385. var result = "";
  386. result += this._title(card, options, ind + ind0, ind0);
  387. result += this._contents(card.contents, card, options, ind + ind0, ind0);
  388. return result;
  389. };
  390. CardHtmlGenerator.prototype._card_back = function (card, options, ind, ind0) {
  391. var icon = card.getIconBack(options);
  392. var result = "";
  393. result += ind + '<card-back>\n';
  394. result += this._icon(icon, ind + ind0, ind);
  395. result += ind + '</card-back>\n';
  396. return result;
  397. };
  398. CardHtmlGenerator.prototype._card_empty = function (options, ind, ind0) {
  399. var result = "";
  400. result += ind + '<card-contents>\n';
  401. result += ind + '</card-contents>\n';
  402. return result;
  403. };
  404. CardHtmlGenerator.prototype._card = function (options, ind, ind0, content, color) {
  405. var size = options.card_size || "25x35";
  406. var result = "";
  407. result += ind + '<rpg-card color="' + color + '" size="' + size + '">\n';
  408. result += content;
  409. result += ind + '</rpg-card>\n';
  410. return result;
  411. };
  412. /** Generates HTML for the front side of the given card */
  413. CardHtmlGenerator.prototype.card_front = function (card, options, indent) {
  414. var content = this._card_front(card, options, "", indent);
  415. return this._card(options, "", indent, content, card.getColorFront(options));
  416. };
  417. /** Generates HTML for the back side of the given card */
  418. CardHtmlGenerator.prototype.card_back = function (card, options, indent) {
  419. var content = this._card_back(card, options, "", indent);
  420. return this._card(options, "", indent, content, card.getColorBack(options));
  421. };
  422. /** Generates HTML for an empty given card */
  423. CardHtmlGenerator.prototype.card_empty = function (options, indent) {
  424. var content = this._card_empty(options, "", indent);
  425. return this._card(options, "", indent, content, options.empty_color);
  426. };
  427. return CardHtmlGenerator;
  428. })();
  429. RpgCards.CardHtmlGenerator = CardHtmlGenerator;
  430. var CardPage = (function () {
  431. function CardPage(rows, cols) {
  432. this.rows = rows;
  433. this.cols = cols;
  434. this.cards = [];
  435. }
  436. /** Returns an empty page with the same dimensions */
  437. CardPage.prototype.newPage = function () {
  438. return new CardPage(this.rows, this.cols);
  439. };
  440. CardPage.prototype._posToIndex = function (row, col) {
  441. return row * this.cols + col;
  442. };
  443. /** Adds one card to the page */
  444. CardPage.prototype.addCard = function (card) {
  445. if (this.capacity() === 0) {
  446. throw new Error("This page is full.");
  447. }
  448. this.cards.push(card);
  449. };
  450. /**
  451. Adds several copies of a card to the page.
  452. Returns the number of copies that did not fit on the page.
  453. */
  454. CardPage.prototype.addCards = function (card, count) {
  455. while (this.capacity() > 0 && count > 0) {
  456. this.addCard(card);
  457. --count;
  458. }
  459. return count;
  460. };
  461. /** Fills all remaining slots on the current row with the given card */
  462. CardPage.prototype.fillRow = function (card) {
  463. while (this.capacityRow() > 0) {
  464. this.addCard(card);
  465. }
  466. };
  467. /** Fills all remaining slots on the page with empty cards */
  468. CardPage.prototype.fillPage = function (card) {
  469. while (this.capacity() > 0) {
  470. this.addCard(card);
  471. }
  472. };
  473. /** Empty slots on the page */
  474. CardPage.prototype.capacity = function () {
  475. return this.rows * this.cols - this.cards.length;
  476. };
  477. /** Empty slots on the current line */
  478. CardPage.prototype.capacityRow = function () {
  479. return this.capacity() % this.cols;
  480. };
  481. /** Flip card slots horizontally */
  482. CardPage.prototype.flipH = function () {
  483. if (this.capacity() > 0) {
  484. throw new Error("Cannot perform this operation while the page is not full");
  485. }
  486. for (var r = 0; r < this.rows; ++r) {
  487. for (var c = 0; c < Math.floor(this.cols / 2); ++c) {
  488. var indexL = this._posToIndex(r, c);
  489. var indexR = this._posToIndex(r, this.cols - c - 1);
  490. var cardL = this.cards[indexL];
  491. var cardR = this.cards[indexR];
  492. this.cards[indexL] = cardR;
  493. this.cards[indexR] = cardL;
  494. }
  495. }
  496. };
  497. return CardPage;
  498. })();
  499. var CardPageSet = (function () {
  500. function CardPageSet(rows, cols) {
  501. this.rows = rows;
  502. this.cols = cols;
  503. this.pages = [];
  504. }
  505. CardPageSet.prototype.lastPage = function () {
  506. if (this.pages.length === 0) {
  507. return null;
  508. }
  509. else {
  510. return this.pages[this.pages.length - 1];
  511. }
  512. };
  513. CardPageSet.prototype.addPage = function () {
  514. var newPage = new CardPage(this.rows, this.cols);
  515. this.pages.push(newPage);
  516. return newPage;
  517. };
  518. /**
  519. Adds one card to the last page.
  520. Adds a new pages if necessary.
  521. */
  522. CardPageSet.prototype.addCard = function (card) {
  523. var page = this.lastPage();
  524. if (page === null || page.capacity() === 0) {
  525. page = this.addPage();
  526. }
  527. page.addCard(card);
  528. };
  529. /**
  530. Adds several copies of a card to the last page.
  531. Adds new pages if necessary.
  532. */
  533. CardPageSet.prototype.addCards = function (card, count) {
  534. for (var i = 0; i < count; ++i) {
  535. this.addCard(card);
  536. }
  537. };
  538. CardPageSet.prototype.forEach = function (fn) {
  539. this.pages.forEach(fn);
  540. };
  541. CardPageSet.prototype.merge = function (other) {
  542. if (this.pages.length !== other.pages.length) {
  543. throw new Error("This function is only for merging two equally sized page sets");
  544. }
  545. var result = new CardPageSet(this.rows, this.cols);
  546. for (var i = 0; i < this.pages.length; ++i) {
  547. result.pages.push(this.pages[i]);
  548. result.pages.push(other.pages[i]);
  549. }
  550. return result;
  551. };
  552. return CardPageSet;
  553. })();
  554. var BoxSize = (function () {
  555. function BoxSize(p, w, h, wpx, hpx) {
  556. this.page = p;
  557. this.width = w;
  558. this.height = h;
  559. this.width_px = Math.floor(wpx);
  560. this.height_px = Math.floor(hpx);
  561. }
  562. return BoxSize;
  563. })();
  564. var boxSizes = {};
  565. boxSizes["auto"] = new BoxSize("auto", "auto", "auto", Infinity, Infinity);
  566. boxSizes["A2"] = new BoxSize("A2 portrait", "420mm", "594mm", 1587.401575, 2245.03937);
  567. boxSizes["A3"] = new BoxSize("A3 portrait", "297mm", "420mm", 1118.740158, 1587.401575);
  568. boxSizes["A4"] = new BoxSize("A4 portrait", "210mm", "297mm", 793.700787, 1118.740158);
  569. boxSizes["A5"] = new BoxSize("A5 portrait", "148mm", "210mm", 559.370079, 793.700787);
  570. boxSizes["Letter"] = new BoxSize("Letter portrait", "8.5in", "11in", 816, 1056);
  571. boxSizes["225x35"] = new BoxSize("2.25in 3.5in", "2.25in", "3.5in", 216, 336);
  572. boxSizes["25x35"] = new BoxSize("2.5in 3.5in", "2.5in", "3.5in", 240, 336);
  573. boxSizes["35x50"] = new BoxSize("3.5in 5.0in", "3.5in", "5.0in", 336, 480);
  574. boxSizes["50x70"] = new BoxSize("5.0in 7.0in", "5.0in", "7.0in", 480, 672);
  575. var PageHtmlGenerator = (function () {
  576. function PageHtmlGenerator() {
  577. this.indent = " ";
  578. }
  579. PageHtmlGenerator.prototype._pageColor = function (page, options) {
  580. if ((options.card_arrangement == "doublesided") && (page % 2 == 1)) {
  581. return options.background_color;
  582. }
  583. else {
  584. return options.foreground_color;
  585. }
  586. };
  587. PageHtmlGenerator.prototype._wrap = function (pageSet, options) {
  588. var result = "";
  589. for (var i = 0; i < pageSet.pages.length; ++i) {
  590. var page = pageSet.pages[i];
  591. var style = ' style="background-color:' + this._pageColor(i, options) + '"';
  592. result += '<card-page' + style + '>\n';
  593. result += page.cards.join("");
  594. result += '</card-page>\n';
  595. }
  596. return result;
  597. };
  598. PageHtmlGenerator.prototype._generatePagesDoublesided = function (cards, options, rows, cols, generator) {
  599. var front_pages = new CardPageSet(rows, cols);
  600. var back_pages = new CardPageSet(rows, cols);
  601. var empty = generator.card_empty(options, this.indent);
  602. for (var i = 0; i < cards.length; ++i) {
  603. var card = cards[i];
  604. var front = generator.card_front(card, options, this.indent);
  605. var back = generator.card_back(card, options, this.indent);
  606. front_pages.addCards(front, card.count);
  607. back_pages.addCards(back, card.count);
  608. }
  609. // Fill empty slots
  610. front_pages.forEach(function (page) { return page.fillPage(empty); });
  611. back_pages.forEach(function (page) { return page.fillPage(empty); });
  612. // Shuffle back cards so that they line up with their corresponding front cards
  613. back_pages.forEach(function (page) { return page.flipH(); });
  614. // Interleave front and back pages so that we can print double-sided
  615. return front_pages.merge(back_pages);
  616. };
  617. PageHtmlGenerator.prototype._generatePagesFrontOnly = function (cards, options, rows, cols, generator) {
  618. var pages = new CardPageSet(rows, cols);
  619. var empty = generator.card_empty(options, this.indent);
  620. for (var i = 0; i < cards.length; ++i) {
  621. var card = cards[i];
  622. var front = generator.card_front(card, options, this.indent);
  623. pages.addCards(front, card.count);
  624. }
  625. // Fill empty slots
  626. pages.forEach(function (page) { return page.fillPage(empty); });
  627. return pages;
  628. };
  629. PageHtmlGenerator.prototype._generatePagesSideBySide = function (cards, options, rows, cols, generator) {
  630. if (cols < 2) {
  631. throw new Error("Need at least two columns for side-by-side");
  632. }
  633. var pages = new CardPageSet(rows, cols);
  634. var empty = generator.card_empty(options, this.indent);
  635. for (var i = 0; i < cards.length; ++i) {
  636. var card = cards[i];
  637. var front = generator.card_front(card, options, this.indent);
  638. var back = generator.card_back(card, options, this.indent);
  639. for (var j = 0; j < card.count; ++j) {
  640. if (pages.pages.length > 0 && pages.lastPage().capacityRow() < 2) {
  641. pages.lastPage().fillRow(empty);
  642. }
  643. pages.addCard(front);
  644. pages.addCard(back);
  645. }
  646. }
  647. // Fill empty slots
  648. pages.forEach(function (page) { return page.fillPage(empty); });
  649. return pages;
  650. };
  651. PageHtmlGenerator.prototype._generatePages = function (cards, options, rows, cols, generator) {
  652. switch (options.card_arrangement) {
  653. case "doublesided": return this._generatePagesDoublesided(cards, options, rows, cols, generator);
  654. case "front_only": return this._generatePagesFrontOnly(cards, options, rows, cols, generator);
  655. case "side_by_side": return this._generatePagesSideBySide(cards, options, rows, cols, generator);
  656. default: throw new Error("Unknown card arrangement");
  657. }
  658. };
  659. PageHtmlGenerator.prototype._generateStyle = function (options) {
  660. var page_box = boxSizes[options.page_size] || boxSizes["auto"];
  661. var result = '';
  662. result += '<style type="text/css">\n';
  663. result += 'body {\n';
  664. result += ' display: block;\n';
  665. result += ' background: rgb(204, 204, 204);\n';
  666. result += '}\n';
  667. result += 'card-page {\n';
  668. result += ' width: ' + (page_box.width_px) + 'px;\n';
  669. result += ' height: ' + (page_box.height_px) + 'px;\n';
  670. result += '}\n';
  671. result += '@media print {\n';
  672. result += ' html, body {\n';
  673. result += ' width: ' + page_box.width_px + 'px;\n';
  674. result += ' }\n';
  675. result += ' body {\n';
  676. result += ' margin: 0;\n';
  677. result += ' padding: 0;\n';
  678. result += ' border: 0;\n';
  679. result += ' }\n';
  680. result += '}\n';
  681. result += '@page {\n';
  682. result += ' margin: 0;\n';
  683. result += ' size:' + page_box.width_px + 'px ' + page_box.height_px + 'px;\n';
  684. result += ' -webkit-print-color-adjust: exact;\n';
  685. result += '}\n';
  686. result += '</style>\n';
  687. return result;
  688. };
  689. PageHtmlGenerator.prototype.generateHtml = function (cards, options) {
  690. options = options || new Options();
  691. var rows = options.page_rows || 3;
  692. var cols = options.page_columns || 3;
  693. // Generate the HTML for each card
  694. var generator = new CardHtmlGenerator();
  695. var pages = this._generatePages(cards, options, rows, cols, generator);
  696. // Wrap all pages in a <page> element
  697. var document = this._wrap(pages, options);
  698. // Generate the HTML for the page layout
  699. var style = this._generateStyle(options);
  700. // Wrap all pages in a <page> element and add CSS for the page size
  701. var result = "";
  702. result += style;
  703. result += document;
  704. return result;
  705. };
  706. PageHtmlGenerator.prototype.insertInto = function (cards, options, container) {
  707. while (container.hasChildNodes()) {
  708. container.removeChild(container.lastChild);
  709. }
  710. // Insert the HTML
  711. var html = this.generateHtml(cards, options);
  712. container.innerHTML = html;
  713. };
  714. return PageHtmlGenerator;
  715. })();
  716. RpgCards.PageHtmlGenerator = PageHtmlGenerator;
  717. })(RpgCards || (RpgCards = {}));
  718. //# sourceMappingURL=card.js.map