How to add a page break before header automatically in pandoc - lua

I need to convert a markdown document into a Word document.
I need it so that before each header there is a page break.
For example, here, a page break would be inserted before # Heading 1 and before # Heading 2. I wouldn't mind if it skipped the very first one if there is no content before it in the document.
# Heading 1
Hello
# Heading 2
World
I have found this Lua filter, but, as far as I understand, it's just for Latex and it's not automatic.
I have tried to write a Lua script myself, but failed, because I do not understand well how pandoc works.
For example, I have tried returning a Para with the contents of the previous one + a page break from the Header function like this:
function Header(el)
if el.level == 1 then
local t = { pandoc.RawBlock('openxml', '<w:p><w:r><w:br w:type="page"/></w:r></w:p>'), el }
return pandoc.Para(t)
end
return el
end
However, it just ends up wiping all of the headers.
I have tried a few other alterations of the same idea, neither of which worked.
The trouble in Lua is mainly the fact that there is no static analysis and no Intellisense. I may be doing something completely inadequate in this code without any compiler errors and without even realising it.

I believe the following should fix that:
local pagebreak = '<w:p><w:r><w:br w:type="page"/></w:r></w:p>'
function Header(el)
if el.level == 1 then
-- return both the page break and the header as a list
return { pandoc.RawBlock('openxml', pagebreak), el }
end
-- No `return el` needed, as not returning any value is the same as
-- returning the original value.
end
The error reporting of pandoc during unmarshalling, i.e., while retrieving objects from Lua, is not great, to say the least. Ideally, pandoc should report the type error that comes from wrapping a list of "blocks" in a Para, as that constructor should only accept "inlines".
In case you are curious: I'm working on fixing this by switching to a different marshalling strategy, see this PR. It's taking a while, but we'll get there.

Related

"function arguments expected near 'levelc'" when using LOVE

I'm currently trying to make a level loading system for a game.
function love.filedropped(file)
ofile=io.open(file:getFilename(),"r")
io.input(ofile)
file:close
levelc=io.read()
for i=1,levelc do
levels[i]=io.read()
print levels[i]
end
levelc should be the first line of the file, and file:getFilename is the file to open (path included) the project gives an error message on startup, and i've used a similar structure before, but for an output. The error is at line 30, which is the levelc=io.read().
I've tried changing the name of the file pointer (it was "f" before, now "ofile") and i've tried using io.read("*l") instead of io.read() but same result.
EDITS:
-this is a love.filedropped(file)
-i need to open other files from a .txt later and i don't really understand how do do that
The parameter given by love.filedropped is a DroppedFile.
In your case helpful could be File:lines().
For example:
function love.filedropped(file)
-- Open for reading
file:open("r")
-- Iterate over the lines
local i = 0
for line in file:lines() do
i = i + 1
levels[i] = line
print(i, levels[i]) -- Notice the parentheses missing in your code
end
-- Close the file
file:close()
end
Notice that love2d usually only allows reading/writing files within the save or working directory. Dropped files are an exception.
Unrelated to this answer but things I noticed in your code:
Use locals, oFile should be local
file:close() required parentheses as its a function call
Same for the print
The filedropped callback has no end
You mentioned reading other files too, to do so, you can either:
Use love.filesystem.newFile and a similar approach as before
The recommended one-liner love.filesystem.lines

Lua — If error in function, then do something

