├── .gitignore ├── Makefile ├── README.md ├── american-political-science-association.csl ├── analysis.R ├── apsa-leeper.bst ├── manuscript-htlatex.docx ├── manuscript-pandoc-csl.docx ├── manuscript-pandoc.docx ├── manuscript.pdf ├── manuscript.tex └── references.bib /.gitignore: -------------------------------------------------------------------------------- 1 | *.4ct 2 | *.4tc 3 | *.aux 4 | *.bbl 5 | *.blg 6 | *.css 7 | *.dvi 8 | *.fdb_latexmk 9 | *.html 10 | *.idv 11 | *.ini 12 | *.lg 13 | *.lof 14 | *.log 15 | *.out 16 | *.synctex.gz 17 | *.tmp 18 | *.toc 19 | *.xref 20 | *.png 21 | *.bib.bak 22 | Rplots.pdf 23 | figures/figure.png 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: manuscript-htlatex.docx manuscript-pandoc.docx manuscript-pandoc-csl.docx 2 | 3 | manuscript-htlatex.docx: manuscript.html 4 | pandoc manuscript.html -o manuscript-htlatex.docx 5 | 6 | manuscript.html: manuscript.tex references.bib figure.png 7 | htlatex manuscript "html,fn-in" 8 | bibtex manuscript 9 | htlatex manuscript "html,fn-in" 10 | htlatex manuscript "html,fn-in" 11 | 12 | figure.png: analysis.R 13 | Rscript analysis.R 14 | 15 | manuscript-pandoc.docx: manuscript.html 16 | pandoc manuscript.tex -o manuscript-pandoc.docx 17 | 18 | manuscript-pandoc-csl.docx: manuscript.html 19 | pandoc manuscript.tex -o manuscript-pandoc-csl.docx --filter pandoc-citeproc --csl american-political-science-association.csl 20 | 21 | manuscript.pdf: manuscript.tex references.bib figure.png 22 | pdflatex manuscript 23 | bibtex manuscript 24 | pdflatex manuscript 25 | pdflatex manuscript 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Demo of `htlatex` build cycle 2 | 3 | This repository demonstrates how to get a word (.docx) document from a LaTeX (.tex) source file, preserving tables, equations, and references. 4 | 5 | (This demo uses make. So just type `make` on the command line. For a basic `make` demo, see [https://github.com/leeper/make-example](https://github.com/leeper/make-example).) 6 | 7 | There are a couple of strategies available here. 8 | 9 | ## `htlatex` 10 | 11 | I like `htlatex`. I works well, preserves cross-references, section numbers, citations, and equations. Other options include installing additional software, which might work better, but you already have `htlatex` installed with your TeX distribution. 12 | 13 | The build workflow - using `make` is two steps: 14 | 15 | ```bash 16 | htlatex manuscript "html,fn-in" 17 | bibtex manuscript 18 | htlatex manuscript "html,fn-in" 19 | htlatex manuscript "html,fn-in" 20 | pandoc manuscript.html -o manuscript-htlatex.docx 21 | ``` 22 | 23 | Note the second argument to `htlatex`, which delivers footnotes. For whatever reason they're not included in the HTML by default. 24 | 25 | This workflow, in my experience, is the best one available. Basically, you're buiding an HTML file and using `pandoc` to convert the well-formatted HTML into a word document. 26 | 27 | ## Basic `pandoc` 28 | 29 | An alternative is to call `pandoc` directly on the `.tex` file, but the result misses a lot: 30 | 31 | ```bash 32 | pandoc manuscript.tex -o manuscript-pandoc.docx 33 | ``` 34 | 35 | Note that cross-references and citations are messed up. An advantage is that equations are actually typeset in Word, rather than being images of the LaTeX equations (as above). If you have an equation-heavy document, this may be the way to go. Basically figure out which is better to resolve manually - equations or cross-references. 36 | 37 | ## `pandoc` with a CSL file 38 | 39 | Update: John McFarlane points out that the simple `pandoc` command is not appropriate. Instead, to preserve citations you need to specify a "citation style language" file and call a more verbose `pandoc` command. We'll use [this CSL file from the official CSL repo](https://github.com/citation-style-language/styles/blob/master/american-political-science-association.csl). 40 | 41 | ```bash 42 | pandoc manuscript.tex -o manuscript-pandoc.docx --filter pandoc-citeproc --csl american-political-science-association.csl 43 | ``` 44 | 45 | This gets references working quite well. 46 | -------------------------------------------------------------------------------- /american-political-science-association.csl: -------------------------------------------------------------------------------- 1 | 2 | 237 | -------------------------------------------------------------------------------- /analysis.R: -------------------------------------------------------------------------------- 1 | library("ggplot2") 2 | x <- rnorm(100L) 3 | p <- ggplot(, aes(x = x)) + geom_histogram() 4 | ggsave("figure.png", p, width = 4, height = 3) 5 | -------------------------------------------------------------------------------- /apsa-leeper.bst: -------------------------------------------------------------------------------- 1 | % BibTeX standard bibliography style `apsr' (one of the harvard family) version 0.99a for BibTeX versions 0.99a or later, LaTeX version 2.09. 2 | % Copyright (C) 2011, all rights reserved. 3 | % Copying of this file is authorized only if either: 4 | % (1) you make absolutely no changes to your copy, including name, or 5 | % (2) if you do make changes, you name it something other than btxbst.doc, plain.bst, unsrt.bst, alpha.bst, abbrv.bst, agsm.bst, dcu.bst or kluwer.bst, jmr.bst, apsr.bst. 6 | % This restriction helps ensure that all standard styles are identical. 7 | % The file harvard.tex has the documentation for this style. 8 | 9 | % ACKNOWLEDGEMENT: 10 | % This document is a modified version of alpha.bst and apsr.bst to which it owes much of its functionality. It has been adapted to produce American Political Science Association style references 11 | 12 | % Original Author 13 | % Peter Williams, Key Centre for Design Quality, Sydney University 14 | % e-mail: peterw@archsci.arch.su.oz.au 15 | 16 | % Additional changes by Bernd Beber, Columbia University, bhb2102@columbia.edu (August 2008) 17 | % Includes fixes for some minor formatting inconsistencies between current requirements for 18 | % the American Political Science Review and the style file apsr.bst distributed with the harvard LaTeX package: 19 | % * A comma is now placed before the word "and" when it separates author names in the bibliography; 20 | % * A comma is placed before the word "and" when it separates author names for in-text citations with more than two authors; 21 | % * A space is added between journal volume and issue, and colon and page numbers; 22 | % * For BibTeX item incollection, the chapter title is now quoted. 23 | 24 | %Additional changes by Michael P. Fix (mpfix1@gmail.com) and Susanne Schorpp (SCHORPP@mailbox.sc.edu), University of South Carolina (November 2009) 25 | % Includes fixes for minor formatting inconsistencies between the style file apsr.bst and the most recent revision of the APSA Style Manual for Political Science: 26 | %*Month is now placed in article citations in place of issue number, unless month is empty in which case issue number used 27 | %* The space between volume and month has been removed for article citations 28 | %* The ampersand symbol has been replaced with the word "and" to separate lists of two or more authors 29 | 30 | %Additional changes by Thomas J. Leeper, Northwestern University (thosjleeper@gmail.com) 31 | %Remove URL from reference list 32 | %Drops change.case functions from titles 33 | %Other changes marked in comments 34 | 35 | 36 | ENTRY 37 | { address 38 | author 39 | booktitle 40 | chapter 41 | edition 42 | editor 43 | howpublished 44 | institution 45 | journal 46 | key 47 | month 48 | note 49 | number 50 | organization 51 | pages 52 | publisher 53 | school 54 | series 55 | title 56 | type 57 | url %changed URL to url (for Mendeley) 58 | volume 59 | year 60 | } 61 | { field.used etal.allowed etal.required} %%%XXX change 62 | { extra.label sort.label list.year } 63 | 64 | INTEGERS { output.state before.all mid.sentence after.sentence after.block } 65 | 66 | FUNCTION {init.state.consts} 67 | { #0 'before.all := 68 | #1 'mid.sentence := 69 | #2 'after.sentence := 70 | #3 'after.block := 71 | } 72 | 73 | STRINGS { s t f } 74 | 75 | FUNCTION {output.nonnull} 76 | { 's := 77 | output.state mid.sentence = 78 | { " " * write$ } 79 | { output.state after.block = 80 | { add.period$ write$ 81 | newline$ 82 | "\newblock " write$ 83 | } 84 | { output.state before.all = 85 | 'write$ 86 | { add.period$ " " * write$ } 87 | if$ 88 | } 89 | if$ 90 | mid.sentence 'output.state := 91 | } 92 | if$ 93 | s 94 | } 95 | 96 | FUNCTION {output} 97 | { duplicate$ empty$ 98 | 'pop$ 99 | 'output.nonnull 100 | if$ 101 | } 102 | 103 | FUNCTION {output.check} 104 | { 't := 105 | duplicate$ empty$ 106 | { pop$ "empty " t * " in " * cite$ * warning$ } 107 | 'output.nonnull 108 | if$ 109 | } 110 | 111 | FUNCTION {item.check} 112 | { 't := 113 | empty$ 114 | { "empty " t * " in " * cite$ * warning$ } 115 | { skip$ } 116 | if$ 117 | } 118 | 119 | FUNCTION {fin.entry} 120 | { add.period$ 121 | write$ 122 | newline$ 123 | } 124 | 125 | FUNCTION {new.block} 126 | { output.state before.all = 127 | 'skip$ 128 | { after.block 'output.state := } 129 | if$ 130 | } 131 | 132 | FUNCTION {not} 133 | { { #0 } 134 | { #1 } 135 | if$ 136 | } 137 | 138 | FUNCTION {and} 139 | { 'skip$ 140 | { pop$ #0 } 141 | if$ 142 | } 143 | 144 | FUNCTION {or} 145 | { { pop$ #1 } 146 | 'skip$ 147 | if$ 148 | } 149 | 150 | FUNCTION {field.or.null} 151 | { duplicate$ empty$ 152 | { pop$ "" } 153 | 'skip$ 154 | if$ 155 | } 156 | 157 | FUNCTION {emphasize} 158 | { duplicate$ empty$ 159 | { pop$ "" } 160 | { "{\em " swap$ * "}" * } 161 | if$ 162 | } 163 | 164 | FUNCTION {embolden} 165 | { duplicate$ empty$ 166 | { pop$ "" } 167 | { "{\bf " swap$ * "}" * } 168 | if$ 169 | } 170 | 171 | FUNCTION {quote} 172 | { duplicate$ empty$ 173 | { pop$ "" } 174 | { "``" swap$ * "''" * } 175 | if$ 176 | } 177 | 178 | FUNCTION {write.url} %Removed URL reference from most things 179 | { url empty$ % changed URL to url 180 | { skip$ } 181 | % { "\newline\harvardurl{" url * "}" * write$ newline$ } % changed URL to url 182 | { "\url{" url * "}" * write$ newline$ } % changed URL to url; dropped newline and "URL:" 183 | if$ 184 | } 185 | 186 | INTEGERS { nameptr namesleft numnames } 187 | 188 | FUNCTION {format.rem.names} 189 | { 's := 190 | 'f := 191 | #2 'nameptr := 192 | s num.names$ 'numnames := 193 | numnames #1 - 'namesleft := 194 | { namesleft #0 > } 195 | { s nameptr f format.name$ 't := 196 | nameptr #1 > 197 | { namesleft #1 > 198 | { ", " * t * } 199 | { t "others" = 200 | { " et~al." * } 201 | % { ", \harvardand\ " * t * } %Adds comma after second-to-last author 202 | { numnames #2 > 203 | { ", and " * t * } 204 | { ", and " * t * } 205 | if$ 206 | } 207 | if$ 208 | } 209 | if$ 210 | } 211 | 't 212 | if$ 213 | nameptr #1 + 'nameptr := 214 | namesleft #1 - 'namesleft := 215 | } 216 | while$ 217 | } 218 | 219 | FUNCTION {format.authors} 220 | { author empty$ 221 | { "" } 222 | { author #1 "{vv~}{ll}{, jj}{, ff}" format.name$ 223 | "{ff }{vv~}{ll}{, jj}" author format.rem.names 224 | } 225 | if$ 226 | } 227 | 228 | FUNCTION {format.editors} 229 | { editor empty$ 230 | { "" } 231 | { editor #1 "{vv~}{ll}{, jj}{, ff}" format.name$ 232 | "{ff }{vv~}{ll}{, jj}" editor format.rem.names 233 | editor num.names$ #1 > 234 | { ", eds" * } 235 | { ", ed." * } 236 | if$ 237 | } 238 | if$ 239 | } 240 | 241 | FUNCTION {format.editors.reverse} 242 | { editor empty$ 243 | { "" } 244 | { editor num.names$ #1 > 245 | { ", eds. " * } 246 | { ", ed. " * } 247 | if$ 248 | editor #1 "{ff }{vv~}{ll}{, jj}" format.name$ 249 | "{ff }{vv~}{ll}{, jj}" editor format.rem.names 250 | } 251 | if$ 252 | } 253 | 254 | FUNCTION {format.title} 255 | { title empty$ 256 | %{ title empty$ change.case$ %Eliminate change.case function 257 | { "" } 258 | { title add.period$ } 259 | % { title add.period$ change.case$} %Eliminate change.case function 260 | if$ 261 | } 262 | 263 | FUNCTION {n.dashify} 264 | { 't := 265 | "" 266 | { t empty$ not } 267 | { t #1 #1 substring$ "-" = 268 | { t #1 #2 substring$ "--" = not 269 | { "--" * 270 | t #2 global.max$ substring$ 't := 271 | } 272 | { { t #1 #1 substring$ "-" = } 273 | { "-" * 274 | t #2 global.max$ substring$ 't := 275 | } 276 | while$ 277 | } 278 | if$ 279 | } 280 | { t #1 #1 substring$ * 281 | t #2 global.max$ substring$ 't := 282 | } 283 | if$ 284 | } 285 | while$ 286 | } 287 | 288 | FUNCTION {format.btitle} 289 | { title emphasize 290 | } 291 | 292 | FUNCTION {tie.or.space.connect} 293 | { duplicate$ text.length$ #3 < 294 | { "~" } 295 | { " " } 296 | if$ 297 | swap$ * * 298 | } 299 | 300 | FUNCTION {either.or.check} 301 | { empty$ 302 | 'pop$ 303 | { "can't use both " swap$ * " fields in " * cite$ * warning$ } 304 | if$ 305 | } 306 | 307 | FUNCTION {format.bvolume} 308 | { volume empty$ 309 | { "" } 310 | { "Vol." volume tie.or.space.connect 311 | series empty$ 312 | 'skip$ 313 | { " of " * series emphasize * } 314 | if$ 315 | "volume and number" number either.or.check 316 | } 317 | if$ 318 | } 319 | 320 | FUNCTION {format.number.series} 321 | { volume empty$ 322 | { number empty$ 323 | { series field.or.null } 324 | { output.state mid.sentence = 325 | { "number" } 326 | { "Number" } 327 | if$ 328 | number tie.or.space.connect 329 | series empty$ 330 | { "there's a number but no series in " cite$ * warning$ } 331 | { " {\em in} " * series quote * } 332 | if$ 333 | } 334 | if$ 335 | } 336 | { "" } 337 | if$ 338 | } 339 | 340 | FUNCTION {format.edition} 341 | { edition empty$ 342 | { "" } 343 | { output.state mid.sentence = 344 | { edition "l" change.case$ " ed." * } 345 | { edition "t" change.case$ " ed." * } 346 | if$ 347 | } 348 | if$ 349 | } 350 | 351 | INTEGERS { multiresult } 352 | 353 | FUNCTION {multi.page.check} 354 | { 't := 355 | #0 'multiresult := 356 | { multiresult not 357 | t empty$ not 358 | and 359 | } 360 | { t #1 #1 substring$ 361 | duplicate$ "-" = 362 | swap$ duplicate$ "," = 363 | swap$ "+" = 364 | or or 365 | { #1 'multiresult := } 366 | { t #2 global.max$ substring$ 't := } 367 | if$ 368 | } 369 | while$ 370 | multiresult 371 | } 372 | 373 | FUNCTION {format.pages} 374 | { pages empty$ 375 | { "" } 376 | { pages multi.page.check 377 | % { "pp.~" pages n.dashify * } %Eliminates "pp" in pages 378 | { ",~" pages n.dashify * } 379 | % { "p.~" pages * } 380 | { ",~" pages * } 381 | if$ 382 | } 383 | if$ 384 | } 385 | 386 | FUNCTION {format.address} 387 | { address empty$ 388 | { "" } 389 | { address ": " * 390 | } 391 | if$ 392 | } 393 | 394 | FUNCTION {format.confcity} %new conference city formatting 395 | { address empty$ 396 | { "" } 397 | { address ". " * 398 | } 399 | if$ 400 | } 401 | 402 | FUNCTION {format.vol.num.pages} 403 | { volume field.or.null 404 | number empty$ 405 | 'skip$ 406 | { "(" number * ")" * * 407 | volume empty$ 408 | { "there's a number but no volume in " cite$ * warning$ } 409 | 'skip$ 410 | if$ 411 | } 412 | if$ 413 | pages empty$ 414 | 'skip$ 415 | { duplicate$ empty$ 416 | { pop$ format.pages } 417 | { ":~" * pages n.dashify * } 418 | if$ 419 | } 420 | if$ 421 | } 422 | 423 | FUNCTION {format.chapter.pages} 424 | { chapter empty$ 425 | 'format.pages 426 | { chapter tie.or.space.connect 427 | pages empty$ 428 | 'skip$ 429 | { ", " * format.pages * } 430 | if$ 431 | } 432 | if$ 433 | } 434 | 435 | FUNCTION {format.in.ed.booktitle} 436 | { booktitle empty$ 437 | { "" } 438 | { editor empty$ 439 | { " In " booktitle emphasize * } 440 | { " In " booktitle emphasize * format.editors.reverse * } 441 | if$ 442 | } 443 | if$ 444 | } 445 | 446 | FUNCTION {format.inconf.title} %New Conference/Proceedings Title function 447 | { booktitle empty$ 448 | { "" } 449 | % { editor empty$ 450 | % { " Paper presented at " booktitle emphasize * } 451 | { " Paper presented at the " booktitle * } 452 | % { " In " booktitle emphasize * format.editors.reverse * } 453 | % if$ 454 | % } 455 | if$ 456 | } 457 | 458 | FUNCTION {empty.misc.check} 459 | { author empty$ title empty$ howpublished empty$ 460 | month empty$ year empty$ note empty$ 461 | and and and and and 462 | key empty$ not and 463 | { "all relevant fields are empty in " cite$ * warning$ } 464 | 'skip$ 465 | if$ 466 | } 467 | 468 | FUNCTION {format.thesis.type} 469 | { type empty$ 470 | 'skip$ 471 | { pop$ 472 | type "t" change.case$ 473 | } 474 | if$ 475 | } 476 | 477 | FUNCTION {format.tr.number} 478 | { type empty$ 479 | { "Technical Report" } 480 | 'type 481 | if$ 482 | number empty$ 483 | { "t" change.case$ } 484 | { number tie.or.space.connect } 485 | if$ 486 | } 487 | 488 | FUNCTION {format.article.crossref} 489 | { key empty$ 490 | { journal empty$ 491 | { "need key or journal for " cite$ * " to crossref " * crossref * 492 | warning$ 493 | "" 494 | } 495 | { "in {\em " journal * "\/} \cite{" * crossref * "}" *} 496 | if$ 497 | } 498 | { "{\em in} \citeasnoun{" crossref * "}" * } 499 | if$ 500 | 501 | } 502 | 503 | FUNCTION {format.book.crossref} 504 | { volume empty$ 505 | { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ 506 | "in " 507 | } 508 | { "Vol." volume tie.or.space.connect 509 | " of " * 510 | } 511 | if$ 512 | editor empty$ 513 | editor field.or.null author field.or.null = 514 | or 515 | { key empty$ 516 | { series empty$ 517 | { "need editor, key, or series for " cite$ * " to crossref " * 518 | crossref * warning$ 519 | "" * 520 | } 521 | { "{\em " * series * "\/} \cite{" * crossref * "}" *} 522 | if$ 523 | } 524 | { " \citeasnoun{" * crossref * "}" * } 525 | if$ 526 | } 527 | { " \citeasnoun{" * crossref * "}" * } 528 | if$ 529 | } 530 | 531 | FUNCTION {format.incoll.inproc.crossref} 532 | { editor empty$ 533 | editor field.or.null author field.or.null = 534 | or 535 | { key empty$ 536 | { booktitle empty$ 537 | { "need editor, key, or booktitle for " cite$ * " to crossref " * 538 | crossref * warning$ 539 | "" 540 | } 541 | { "in {\em " booktitle * "\/}" * " \cite{" * crossref * "}" *} 542 | if$ 543 | } 544 | { "{\em in} \citeasnoun{" crossref * "}" * } 545 | if$ 546 | } 547 | { "{\em in} \citeasnoun{" crossref * "}" * } 548 | if$ 549 | 550 | } 551 | 552 | INTEGERS { len } 553 | 554 | FUNCTION {chop.word} 555 | { 's := 556 | 'len := 557 | s #1 len substring$ = 558 | { s len #1 + global.max$ substring$ } 559 | 's 560 | if$ 561 | } 562 | 563 | INTEGERS { ind tsslen } 564 | 565 | STRINGS { tss ret rss istr } 566 | 567 | FUNCTION {replace.substring}{ 568 | 'rss := 569 | 'tss := 570 | 'istr := 571 | "" 'ret := 572 | tss text.length$ 'tsslen := 573 | #1 'ind := 574 | { istr ind tsslen substring$ "" = not } 575 | { istr ind tsslen substring$ tss = 576 | { ret rss * 'ret := 577 | ind tsslen + 'ind := 578 | } 579 | { ret istr ind #1 substring$ * 'ret := 580 | ind #1 + 'ind := 581 | } 582 | if$ 583 | } 584 | while$ 585 | ret 586 | } 587 | 588 | FUNCTION {format.lab.names.full} 589 | { 's := 590 | #1 'nameptr := 591 | s num.names$ 'numnames := 592 | numnames 'namesleft := 593 | { namesleft #0 > } 594 | { s nameptr "{vv~}{ll}" format.name$ 't := 595 | nameptr #1 > 596 | { namesleft #1 > 597 | { ", " * t * } 598 | { t "others" = 599 | { " et~al." * } 600 | % { " \harvardand\ " * t * } 601 | { numnames #2 > 602 | { ", and " * t * } 603 | { " and " * t * } 604 | if$ 605 | } 606 | if$ 607 | } 608 | if$ 609 | } 610 | 't 611 | if$ 612 | nameptr #1 + 'nameptr := 613 | namesleft #1 - 'namesleft := 614 | } 615 | while$ 616 | } 617 | 618 | FUNCTION {format.lab.names.abbr} 619 | { 's := 620 | s num.names$ 'numnames := 621 | numnames #1 > 622 | { numnames #3 > 623 | { s #1 "{vv~}{ll}" format.name$ " et~al." * } 624 | { s format.lab.names.full } 625 | if$ 626 | } 627 | { s #1 "{vv~}{ll}" format.name$ } 628 | if$ 629 | } 630 | 631 | INTEGERS { author.field editor.field organization.field title.field key.field } 632 | 633 | FUNCTION {init.field.constants} 634 | { #0 'author.field := 635 | #1 'editor.field := 636 | #2 'organization.field := 637 | #3 'title.field := 638 | #4 'key.field := 639 | } 640 | 641 | FUNCTION {make.list.label} 642 | { author.field field.used = 643 | { format.authors } 644 | { editor.field field.used = 645 | { format.editors } 646 | { organization.field field.used = 647 | { "The " #4 organization chop.word #3 text.prefix$ } 648 | { title.field field.used = 649 | { format.btitle } 650 | { key.field field.used = 651 | { key #3 text.prefix$ } 652 | { "Internal error :001 on " cite$ * " label" * warning$ } 653 | if$ 654 | } 655 | if$ 656 | } 657 | if$ 658 | } 659 | if$ 660 | } 661 | if$ 662 | } 663 | 664 | FUNCTION {make.full.label} 665 | { author.field field.used = 666 | { author format.lab.names.full } 667 | { editor.field field.used = 668 | { editor format.lab.names.full } 669 | { organization.field field.used = 670 | { "The " #4 organization chop.word #3 text.prefix$ } 671 | { title.field field.used = 672 | { format.btitle } 673 | { key.field field.used = 674 | { key #3 text.prefix$ } 675 | { "Internal error :001 on " cite$ * " label" * warning$ } 676 | if$ 677 | } 678 | if$ 679 | } 680 | if$ 681 | } 682 | if$ 683 | } 684 | if$ 685 | } 686 | 687 | FUNCTION {make.abbr.label} %%%XXX change 688 | { 689 | etal.allowed 690 | { author.field field.used = 691 | { author format.lab.names.abbr } 692 | { editor.field field.used = 693 | { editor format.lab.names.abbr } 694 | { organization.field field.used = 695 | { "The " #4 organization chop.word #3 text.prefix$ } 696 | { title.field field.used = 697 | { format.btitle } 698 | { key.field field.used = 699 | { key #3 text.prefix$ } 700 | {"Internal error :001 on " cite$ * " label" * warning$ } 701 | if$ 702 | } 703 | if$ 704 | } 705 | if$ 706 | } 707 | if$ 708 | } 709 | if$ 710 | } 711 | { make.full.label } 712 | if$ 713 | } 714 | 715 | FUNCTION {output.bibitem} 716 | { newline$ 717 | etal.allowed %%%XXX change 718 | etal.required 719 | and 720 | { 721 | "\harvarditem[" write$ 722 | make.abbr.label write$ 723 | "]{" write$ 724 | } 725 | { 726 | "\harvarditem{" write$ 727 | } 728 | if$ 729 | make.full.label write$ 730 | "}{" write$ 731 | list.year write$ 732 | "}{" write$ 733 | cite$ write$ 734 | "}" write$ 735 | newline$ 736 | "" 737 | before.all 'output.state := 738 | } 739 | 740 | FUNCTION {list.label.output} 741 | { make.list.label add.period$ " " * write$ 742 | } 743 | 744 | FUNCTION {article} 745 | { output.bibitem 746 | list.label.output 747 | list.year output.nonnull 748 | new.block 749 | author "author" item.check 750 | title.field field.used = 751 | { skip$ } 752 | { format.title quote "title" output.check } 753 | if$ 754 | crossref missing$ 755 | { journal emphasize "journal" duplicate$ item.check 756 | year empty$ 757 | { ". Forthcoming" * output new.block } 758 | { " " * format.vol.num.pages * output } 759 | if$ 760 | } 761 | { format.article.crossref output.nonnull 762 | format.pages output 763 | } 764 | if$ 765 | new.block 766 | note output 767 | fin.entry 768 | % write.url %Exclude URL from articles 769 | } 770 | 771 | FUNCTION {book} 772 | { output.bibitem 773 | list.label.output 774 | list.year output.nonnull 775 | new.block 776 | author empty$ 777 | { editor "author and editor" item.check } 778 | { crossref missing$ 779 | { "author and editor" editor either.or.check } 780 | 'skip$ 781 | if$ 782 | } 783 | if$ 784 | title.field field.used = 785 | { skip$ } 786 | { format.btitle "title" output.check } 787 | if$ 788 | new.block 789 | crossref missing$ 790 | { format.bvolume output 791 | format.number.series output 792 | format.edition output 793 | format.address output 794 | publisher "publisher" output.check 795 | } 796 | { format.book.crossref output.nonnull 797 | format.edition output 798 | } 799 | if$ 800 | new.block 801 | note output 802 | fin.entry 803 | % write.url %Exclude URL from articles 804 | } 805 | 806 | FUNCTION {booklet} 807 | { output.bibitem 808 | list.label.output 809 | list.year output.nonnull 810 | new.block 811 | title.field field.used = 812 | { skip$ } 813 | { format.title quote "title" output.check } 814 | if$ 815 | format.address output 816 | howpublished output 817 | new.block 818 | note output 819 | fin.entry 820 | write.url 821 | } 822 | 823 | FUNCTION {inbook} 824 | { output.bibitem 825 | list.label.output 826 | list.year output.nonnull 827 | new.block 828 | author empty$ 829 | { editor "author and editor" item.check } 830 | { crossref missing$ 831 | { "author and editor" editor either.or.check } 832 | 'skip$ 833 | if$ 834 | } 835 | if$ 836 | title.field field.used = 837 | % { skip$ } 838 | % { format.btitle "title" output.check } %Format in-quotes title rather than italics title 839 | { skip$ } 840 | { format.title quote "title" output.check } 841 | if$ 842 | new.block 843 | crossref missing$ 844 | % { format.bvolume output %Format book title in italics 845 | { format.in.ed.booktitle output 846 | new.block 847 | format.number.series output 848 | format.edition output 849 | format.address output 850 | publisher "publisher" output.check 851 | } 852 | { format.book.crossref output.nonnull 853 | format.edition output 854 | } 855 | if$ 856 | format.pages output.check 857 | new.block 858 | note output 859 | fin.entry 860 | write.url 861 | } 862 | 863 | FUNCTION {incollection} 864 | { output.bibitem 865 | list.label.output 866 | list.year output.nonnull 867 | new.block 868 | title.field field.used = 869 | { skip$ } 870 | % { format.title "title" output.check } 871 | { format.title quote "title" output.check } %uses quotes around conf paper title 872 | if$ 873 | author "author" item.check 874 | crossref missing$ 875 | { format.in.ed.booktitle "booktitle" output.check 876 | new.block 877 | format.edition output 878 | format.bvolume output 879 | format.number.series output 880 | format.address output 881 | publisher "publisher" output.check 882 | } 883 | { format.incoll.inproc.crossref output.nonnull 884 | } 885 | if$ 886 | pages missing$ 887 | { skip$ } 888 | { format.pages output } 889 | if$ 890 | new.block 891 | note output 892 | fin.entry 893 | % write.url %Exclude URL from articles 894 | } 895 | 896 | FUNCTION {inproceedings} 897 | { output.bibitem 898 | list.label.output 899 | list.year output.nonnull 900 | new.block 901 | title.field field.used = 902 | { skip$ } 903 | % { format.title "title" output.check } 904 | { format.title quote "title" output.check } %uses quotes around conf paper title 905 | if$ 906 | author "author" item.check 907 | crossref missing$ 908 | % { format.in.ed.booktitle "booktitle" output.check %eliminate booktitle format 909 | { " Paper presented at the " output %use "Paper presented at" lead 910 | booktitle "," * output %add comma after conference title 911 | address "." output.check %add city with period 912 | new.block 913 | % format.bvolume output 914 | % format.number.series output 915 | % address "." output %empty$ 916 | % { organization output 917 | % publisher output 918 | % } 919 | % { organization output 920 | % format.address output.nonnull 921 | % publisher output 922 | % } 923 | % if$ 924 | } 925 | { format.incoll.inproc.crossref output.nonnull 926 | } 927 | if$ 928 | % format.pages output 929 | % new.block 930 | % note output 931 | fin.entry 932 | % write.url %Exclude URL from articles 933 | } 934 | 935 | FUNCTION {conference} { inproceedings } 936 | 937 | FUNCTION {manual} 938 | { output.bibitem 939 | list.label.output 940 | list.year output.nonnull 941 | new.block 942 | title.field field.used = 943 | { skip$ } 944 | { format.btitle "title" output.check } 945 | if$ 946 | new.block 947 | format.edition output 948 | new.block 949 | author empty$ 950 | { organization empty$ 951 | { format.address output } 952 | 'skip$ 953 | if$ 954 | } 955 | { format.address output 956 | organization output 957 | } 958 | if$ 959 | new.block 960 | note output 961 | fin.entry 962 | write.url 963 | } 964 | 965 | FUNCTION {mastersthesis} 966 | { output.bibitem 967 | list.label.output 968 | list.year output.nonnull 969 | new.block 970 | author "author" item.check 971 | title.field field.used = 972 | { skip$ } 973 | { format.title "title" output.check } 974 | if$ 975 | "Masters thesis, " output.nonnull 976 | school "school" output.check 977 | format.address output 978 | new.block 979 | note output 980 | fin.entry 981 | % write.url %Exclude URL from articles 982 | } 983 | 984 | FUNCTION {misc} 985 | { output.bibitem 986 | list.label.output 987 | list.year output.nonnull 988 | new.block 989 | title.field field.used = 990 | { skip$ } 991 | { format.title quote output } 992 | if$ 993 | howpublished output 994 | institution "institution" output.check %Added Institution to "misc" entries 995 | new.block 996 | %note output 997 | note output.check 998 | publisher "publisher" output.check %Added publisher, for Mendeley 999 | fin.entry 1000 | %write.url 1001 | empty.misc.check 1002 | } 1003 | 1004 | FUNCTION {phdthesis} 1005 | { output.bibitem 1006 | list.label.output 1007 | list.year output.nonnull 1008 | new.block 1009 | author "author" item.check 1010 | title.field field.used = 1011 | { skip$ } 1012 | % { title "title" output.check } %Formats thesis as italics title rather than unquoted article title 1013 | { format.btitle "title" output.check } 1014 | if$ 1015 | new.block 1016 | "Doctoral Dissertation, " output.nonnull 1017 | school "school" output.check 1018 | format.address output 1019 | new.block 1020 | note output 1021 | fin.entry 1022 | % write.url %Exclude URL from articles 1023 | } 1024 | 1025 | FUNCTION {proceedings} 1026 | { output.bibitem 1027 | list.label.output 1028 | list.year output.nonnull 1029 | new.block 1030 | title.field field.used = 1031 | { skip$ } 1032 | { format.btitle "title" output.check } 1033 | if$ 1034 | new.block 1035 | format.bvolume output 1036 | format.number.series output 1037 | address empty$ 1038 | { editor empty$ 1039 | { skip$ } 1040 | { organization output 1041 | } 1042 | if$ 1043 | publisher output 1044 | } 1045 | { editor empty$ 1046 | 'skip$ 1047 | { organization output } 1048 | if$ 1049 | format.address output.nonnull 1050 | publisher output 1051 | } 1052 | if$ 1053 | new.block 1054 | note output 1055 | fin.entry 1056 | write.url 1057 | } 1058 | 1059 | FUNCTION {techreport} 1060 | { output.bibitem 1061 | list.label.output 1062 | list.year output.nonnull 1063 | new.block 1064 | author "author" item.check 1065 | title.field field.used = 1066 | { skip$ } 1067 | { format.title "title" output.check } 1068 | if$ 1069 | format.tr.number output.nonnull 1070 | institution "institution" output.check 1071 | format.address output 1072 | new.block 1073 | note output 1074 | fin.entry 1075 | write.url 1076 | } 1077 | 1078 | FUNCTION {unpublished} 1079 | { output.bibitem 1080 | list.label.output 1081 | list.year output.nonnull 1082 | new.block 1083 | author "author" item.check 1084 | title.field field.used = 1085 | { skip$ } 1086 | { format.title quote "title" output.check } 1087 | if$ 1088 | "Unpublished paper, " format.thesis.type output.nonnull %Added Unpublished paper to reference list 1089 | institution "institution" output.check %Added Institution to "Working paper" entries 1090 | note "note" output.check 1091 | fin.entry 1092 | write.url 1093 | } 1094 | 1095 | FUNCTION {default.type} { misc } 1096 | 1097 | MACRO {jan} {"January"} 1098 | 1099 | MACRO {feb} {"February"} 1100 | 1101 | MACRO {mar} {"March"} 1102 | 1103 | MACRO {apr} {"April"} 1104 | 1105 | MACRO {may} {"May"} 1106 | 1107 | MACRO {jun} {"June"} 1108 | 1109 | MACRO {jul} {"July"} 1110 | 1111 | MACRO {aug} {"August"} 1112 | 1113 | MACRO {sep} {"September"} 1114 | 1115 | MACRO {oct} {"October"} 1116 | 1117 | MACRO {nov} {"November"} 1118 | 1119 | MACRO {dec} {"December"} 1120 | 1121 | READ 1122 | 1123 | EXECUTE {init.field.constants} 1124 | 1125 | FUNCTION {sortify} 1126 | { purify$ 1127 | "l" change.case$ 1128 | } 1129 | 1130 | FUNCTION {sortify.names} 1131 | { " \harvardand\ " " " replace.substring 1132 | " et~al." " zzz" replace.substring 1133 | sortify 1134 | } 1135 | 1136 | FUNCTION {author.key.label} 1137 | { author empty$ 1138 | { key empty$ 1139 | { title.field 'field.used := } 1140 | { key.field 'field.used := } 1141 | if$ 1142 | } 1143 | { author.field 'field.used := } 1144 | if$ 1145 | } 1146 | 1147 | FUNCTION {author.editor.key.label} 1148 | { author empty$ 1149 | { editor empty$ 1150 | { key empty$ 1151 | { title.field 'field.used := } 1152 | { key.field 'field.used := } 1153 | if$ 1154 | } 1155 | { editor.field 'field.used := } 1156 | if$ 1157 | } 1158 | { author.field 'field.used := } 1159 | if$ 1160 | } 1161 | 1162 | FUNCTION {author.key.organization.label} 1163 | { author empty$ 1164 | { key empty$ 1165 | { organization empty$ 1166 | { title.field 'field.used := } 1167 | { organization.field 'field.used := } 1168 | if$ 1169 | } 1170 | { key.field 'field.used := } 1171 | if$ 1172 | } 1173 | { author.field 'field.used := } 1174 | if$ 1175 | } 1176 | 1177 | FUNCTION {editor.key.organization.label} 1178 | { editor empty$ 1179 | { key empty$ 1180 | { organization empty$ 1181 | { title.field 'field.used := } 1182 | { organization.field 'field.used := } 1183 | if$ 1184 | } 1185 | { key.field 'field.used := } 1186 | if$ 1187 | } 1188 | { editor.field 'field.used := } 1189 | if$ 1190 | } 1191 | 1192 | FUNCTION {sort.format.title} 1193 | { 't := 1194 | "A " #2 1195 | "An " #3 1196 | "The " #4 t chop.word 1197 | chop.word 1198 | chop.word 1199 | sortify 1200 | #1 global.max$ substring$ 1201 | } 1202 | 1203 | FUNCTION {calc.label} %%%XXX change 1204 | { make.abbr.label 1205 | title.field field.used = 1206 | { sort.format.title } 1207 | { sortify.names } 1208 | if$ 1209 | year field.or.null purify$ #-1 #4 substring$ sortify 1210 | * 1211 | 'sort.label := 1212 | } 1213 | 1214 | FUNCTION {preliminaries} %%%XXX change 1215 | { type$ "book" = 1216 | type$ "inbook" = 1217 | or 1218 | 'author.editor.key.label 1219 | { type$ "proceedings" = 1220 | 'editor.key.organization.label 1221 | { type$ "manual" = 1222 | 'author.key.organization.label 1223 | 'author.key.label 1224 | if$ 1225 | } 1226 | if$ 1227 | } 1228 | if$ 1229 | author.field field.used = %%%XXX change 1230 | { 1231 | author num.names$ #2 > 1232 | { #1 } 1233 | { #0 } 1234 | if$ 1235 | 'etal.required := 1236 | } 1237 | { 1238 | editor.field field.used = 1239 | { 1240 | editor num.names$ #2 > 1241 | { #1 } 1242 | { #0 } 1243 | if$ 1244 | } 1245 | { #0 } 1246 | if$ 1247 | 'etal.required := 1248 | } 1249 | if$ 1250 | #1 'etal.allowed := 1251 | } 1252 | 1253 | FUNCTION {first.presort} 1254 | { calc.label 1255 | sort.label 1256 | title.field field.used = 1257 | { skip$ } 1258 | { " " 1259 | * 1260 | make.list.label sortify.names 1261 | * 1262 | " " 1263 | * 1264 | title field.or.null 1265 | sort.format.title 1266 | * 1267 | } 1268 | if$ 1269 | #1 entry.max$ substring$ 1270 | 'sort.key$ := 1271 | } 1272 | 1273 | ITERATE {preliminaries} 1274 | 1275 | ITERATE {first.presort} 1276 | 1277 | SORT 1278 | 1279 | STRINGS { last.sort.label next.extra last.full.label} 1280 | 1281 | INTEGERS { last.extra.num last.etal.allowed} 1282 | 1283 | FUNCTION {initialize.confusion} 1284 | { #0 int.to.chr$ 'last.sort.label := 1285 | #0 int.to.chr$ 'last.full.label := 1286 | #1 'last.etal.allowed := 1287 | } 1288 | 1289 | FUNCTION {confusion.pass} 1290 | { last.sort.label sort.label = 1291 | { last.etal.allowed 1292 | { last.full.label make.full.label sortify.names = 1293 | { skip$ } 1294 | { #0 'etal.allowed := 1295 | #0 'last.etal.allowed := 1296 | } 1297 | if$ 1298 | } 1299 | { #0 'etal.allowed := } 1300 | if$ 1301 | } 1302 | { sort.label 'last.sort.label := 1303 | make.full.label sortify.names 'last.full.label := 1304 | #1 'last.etal.allowed := 1305 | } 1306 | if$ 1307 | } 1308 | 1309 | EXECUTE {initialize.confusion} 1310 | 1311 | ITERATE {confusion.pass} 1312 | 1313 | EXECUTE {initialize.confusion} 1314 | 1315 | REVERSE {confusion.pass} 1316 | 1317 | FUNCTION {initialize.last.extra.num} 1318 | { #0 int.to.chr$ 'last.sort.label := 1319 | "" 'next.extra := 1320 | #0 'last.extra.num := 1321 | } 1322 | 1323 | FUNCTION {forward.pass} 1324 | { last.sort.label sort.label = 1325 | { last.extra.num #1 + 'last.extra.num := 1326 | last.extra.num int.to.chr$ 'extra.label := 1327 | } 1328 | { "a" chr.to.int$ 'last.extra.num := 1329 | "" 'extra.label := 1330 | sort.label 'last.sort.label := 1331 | } 1332 | if$ 1333 | } 1334 | 1335 | FUNCTION {reverse.pass} 1336 | { next.extra "b" = 1337 | { "a" 'extra.label := } 1338 | 'skip$ 1339 | if$ 1340 | year empty$ 1341 | { "N.d." extra.label emphasize * 'list.year := } 1342 | { year extra.label emphasize * 'list.year := } 1343 | if$ 1344 | extra.label 'next.extra := 1345 | } 1346 | 1347 | ITERATE {first.presort} 1348 | 1349 | SORT 1350 | 1351 | EXECUTE {initialize.last.extra.num} 1352 | 1353 | ITERATE {forward.pass} 1354 | 1355 | REVERSE {reverse.pass} 1356 | 1357 | FUNCTION {second.presort} 1358 | { make.list.label 1359 | title.field field.used = 1360 | { sort.format.title } 1361 | { sortify.names } 1362 | if$ 1363 | " " 1364 | * 1365 | list.year field.or.null sortify 1366 | * 1367 | " " 1368 | * 1369 | title.field field.used = 1370 | { skip$ } 1371 | { title field.or.null 1372 | sort.format.title 1373 | * 1374 | } 1375 | if$ 1376 | #1 entry.max$ substring$ 1377 | 'sort.key$ := 1378 | } 1379 | 1380 | ITERATE {second.presort} 1381 | 1382 | SORT 1383 | 1384 | FUNCTION {begin.bib} 1385 | { preamble$ empty$ 1386 | 'skip$ 1387 | { "\harvardpreambledefs{%" write$ newline$ 1388 | preamble$ write$ "}" write$ newline$ 1389 | "\harvardpreambletext{%" write$ newline$ 1390 | preamble$ write$ "}" write$ newline$ } 1391 | if$ 1392 | "\begin{thebibliography}{xx}" write$ newline$ 1393 | } 1394 | 1395 | EXECUTE {begin.bib} 1396 | 1397 | EXECUTE {init.state.consts} 1398 | 1399 | ITERATE {call.type$} 1400 | 1401 | FUNCTION {end.bib} 1402 | { newline$ 1403 | "\end{thebibliography}" write$ newline$ 1404 | } 1405 | 1406 | EXECUTE {end.bib} 1407 | -------------------------------------------------------------------------------- /manuscript-htlatex.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leeper/htlatex-example/56cbc87f281b26e4a7544da8a88084b6aadfd019/manuscript-htlatex.docx -------------------------------------------------------------------------------- /manuscript-pandoc-csl.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leeper/htlatex-example/56cbc87f281b26e4a7544da8a88084b6aadfd019/manuscript-pandoc-csl.docx -------------------------------------------------------------------------------- /manuscript-pandoc.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leeper/htlatex-example/56cbc87f281b26e4a7544da8a88084b6aadfd019/manuscript-pandoc.docx -------------------------------------------------------------------------------- /manuscript.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leeper/htlatex-example/56cbc87f281b26e4a7544da8a88084b6aadfd019/manuscript.pdf -------------------------------------------------------------------------------- /manuscript.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage[margin=1in]{geometry} 3 | \usepackage{natbib} 4 | \usepackage{graphicx} 5 | \usepackage{amsmath} 6 | 7 | \title{Example of htlatex} 8 | \author{Thomas J. Leeper} 9 | 10 | \begin{document} 11 | 12 | \maketitle 13 | 14 | \noindent This is a manuscript. Section \ref{sec:table} has a table. Section \ref{sec:figure} has a figure. Section \ref{sec:eq} has an equation. For demonstration purposes, here's a reference \citep{Grovesetal2006}.\footnote{This is a footnote.} 15 | 16 | \subsection{A Table}\label{sec:table} 17 | 18 | This section has a table. It's Table \ref{tab:table1}. 19 | 20 | \begin{table}[ht] 21 | \caption{An example table}\label{tab:table1} 22 | \begin{tabular}{ll} 23 | Header 1 & Header 2\\ 24 | Row 1 & Value 1 \\ 25 | Row 2 & Value 2 \\ 26 | \end{tabular} 27 | \end{table} 28 | 29 | \subsection{A Figure}\label{sec:figure} 30 | 31 | This section has a figure. It's Figure \ref{fig:fig1}. 32 | 33 | \begin{figure}[ht] 34 | \caption{An example figure}\label{fig:fig1} 35 | \includegraphics[height=2in]{figure.png} 36 | \end{figure} 37 | 38 | \subsection{An equation}\label{sec:eq} 39 | 40 | This section has an in-line equation: $x^2 = 2^2 = 4$ and an equation environment: 41 | 42 | \begin{equation} 43 | a^2 = b^2 + c^2 44 | \end{equation} 45 | 46 | \noindent That's it. 47 | 48 | \bibliographystyle{apsa-leeper} 49 | \bibliography{references} 50 | 51 | \end{document} 52 | -------------------------------------------------------------------------------- /references.bib: -------------------------------------------------------------------------------- 1 | % Encoding: UTF-8 2 | 3 | @Article{Grovesetal2006, 4 | author = {Robert M. Groves and Mick P. Couper and Stanley Presser and Eleanor Singer and Roger Tourangeau and Giorgina Piani Acosta and Lindsay Nelson}, 5 | title = {Experiments in Producing Nonresponse Bias}, 6 | journal = {Public Opinion Quarterly}, 7 | year = {2006}, 8 | volume = {70}, 9 | number = {5}, 10 | pages = {720--736}, 11 | doi = {10.1093/poq/nfl036}, 12 | publisher = {Oxford University Press ({OUP})} 13 | } 14 | --------------------------------------------------------------------------------