diff --git a/Makefile b/Makefile index b5655f1..4e8910a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,10 @@ -all: lectureToOutline lectureToSlidedeck clean +DEST=/usr/local/bin -%: %.hs - ghc $@ +all: $(DEST)/lectureToOutline $(DEST)/lectureToSlidedeck $(DEST)/shuffleAllLists $(DEST)/convertOldFormat clean + +$(DEST)/%: src/%.hs + ghc $< + mv src/$* $@ clean: - rm *.hi *.o + rm -f src/*.hi src/*.o diff --git a/README.md b/README.md index 4141c5d..42d4508 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,10 @@ Convert a single markdown file into lectures, slides, and outlines. An explanation of the project is [here](http://benschmidt.org/2014/11/07/building-outlines-for-markdown-documents-with-pandoc/). +This repo is periodically updated to work with the latest build of pandoc. As of Pandoc 2.0, it uses the new fenced divs syntax instead of codes blocks to delineate slides. + + + Some potentially useful lines from my Makefile are below. ``` diff --git a/lecture.md b/lecture.md new file mode 100644 index 0000000..0942978 --- /dev/null +++ b/lecture.md @@ -0,0 +1,201 @@ +--- +title: The Californians +date: 2017-11-30 +author: HIST 1031 +... + +This is some lecture text. It won't appear in the presentation in any way. + +Here's an introductory slide outside of the outline that shows Reagan and Nixon together. + +:::slide +![Reagan and Nixon](https://cdn.theatlantic.com/assets/media/old_wire/img/upload/2013/08/21/AP070321015839/lead_large.jpg?1473252773) +::: + +# Ronald Reagan + +Who Was Reagan? +--------------- + +We should really have an image of Reagan in a cowboy hat. + +He has an image: but a presented one. + +Here's slide of that. + +:::slide +![Reagan and Nixon](https://cdn.theatlantic.com/assets/media/old_wire/img/upload/2013/08/21/AP070321015839/lead_large.jpg?1473252773) +::: + +:::slide +![Ronald Reagan](https://upload.wikimedia.org/wikipedia/commons/6/6a/Ronald_Reagan_with_cowboy_hat_12-0071M_edit.jpg) +::: + +Have you ever seen King's Row? Did you know that John Williams ripped off the score for *both* Star Wars *and* Superman from it? And Ronnie only gets third billing, because he's not a big star! + +::: {.slide} +![King's Row](>https://www.youtube.com/embed/DavgzfxQBZc?start=21) +::: + +You can't talk about Reagan without this cover. + +::: {.slide} +![Record, 1961](https://upload.wikimedia.org/wikipedia/commons/b/b2/Reagan-LPcover.jpg) +::: + +But his political rise was linked with a new feature in US politics after 1975. + +The Tax Revolt +-------------- + +Reagan's rise and success had a lot to do with the sudden emergence of *taxes* as a key issue in state and local politics. + +The key event was **California Proposition 13**. (This will show up as an ID in the outline, because it's bolded in the markdown. + +::: {.slide} +![.](https://tropicsofmeta.files.wordpress.com/2011/05/12462790872889-1.jpg) +::: + +Before the late 1970s, income taxes had not been a defining issue in +national politics. Kennedy campagined on cutting them. + +::: {.slide} +![.](https://si.wsj.net/public/resources/images/RV-AB458B_TAXID_NS_20110128190801.jpg) +::: + +### Supply-side Economics + +The New Deal had been predicated on generating *consumer* spending. + +The idea of Supply-side economics was that rather than promoting +consumers, you should promote spenders to spend and invest more money. + +(Note that I've tacked the class 'red' on the end of the slide here: I use a stylesheet in my particular version of revealjs so that the text doesn't get washed out.) + +The **Laffer Curve** was written on a napkin. This is the man! + +::: {.slide} +![The "Laffer Curve"](https://qzprod.files.wordpress.com/2017/04/art-laffer-with-curve-ap-photo.jpg?quality=80&strip=all&w=3000){.red} +::: + +:::slide +> You could only make four pictures and then you were in the top +> bracket. So we all quit working after four pictures and went off to +> the country. + +--Reagan on high marginal taxes. +::: + + +The Religious Right +------------------- + +::: {.slide} +Major Christian issues in 1978-1980 + +* Prayer +* Abortion (only later in the decade) +* Tax-exempt status for churches and religious schools. +::: + +1978 off-year elections demonstrated that the right could organize +around abortion as well. Brought catholics on board as well. + +Tax exemption especially important because many evangelical schools had +emerged in the South as ways to avoid segregation. + +Christian Academies with explicitly racist policies, created to +circumvent + +Reagan had signed the most liberal abortion bill in the nation in 1970. +George Bush, his VP, had only recently come around to pro-life. + +- So here's a video of the end of his convention speech. + +:::slide +![Reagan's Convention Speech, 1980](>https://www.youtube.com/embed/SBP2gvZTnwM?start=2685) +::: + +Even more famously, met with Jerry Falwell and other leaders of the +right. "I know you can't endorse me," he was quoted as saying. "But . . . I want you to know that I endorse you." + +**Lee Atwater** + +::: {.slide} +You start out in 1954 by saying, "Nigger, nigger, nigger." By 1968 you can't say "nigger" — that hurts you. Backfires. So you say stuff like forced busing, states' rights and all that stuff. You're getting so abstract now [that] you're talking about cutting taxes, and all these things you're talking about are totally economic things and a byproduct of them is [that] blacks get hurt worse than whites. And subconsciously maybe that is part of it. I'm not saying that. But I'm saying that if it is getting that abstract, and that coded, that we are doing away with the racial problem one way or the other. You follow me — because obviously sitting around saying, "We want to cut this," is much more abstract than even the busing thing, and a hell of a lot more abstract than "Nigger, nigger." + +Lee Atwater, 1981 +::: + +## Reagan in office + +::: {.slide} +Reagan in Office + +* Tax Cuts and Tax Reform +* Increase in Military Spending +* Continued fight against unions (Air Traffic Controllers' Strike) +* Deregulation of Various Industries. +::: + +Relatively popular president in office; like Nixon, hobbled by scandals +at the end. + +Iran Contra: secretly selling missiles to Iran, which was the United +States' primary foe in the middle east at the time; using the money to +fund a right-wing paramilitary insurgency in Nicaragua against a +socialist. + +# US Politics, 1980-2008 + +::: {.slide} +Some Contested issues, 1980 - 2008: + +* Health Care (Dems want) +* Tax Cuts (Reps want) +* Cutting New Deal and Great Society Programs. +* Abortion +* Gay Rights +::: + + +::: {.slide} +Some uncontested Issues, 1980 - 2008: + +* Free trade (it's good!) +* Deregulation +* Immigration +::: + +::: {.slide} +Some dead issues, 1980 - 2008: + +* Unions (they're going away) +* Segregation (it's over) +::: + +Paradoxically, presidents are evaluated more and more in their effects +on the economy even as the levers they have to affect jobs are taken +more and more away. + +::: {.slide} +![.](https://fred.stlouisfed.org/graph/fredgraph.png?g=fXYV) +::: + +::: {.slide} +Major Deregulatory Moves: + +* Airlines (1978) +* Railroads (1980) +* AT&T Antitrust breakup (1982) +* Removal of Equal Time doctrines for TV, 1987 +* Repeal and circumvention of rules about banking sector (1998-1999) +::: + +**Bill Clinton** + +**The Third Way** + +::: {.slide} +![Clinton on Government](>https://www.youtube.com/embed/GXRLW1KEtvo?start=460) +::: diff --git a/lectureToSlidedeck.hs b/lectureToSlidedeck.hs deleted file mode 100644 index 8dc80b2..0000000 --- a/lectureToSlidedeck.hs +++ /dev/null @@ -1,104 +0,0 @@ -import Text.Pandoc.Error -import Text.Pandoc -import Text.Pandoc.Walk (walk,query) -import Text.Pandoc.Shared (stringify) - ---Just for Bookworm. -import Network.HTTP.Base (urlEncode) --- - ---Functions to first build up a new document consisting of ---all the header blocks or quote blocks. To be combined into a new ---doc. - -extractSlides :: Block -> [Block] ---Level one headers get their own slide, followed by a horizontal rule. - -extractSlides (Header n m xs) - | n==1 = [(Header n m xs),HorizontalRule] - | otherwise = [Null] ---Anything in a CodeBlock is treated as a slide: the previously-ignored markdown is parsed and ---assembled into a pandoc document. - -extractSlides (CodeBlock attr string) = - pullBlocks (readMarkdown def string) ---All other text is skipped - -extractSlides x = [] - -pullBlocks :: Either Text.Pandoc.Error.PandocError Pandoc -> [Block] - ---Each slide is read as a Pandoc "document," and then images are corrected -pullBlocks (Right (Pandoc meta blocks)) = do - let newblocks = walk fiximages $ walk fancyLink $ walk addBookwormLinks blocks --- it's also fed back with a horizontal rule --- to separate it from the other slides in the deck. - (newblocks ++ [HorizontalRule]) - -addBookwormLinks :: Block -> Block -addBookwormLinks (CodeBlock (codeblock,["bookworm"],keyvals) code) = do - let block = (CodeBlock (codeblock,["bookworm"],keyvals) code) - let target = "http://benschmidt.org/BookwormD3/#" ++ (urlEncode code) - let target = "http://benschmidt.org/beta/#" ++ (urlEncode code) - let link = Para [Link nullAttr [Str "View"] (target,"")] - Div nullAttr [block,link] -addBookwormLinks (RawBlock _ _) = Null -addBookwormLinks x = x - -fancyLink :: Inline -> Inline --- For the time being, reveal.js will launch links *inside* the window. This is nice, so I do it for all links. --- Note it has the unfortunate side-effect of stripping formatting from the link text. - -fancyLink (Link attr textbits (url,title)) = do - let newlink = "" ++ (myHTML (Pandoc nullMeta [(Para textbits)])) ++ "" - RawInline (Format "html") newlink - -fancyLink x = x - -makeIframe :: String -> Inline --- Iframes are arbitrarily defined at 600px tall, because they seem to break when scaling by percent. -makeIframe target = do - let iframe = "" - RawInline (Format "html") iframe - -fiximages :: Block -> Block --- Images and Iframes that occupy a whole paragraph on their own are reformatted. --- null list handling for images: just return the thing. -fiximages (Para [Image attr [] target]) = (Para [Image attr [] target]) - --- an initial ">" before the link target denotes presenting it as an iframe, not an image. --- More recently, pandoc seems to encodeurl '>' as '%3E'; keeping the old pattern just in case. -fiximages (Para [Image attr text ('>':target,_)]) = Div attr [Para text, Plain [(makeIframe target)]] -fiximages (Para [Image attr text ('%':'3':'E':target,_)]) = Div attr [Para text, Plain [(makeIframe target)]] - - - --- In general, image titles are dropped above the images and the image when clicked expands to fullscreen. -fiximages (Para [Image attr text target]) = do - let myimage =[Image nullAttr [] target] - let newlink = fancyLink $ Link nullAttr myimage target - let title = fancyLink $ Link nullAttr text target - Div nullAttr [Para [title], Para [newlink]] - --- Anything else is just itself. -fiximages x = x - - -slideReturn :: Either Text.Pandoc.Error.PandocError Pandoc -> Pandoc --- extractSlides is a function, not a query, b/c it takes the format Block->[Block]. --- This could and should be changed by just wrapping it all in a div element. -slideReturn (Right (Pandoc meta blocks)) = do - let newData = foldl (++) [] (map extractSlides blocks) - Pandoc meta newData - -readDoc :: String -> Either Text.Pandoc.Error.PandocError Pandoc -readDoc = readJSON def - -writeDoc :: Pandoc -> String -writeDoc = writeJSON def - -myHTML :: Pandoc -> String -myHTML = writeHtmlString def - -main :: IO () -main = interact (writeDoc . slideReturn . readDoc) diff --git a/src/convertOldFormat.hs b/src/convertOldFormat.hs new file mode 100644 index 0000000..ef0b339 --- /dev/null +++ b/src/convertOldFormat.hs @@ -0,0 +1,17 @@ +import Text.Pandoc.Error +import Text.Pandoc +import Text.Pandoc.Walk (walk,query) +import Text.Pandoc.Shared (stringify) +import Text.Pandoc.JSON +import Data.String + +-- Converts from the old format to the new one. + +reformat :: Block -> Block +reformat (CodeBlock (id,classes,attr) string) = + Div (id, "slide":classes, attr) [RawBlock (Format "markdown") string] +reformat x = x + + +main :: IO() +main = toJSONFilter reformat diff --git a/lectureToOutline.hs b/src/lectureToOutline.hs similarity index 90% rename from lectureToOutline.hs rename to src/lectureToOutline.hs index e380e62..bbd2a7e 100644 --- a/lectureToOutline.hs +++ b/src/lectureToOutline.hs @@ -1,5 +1,6 @@ import Text.Pandoc.Error import Text.Pandoc +import Text.Pandoc.JSON import Text.Pandoc.Walk (walk,query) import Text.Pandoc.Builder @@ -18,7 +19,7 @@ extractBold :: Inline -> [Block] extractBold (Strong xs) = [Para xs] extractBold x = [] ---List junk--probably are better ways to do this. +--List junk--probably are better ways to do this, but haskell is hard. --First, adding a paragraph to the end of a block of blocks --(the basic element in an outline) @@ -43,7 +44,6 @@ addParaToFront (x:xs) newblock = do newblock:x:xs addParaToFront _ newblock = [newblock] - -- Here's another goofy first-last pairing for adding outlines ensureOutlineAtFront :: [Block] -> [Block] @@ -93,23 +93,15 @@ appendOutline oldlist newheader = do -- Convenience function for building an ordered pandoc list with default settings emptyOrderedList = OrderedList ( 1 , DefaultStyle , DefaultDelim ) [] - -- The overall action: first build out the list of bolds and headers, -- and then fold them all together into a new outline, -- and finally return a new Pandoc dcoument consisting of just that outline. -outlineReturn :: Either Text.Pandoc.Error.PandocError Pandoc -> Pandoc -outlineReturn (Right (Pandoc meta blocks)) = do +outlineReturn :: Pandoc -> Pandoc +outlineReturn (Pandoc meta blocks) = do let newData = foldl appendOutline emptyOrderedList (extractBolds blocks) Pandoc meta [newData] --Very broken-down functions to actually read and write. -readDoc :: String -> Either Text.Pandoc.Error.PandocError Pandoc -readDoc = readJSON def - -writeDoc :: Pandoc -> String -writeDoc = writeJSON def - -main :: IO () -main = interact (writeDoc . outlineReturn . readDoc) +main = toJSONFilter outlineReturn diff --git a/src/lectureToSlidedeck.hs b/src/lectureToSlidedeck.hs new file mode 100644 index 0000000..6b7377c --- /dev/null +++ b/src/lectureToSlidedeck.hs @@ -0,0 +1,119 @@ +import Text.Pandoc.Error +import Text.Pandoc +import Text.Pandoc.Walk (walk,query) +import Text.Pandoc.Shared (stringify) +import Text.Pandoc.JSON +import Text.Pandoc.Pretty (text) +import Data.Text (pack,unpack) +import qualified Data.Text as T +--Just for Bookworm. +import Network.HTTP.Base (urlEncode) + + +--Functions to first build up a new document consisting of +--all the header blocks or quote blocks. To be combined into a new +--doc. +extractSlides :: Block -> [Block] + +--Level one headers get their own slide, followed by a horizontal rule. +--All slides, in general, are followed by a Horizontal rule to ensure blocks don't run into each other. + +extractSlides (Header n m xs) + | n==1 = [(Header 1 m xs), HorizontalRule] + | otherwise = [] + +-- Divs of class 'slide' are expanded into their contents, +-- with a slidebreak delimiter at the end. + +extractSlides (Div (id, classes, meta) contents) + | "slide" `elem` classes = contents ++ [HorizontalRule] + | otherwise = [] + where content = Div (id, classes, meta) contents + +--All other text is skipped +extractSlides x = [] + + +-- This is just for my personal use. Shouldn't affect anyone else. +addBookwormLinks :: Block -> Block +addBookwormLinks (CodeBlock (codeblock,["bookworm"],keyvals) code) = do + let block = (CodeBlock (codeblock,["bookworm"],keyvals) code) + let target = "http://benschmidt.org/BookwormD3/#" ++ (urlEncode code) + let target = "http://benschmidt.org/D3/#" ++ (urlEncode code) + let link = Para [Link nullAttr [Str "View"] (target,"")] + Div nullAttr [block,link] +--addBookwormLinks (RawBlock _ _) = Null +addBookwormLinks x = x + +fancyLink :: Inline -> Inline +-- For the time being, reveal.js will launch links *inside* the window. This is nice, so I do it for all links. +-- Note it has the unfortunate side-effect of stripping formatting from the link text. + +fancyLink (Link (id,classes,attr) textbits link) = do + Link (id,classes,attr ++ [("data-preview-link","false")]) textbits link +fancyLink x = x + +makeIframe :: String -> Inline + +-- Iframes are arbitrarily defined at 600px tall, because they seem to break when scaling by percent. +makeIframe target = do + let iframe = "" + RawInline (Format "html") iframe + +fiximages :: Block -> Block +-- Images and Iframes that occupy a whole paragraph on their own are reformatted. +-- an initial ">" before the link target denotes presenting it as an iframe, not an image. +-- More recently, pandoc seems to encodeurl '>' as '%3E'; keeping the old pattern just in case. +fiximages (Para [Image attr text ('>':target,_)]) = + Div attr [Para text, Plain [(makeIframe target)]] + +fiximages (Para [Image attr text ('%':'3':'E':target,_)]) = + Div attr [Para text, Plain [(makeIframe target)]] + +-- null list handling for images: just return the thing. +fiximages (Para [Image attr [] (target_1, target_2)]) = +-- Header 2 ([],[],[("data-background-image",target_1),("data-background-size","contain")]) [] + -- Don't change until the fullscreen works again. + Para [Image attr [] (target_1, target_2)] + +-- Putting a period as the text does the same thing--back compatibility. +fiximages (Para [Image attr [(Str ".")] (target_1, target_2)]) = do + Header 2 ([],[],[("data-background-image",target_1),("data-background-size","contain")]) [] + +fiximages (Para [Image attr text (target_1, target_2)]) = do + let myimage =[Image nullAttr [] (target_1, target_2)] + let newlink = fancyLink $ Link nullAttr myimage (target_1, target_2) + let title = fancyLink $ Link nullAttr text (target_1, target_2) + Div nullAttr [Para [title], Para [newlink]] +-- Header 2 ([],[],[("data-background-image",target_1),("data-background-size","contain")]) [Span attr text] + +-- Anything else is just itself. +fiximages x = x + +slideReturn :: Pandoc -> Pandoc + +-- Should probably be a foldl, but I forget how. + +removeUnneededBars :: [Block] -> [Block] + +removeUnneededBars (HorizontalRule:Header n m x:xs) = + (Header n m x):removeUnneededBars(xs) + +removeUnneededBars (x:y:xs) = + x:removeUnneededBars(y:xs) + +removeUnneededBars [x] = + [x] + +removeUnneededBars [] = + [] + +slideReturn (Pandoc meta blocks) = do + let slides = query extractSlides blocks + let newData = removeUnneededBars $ walk fiximages $ walk fancyLink $ slides +-- let newData = walk fiximages $ walk fancyLink $ slides + Pandoc meta newData + + +main :: IO() +main = toJSONFilter slideReturn diff --git a/src/shuffleAllLists.hs b/src/shuffleAllLists.hs new file mode 100644 index 0000000..2173ee5 --- /dev/null +++ b/src/shuffleAllLists.hs @@ -0,0 +1,24 @@ +import Text.Pandoc.Error +import Text.Pandoc +import Text.Pandoc.Walk (walk,query) +import Text.Pandoc.JSON +import Text.Pandoc.Builder +import System.Random +import System.IO.Unsafe (unsafePerformIO) + +shuffle :: [a] -> IO [a] +shuffle x = if length x < 2 then return x else do + i <- System.Random.randomRIO (0, length(x)-1) + r <- shuffle (take i x ++ drop (i+1) x) + return (x!!i : r) + +shuffleList :: Block -> Block +shuffleList (OrderedList attr xs) = (OrderedList attr (unsafePerformIO (shuffle xs))) +shuffleList x = x + +shuffleLists :: Pandoc -> Pandoc +shuffleLists = walk shuffleList + + +main :: IO () +main = toJSONFilter shuffleLists diff --git a/uploadToWordpress.sh b/uploadToWordpress.sh deleted file mode 100755 index 36f2495..0000000 --- a/uploadToWordpress.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -#Read in the configurations -#source syllabus/course.cnf - - -FILE=$1; -BASENAME=$(echo "$FILE" | sed "s/\.md//;s/.*\///;s/_/ /g") - -echo "Using basename of $BASENAME" -PARENT=$2; -: ${PARENT:=""} - -#Create if not exists -parentVersion=$(wp post list --post_type=page --format=csv | awk "{FS=\",\"}{if(\$2 ~ \"$PARENT\") {print \$1}}") -: ${parentVersion:=$(wp post create --porcelain --post_type=page --post_status=publish --post_title="$PARENT")} - - -#Create if not exists -EXISTINGVERSION=$(wp post list --post_type=page --format=csv | awk "{FS=\",\"}{if(\$2 ~ /^\"?$BASENAME\"?$/) {print \$1}}") -: ${EXISTINGVERSION:=$(wp post create --porcelain --post_type=page --post_status=publish --post_title="$BASENAME" --post_parent=$parentVersion)} - -CONTENT=$(pandoc -t html --base-header-level=2 --bibliography=../../MyLibrary.bib --smart --csl=citationstyles/inline.csl "$FILE") - -#Now that it's created, we just need to paste in the content as piped through Pandoc. -wp post update $EXISTINGVERSION --post_content="${CONTENT}" - - -