I feel like this should be simple, but can't seem to solve it. I have a function in Lua that's designed to validate a confirm code in a survey. Basically, if the ID is valid, then we can grab lots of data from that code, but if it's not a valid code, the script will break because it'll be populating nil values.
So, I basically need an error check — if the function can run properly, then run it. If it can't then I need to ask for a new code.
I've tried using pcall which feels like is exactly for this. I'm working off the Lua documentation:
if pcall(foo) then
-- no errors while running `foo'
...
else
-- `foo' raised an error: take appropriate actions
...
end
On my end, that means I have a function:
function populate()
... doing lots here to unencrypt and parse the ID someone gives and populate variables
end
Then I'm running the follwing:
if pcall(populate) then
print('no errors!') -- Just printing as a test, if there's no error, I'll run the script
else
print('Oh snap theres an error!) -- I'll change this to ask the user for a valid ID and then try again
end
What am I missing? I know it's going to be simple. But the last part of my code always returns the "Oh snap..." no matter what.
Thanks in advance, I have a super complex code running that I was able to build from just reading responses to other questions, but can't seem to get this simple part to work. Entirely possible I'm missing the point of pcall.
What do you expect?
If i am unsure what happen or which return value i should use for another condition i normally test/check in Lua Standalone...
€ lua
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> pcall(string.gsub,'foo','%l','bar') -- Check for lowercases
true barbarbar 3
> pcall(string.gsub,'foo','%u','bar') -- Check for uppercases
true foo 0
> -- In this case i have to use maybe the third return value to decide what to do?
> -- OK -- Lets go...
> a, b, c = pcall(string.gsub,'foo','%u','bar') -- Check for uppercases
> if a and c == 0 then print('Only Kiddies here!') return false end
Only Kiddies here!
false
>

Lua io.popen freezing after a while of reading a log file

I'm attempting to constantly read and parse a log file (Minecraft log file) by using io.popen in tandem with Ubuntu's tail command so that I can send some messages upon certain events.
Now, I have mostly everything working here, except one small issue. After a while of reading, the entire program just freezes.
Here is the relevant code:
-- Open the tail command, return a file handle for it.
local pop = io.popen(config.listen_command)
-- Simply read a single line, I've pulled this into its own
-- function so that if this ever needs changing I can do so
-- easily.
local function get_line()
logger:log(4, "READ LINE")
return pop:read("*l")
end
-- For each line in the log file, check if it matches any
-- of a list of patterns, return the matches and the
-- pattern information if so.
local function match_line()
local line = get_line()
logger:log(4, "Line: %s", line)
-- This all works, and I've tested that it's not freezing
-- here. I've just included it for completion of the call
-- -stack.
for event_type, data in pairs(config.message_patterns) do
for event_name, pattern in pairs(data) do
local matches = {line:match(pattern)}
if matches[1] then
return event_type, event_name, matches
end
end
end
end
-- The main loop, simply read a line and send a message
-- if there was a match.
logger:log(4, "Main loop begin.")
while true do
local event_type, event_name, matches = match_line()
-- ...
-- The rest of the code here is not relevant.
config.listen_command = "tail -F --lines=1 latest.log"
The issue is in the get_line function. After a while of reading the log file, it completely freezes on the pop:read("*l"). It prints the READ LINE message, but never prints the Line: <whatever data here> line.
This is a really strange issue that I've been getting really confused about. I've tried swapping to different distributions of Lua (Luvit, LuaJIT, Lua) and a very large amount of debugging, changing small things, rerunning, ... But I cannot think of anything that'd be causing this.
Perhaps there's something small I've missed.
So my question here is this: Why is pop:read("*l") freezing, even though more data is being outputted to the logfile? Is there a way to fix this? Perhaps to detect if the next read will freeze indefinitely, so I can try closing the popen'ed file and re-open it (or to preferably stop it happening altogether?)

Lua error for WoW addon (Tukui)

I don't have a lot of coding experience, did some C a few years ago, so that helps, but Lua handles things a bit differently, so I can't keep track.
I sometimes (not always) get this error when a friend or guildy logs into the game:
Date: 2013-06-14 16:57:57
ID: -1
Error occured in: Global
Count: 4
Message: ..\AddOns\Tukui\scripts\chat.lua line 335:
attempt to concatenate upvalue 'classColor' (a nil value)
Debug:
[C]: ?
Tukui\scripts\chat.lua:335: AddMessage()
..\FrameXML\ChatFrame.lua:2755: ChatFrame_MessageEventHandler()
..\FrameXML\ChatFrame.lua:2491: ChatFrame_OnEvent()
...s\WIM\Libs\LibChatHandler-1.0\LibChatHandler-1.0.lua:281:
...s\WIM\Libs\LibChatHandler-1.0\LibChatHandler-1.0.lua:252
...s\WIM\Libs\LibChatHandler-1.0\LibChatHandler-1.0.lua:308:
...s\WIM\Libs\LibChatHandler-1.0\LibChatHandler-1.0.lua:296
I have to do a reload of the ui after this happens to be able to see chat text again for that person.
Line 335 in that .lua file is this:
text = replace(text, "^|Hplayer:(.+)|h%[(.+)%]|h", "|Hplayer:%1|h|cff"..classColor.."%2|r|h")
Now I've learned that the .. indicates the concatenate function, but that isn't really helping me.
I don't know if this is enough information, but if you need it I can post the whole local function or whatever else is required.
If it makes any difference, I'm running the 3.3.5a WoW client.
You are probably using a global that gets defined from some other addon in a now deterministic way
While the (classColor or "") will get you rid of the error, you should try and find why that variable (classColor) is sometimes defined and sometimes not. Maybe it happens only for certain classes?
A simple hack would be to just replace
..classColor..
with
..(classColor or "")..
where it will select a blank string when classColor has no value assigned to it.

#line and jump to line

Do any editors honer C #line directives with regards to goto line features?
Context:
I'm working on a code generator and need to jump to a line of the output but the line is specified relative to the the #line directives I'm adding.
I can drop them but then finding the input line is even a worse pain
If the editor is scriptable it should be possible to write a script to do the navigation. There might even be a Vim or Emacs script that already does something similar.
FWIW when I writing a lot of Bison/Flexx I wrote a Zeus Lua macro script that attempted to do something similar (i.e. move from input file to the corresponding line of the output file by search for the #line marker).
For any one that might be interested here is that particular macro script.
#line directives are normally inserted by the precompiler, not into source code, so editors won't usually honor that if the file extension is .c.
However, the normal file extension for post-compiled files is .i or .gch, so you might try using that and see what happens.
I've used the following in a header file occasionally to produce clickable items in
the VC6 and recent VS(2003+) compiler ouptut window.
Basically, this exploits the fact that items output in the compiler output
are essentially being parsed for "PATH(LINENUM): message".
This presumes on the Microsoft compiler's treatment of "pragma remind".
This isn't quite exactly what you asked... but it might be generally helpful
in arriving at something you can get the compiler to emit that some editors might honor.
// The following definitions will allow you to insert
// clickable items in the output stream of the Microsoft compiler.
// The error and warning variants will be reported by the
// IDE as actual warnings and errors... which means you can make
// them occur in the task list.
// In theory, the coding standards could be checked to some extent
// in this way and reminders that show up as warnings or even
// errors inserted...
#define strify0(X) #X
#define strify(X) strify0(X)
#define remind(S) message(__FILE__ "(" strify( __LINE__ ) ") : " S)
// example usage
#pragma remind("warning: fake warning")
#pragma remind("error: fake error")
I haven't tried it in a while but it should still work.
Use sed or a similar tool to translate the #lines to something else not interpreted by the compiler, so you get C error messages on the real line, but have a reference to the original input file nearby.

Resources