I have a file which conforms to the following standard:
# comment
<section> # comment
{variant1,variant2,...}
a="bar"
b="b\\a\"r"
[array]
[+]
elem="foo"
[+]
elem="bar"
[/]
c=."42"
d=."xDebb1eD0e5Da11a5"
e=."%101010"
f=#"xaa bb cc dd"
{/}
</>
I have defined a new 'language' in Notepad++ and got all my syntax highlighting working well:
Comment Line Style -> Open: # (red)
Operator Style -> Operators 1: = (yellow)
Operator Style -> Delimiter 1 -> Open : < (yellow)
-> Close : >
Delimiter 2 -> Open : [+ (blue)
-> Close : ]
Delimiter 3 -> Open : { (orange)
-> Close : }
Delimiter 4 -> Open : " (cyan)
-> Escape: \
-> Close : "
Delimiter 5 -> Open : ." (lime)
-> Close : "
Delimiter 6 -> Open : #" (green)
-> Close : "
Delimiter 7 -> Open : [ (purple)
-> Close : ]
...But after much searching and reading I cannot work out how to get Notepad++/Scintilla to fold the the [array], {variant} and <section> chunks of the file (which runs to several thousand lines).
I notice that if I highlight a file as HTML, then any tag (html, body, foo, wibble, etc) all fold as expected - which I will need here as the <section>, {variant} and [array] names are arbitrary.
I have worked out that if a character is defined as a delimiter, the fold'er will refuse to fold on any string which starts-with that character.
My question: With regard to this file format, how do I get Notepad++ to fold according to these rules:
Rule 1 -> Starts with: <*>
Ends with: </>
Rule 2 -> Starts with: {*}
Ends with: {/}
Rule 3 -> Starts with: [*] but not [+]
Ends with: [/]
Related
I'm working on a board game where each team must submit an order each turn. To prevent abuse, I'm trying to make a login page, where you can select a team, give the team's password, and continue to the next page.
I'm using Haskell, using the resources provided here, specifically the "Getting user input" section.
Relevant documentation: Network.CGI, Text.XHtml
Imports, relevant data/types, and page function:
import Network.CGI
import Text.XHtml
data Team = Team
{teamID :: Int,
teamName :: String} deriving Eq
type Lang = Int
type Teams = [Team]
page :: String -> Html -> Html
page t b = header << thetitle << t +++ body << b
I have the following loginPage function:
loginPage :: Lang -> Teams -> Html
loginPage lang teams = page (["Lépés Bejelentkezés", "Turn Login"] !! lang) $
form ! [method "post"] <<
-- [paragraph << (["Csapat: ", "Team: "] !! lang +++ (select ! [name "teamID"] << teamOpts)), -- Generated version, does not work
{- -}
[paragraph << (["Csapat: ", "Team: "] !! lang +++
(select ! [name "teamID"] <<
[option ! [value "0"] << "Anglia", option ! [value "1"] << "Franciaország"])), --} -- Manually typed version, works perfectly
paragraph << (["Jelszó: ", "Password: "] !! lang +++ password "password"),
submit "" (["Tovább", "Next"] !! lang) ]
where
teamOpts = map (\t -> option ! [value . show $ teamID t] << teamName t) $ teams
The commented line uses teamOpts to generate a list of options, and put them in a select tag, with name "teamID".
In the currently uncommented lines, I wrote (part of) the list I expect when calling teamOpts.
In ghci, both methods produce the exact same HTML. Yet, when calling this program on my webserver (Apache on Rocky Linux), I get the following outputs:
Generated:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
><head
><title
>Lépés Bejelentkezés</t
Manually written:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
><head
><title
>Lépés Bejelentkezés</title
></head
><body
><form method="post"
><p
>Csapat: <select name="teamID"
><option value="0"
>Anglia</option
><option value="1"
>Franciaország</option
></select
></p
><p
>Jelszó: <input type="password" name="password" id="password"
/></p
><input type="submit" value="Tovább"
/></form
></body
></html
>
As you can see, the generated version simply terminates before even finishing the title tag.
When running the script on the command line (on the webserver), I get the expected outcome (same as Manually written), with the CGI Header: Content-type: text/html; charset=ISO-8859-1 .
I've also set it to Content-type: text/html; charset=UTF-8, but the same problem persists.
Other things I tried:
Using (teams seq ) before creating the list, and other methods of forcing evaluation (Usually the program terminates after returning <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/
Trying to debug using a simpler generator: (Works perfectli in cli, but not when loading it, returning up to </t)
showTeams :: Teams -> Html
showTeams teams = page "Teams" $
paragraph << (concat . map (\t -> teamName t ++ ", ") $ teams)
Trying to use strict versions of IO functions (as recommended here). Worked in cli, but gave hGetContents: invalid argument (invalid byte sequence) errors over the web.
Making sure everything in the directory is owned by apache:apache
The necessary code (newUnitsPage, cgiMain, and main):
newUnitsPage :: Lang -> Teams -> Units -> Maybe String -> Maybe String -> Html
newUnitsPage lang teams units tid passwd = page (["Új egységek", "New units"] !! lang) body
where
body = paragraph << "PLACEHOLDER" +++ paragraph << fromJust tid +++ paragraph << fromJust passwd
cgiMain = do
-- General setup
liftIO $ hSetEncoding stdin utf8 -- This doesn't change anything either
-- (What I use) {- -
paths' <- liftIO $ listDirectory "./"
let mapPaths = sort $ filter (=~ "\\.hmap$") paths'
hmap <- liftIO $ getNewestMap mapPaths
let teams = fetchTeams hmap --}
{- For your convenience:
Write the following to a file named "test.hmap":
Team {teamID = 0, teamName = "Anglia"}
Team {teamID = 1, teamName = "Franciaország"}
-}
test <- readFile "test.hmap" -- Pretty sure this is where it all goes wrong, but strict reading (Sysem.IO.Strict) does not fix it
let teams = map (\line -> read line :: Team) . lines $ test
-- Defaults to 0 (Hungarian)
mlang <- getInput "lang"
let lang = maybe 0 (\l -> if l `elem` ["1", "en"] then 1 else 0) mlang
-- All Inputs
-- Authentication
tid <- getInput "teamID"
password <- getInput "password"
newUnitOrders <- getInput "newUnitOrders" -- This is for the next page, not yet implemented, since login doesn't work yet.
-- Number coding for which form to show - method to show certain form based on what inputs exist
let code = fromJust $ foldM (\lastCode (mInput, code) -> if isNothing mInput then Just lastCode else Just code)
0 -- If username / password is not supplied, be on login page
[(tid,1),(password,1), -- If newUnitOrders are not supplied, be on newUnit page
(newUnitOrders,2)] -- Etc.
-- The html output
let pages =
[loginPage lang teams,
-- [showTeams teams,
newUnitsPage lang teams units tid password]
setHeader "Content-type" "text/html; charset=UTF-8" -- Optional
output . renderHtml $ pages !! code
main = runCGI $ handleErrors cgiMain
I've checked over and over in the documentation, and I've found no indication of what is going wrong.
Thanks for any help!
I was able to duplicate with your test.hmap version. Check the server error logs, and you should see a note about invalid byte sequences in your hmap files, along the lines of:
AH01215: xhtml.cgi: test.hmap: hGetContents: invalid argument (invalid
byte sequence): /usr/lib/cgi-bin/xhtml.cgi
The problem appears to be that Apache runs CGI scripts with LANG=C, and the Haskell script will die at some random point in time when it reads unicode data from one of your hmap files. Making the evaluation stricter may cause the script to fail earlier, but it isn't going to fix the problem.
The easiest fix is probably to add:
liftIO $ setLocaleEncoding utf8 -- from GHC.IO.Encoding
to the top of your cgiMain function. (Changing the encoding of stdin wasn't necessary in my testing.)
Here's my full version of your script used for testing. Without the liftIO $ setLocaleEncoding utf8 line, it truncates output exactly the same way you observed; with that line, it works fine:
import Control.Monad
import Data.Maybe
import Data.List
import System.Directory
import System.IO
import Network.CGI
import Text.XHtml
import GHC.IO.Encoding
data Team = Team
{teamID :: Int,
teamName :: String} deriving (Read, Eq)
type Lang = Int
type Teams = [Team]
page :: String -> Html -> Html
page t b = header << thetitle << t +++ body << b
loginPage :: Lang -> Teams -> Html
loginPage lang teams = page (["Lépés Bejelentkezés", "Turn Login"] !! lang) $
form ! [method "post"] <<
[paragraph << (["Csapat: ", "Team: "] !! lang +++ (select ! [name "teamID"] << teamOpts)), -- Generated version, does not work
paragraph << (["Jelszó: ", "Password: "] !! lang +++ password "password"),
submit "" (["Tovább", "Next"] !! lang) ]
where
teamOpts = map (\t -> option ! [value . show $ teamID t] << teamName t) $ teams
cgiMain :: CGI CGIResult
cgiMain = do
liftIO $ setLocaleEncoding utf8
paths' <- liftIO $ listDirectory "./"
test <- liftIO $ readFile "test.hmap" -- Pretty sure this is where it all goes wrong, but strict reading (Sysem.IO.Strict) does not fix it
let teams = map (\line -> read line :: Team) . lines $ test
-- Defaults to 0 (Hungarian)
mlang <- getInput "lang"
let lang = maybe 0 (\l -> if l `elem` ["1", "en"] then 1 else 0) mlang
-- All Inputs
-- Authentication
tid <- getInput "teamID"
password <- getInput "password"
newUnitOrders <- getInput "newUnitOrders" -- This is for the next page, not yet implemented, since login doesn't work yet.
-- Number coding for which form to show - method to show certain form based on what inputs exist
let code = fromJust $ foldM (\lastCode (mInput, code) -> if isNothing mInput then Just lastCode else Just code)
0 -- If username / password is not supplied, be on login page
[(tid,1),(password,1), -- If newUnitOrders are not supplied, be on newUnit page
(newUnitOrders,2)] -- Etc.
-- The html output
let pages =
[loginPage lang teams]
-- [showTeams teams,
-- newUnitsPage lang teams units tid password]
setHeader "Content-type" "text/html; charset=UTF-8" -- Optional
output . renderHtml $ pages !! code
main :: IO ()
main = runCGI $ cgiMain
How to get typed code in output in html?
I have code that I want to insert in the same way inside the html tag and display in the same way.
<body>
<code>
<script>alert("hey!");</script>
</code>
</body>
I have the above and I expect my html output to be as follows. And this code is typed in the output, not executed!
<script>alert("hey!");</script>
<script>alert("hey!");</script>
Just use < for the < at the beginning of a tag.
<body>
<code>
<script>alert("hey!");</script>
</code>
</body>
You can use special symbols like this
< -> </<
> -> >/>
& -> &
# -> #
( -> (
) -> )
" -> '/"/"
$ -> $
/ -> /
\ -> \
] -> ]
[ -> [
I am having trouble with an error I keep getting while trying to use formlets in racket. It says:
; lifted/5.1: undefined;
; cannot reference an identifier before its definition
; in module: top-level
; internal name: lifted/5.1
Nothing in my code is named "lifted" or "5.1" or any combination of the two. I am thinking that this is something inside the black box of formlets that I'm running up against, but I don't know what.
; set up
(require web-server/servlet web-server/servlet-env)
(require web-server/formlets)
; body of program
(define simpleformlet
(formlet
(#%#
"Name: " ,{input-string . => . name}
"Number: " ,{input-int . => . number})
(name number)))
(define (start request)
(showpage request))
(define (showpage request)
(define (responsegen embed/url)
(response/xexpr
`(html
(head (title "App3"))
(body (h1 "Let's try this...")
(form
([action ,(embed/url actionhandler)]
[method "POST"])
,#(formlet-display simpleformlet)
(input ([type "submit"])))))))
(define (actionhandler request)
(define-values (name number)
(formlet-process simpleformlet request))
(response/xexpr
`(html
(head (title "Alright!"))
(body (h2 "name")
(p ,name)
(h2 "number")
(p ,number)))))
(send/suspend/dispatch responsegen))
; run it!
(serve/servlet start
#:servlet-regexp #rx""
#:servlet-path "/form")
I added the line
#lang racket
at the top of your program. Used "Determine language from source" in the lower, left corner of DrRacket. And ran your program. A browser window opened and I was able to enter a name and a number, before I got a sensible error.
I am using Racket version 6.12, so if you are using an older version of Racket, then upgrade and try again.
This question already has an answer here:
Return the first line of a String in Haskell
(1 answer)
Closed 8 years ago.
Just a simple question, my code is complete. It takes an input file, breaks it into lines, reads the file line by line, does the conversions, which is in this case, turns certain things into HTML format (ex: #This is a line into a line with H1 HTML tags, formatting it into a header). The only thing I have left is to take the First line of code, and print that code into the browser tab. Also, the body, or tail must be printed into the window, not the tab. So the first line of my .txt file is The Title! which I want to show in the tab of the web browser. Here is something I have for that:
formatToHTML :: String -> String
formatToHTML [] = []
formatToHTML x
| head x == --any char = "<title>" ++ head ++ "</title>"
| tail x == --rest of file = "<body>" ++ tail ++ "</tail>"
| otherwise = null
or
formatToHTML :: [String] -> String
formatToHTML = unlines. map (show) "<title>" ++ head ++ </title>" $ lines
I dont want to, or I think even need to use guards here, but I cant think of a shorter way to do my task.
I would call this from my main method before I output my file to html.
Also, I know its a amateur haskell question. but how would I represent any char. Say, I want to say, if the head of x exists, print the head with the title tags. print tail with body tags. Help? Thank You
My guess of what you want is:
formatHtml :: [String] -> String
formatHtml [] = ""
formatHtml (x:xs) = unlines theLines
where theLines = [ "<title>" ++ ...convert x to html... ++ "</title>",
"<body>" ] ++ map toHtml xs ++ [ "</body>" ]
toHtml :: String -> String
toHmtl str = ...converts str to HTML...
Example:
formatHtml [ "the title", "body line 1", "body line2" ]
results in:
<title>the title</title>
<body>
body line 1
body line 2
</body>
You still have to define the toHtml function and decide how to convert the first line to the inner html of the tag.
I had a question concerning some basic transformations in Haskell.
Basically, I have a written Input file, named Input.md. This contains some markdown text that is read in my project file, and I want to write a few functions to do transformations on the text. After completing these functions under a function called convertToHTML, I have output the file as an .html file in the correct format.
module Main
(
convertToHTML,
main
) where
import System.Environment (getArgs)
import System.IO
import Data.Char (toLower, toUpper)
process :: String -> String
process s = head $ lines s
convertToHTML :: String -> String
convertToHTML str = do
x <- str
if (x == '#')
then "<h1>"
else return x
--convertToHTML x = map toUpper x
main = do
args <- getArgs -- command line args
let (infile,outfile) = (\(x:y:ys)->(x,y)) args
putStrLn $ "Input file: " ++ infile
putStrLn $ "Output file: " ++ outfile
contents <- readFile infile
writeFile outfile $ convertToHTML contents
So,
How would I read through my input file, and transform any line that starts with a # to an html tag
How would I read through my input file once more and transform any WORD that is surrounded by _word_ (1 underscore) to another html tag
Replace any Character with an html string.
I tried using such functions such as Map, Filter, ZipWith, but could not figure out how to iterate through the text and transform each text. Please if anybody has any suggestions. I've been working on this for 2 days straight and have a bunch of failed code to show for a couple of weeks and have a bunch of failed code to show it.
I tried using such functions such as Map, Filter, ZipWith, but could not figure out how to iterate through the text and transform each text.
Because they work on appropriate element collection. And they don't really "iterate"; you simply have to feed the appropriate data. Let's tackle the # problem as an example.
Our file is one giant String, and what we'd like is to have it nicely split in lines, so [String]. What could do it for us? I have no idea, so let's just search Hoogle for String -> [String].
Ah, there we go, lines function! Its counterpart, unlines, is also going to be useful. Now we can write our line wrapper:
convertHeader :: String -> String
convertHeader [] = [] -- that prevents us from calling head on an empty line
convertHeader x = if head x == '#' then "<h1>" ++ x ++ "</h1>"
else x
and so:
convertHeaders :: String -> String
convertHeaders = unlines . map convertHeader . lines
-- ^String ^[String] ^[String] ^String
As you can see the function first converts the file to lines, maps convertHeader on each line, and the puts the file back together.
See it live on Ideone
Try now doing the same with words to replace your formatting patterns. As a bonus exercise, change convertHeader to count the number of # in front of the line and output <h1>, <h2>, <h3> and so on accordingly.